백트래킹은 단순히 되돌아가는 것을 넘어, 상태 공간 트리(State Space Tree)를 체계적으로 탐색하며 해답을 찾는 강력한 알고리즘
DFS(Depth-First Search)란?
백트래킹은 재귀 함수를 사용하여 구현되는 경우가 많음
함수는 현재 상태를 인자로 받고, 다음 단계의 모든 후보를 순회하며 자기 자신을 재귀적으로 호출
함수 구조
function backtrack(current_state):
if is_solution(current_state):
save_solution(current_state)
return
for next_candidate in get_candidates(current_state):
if is_promising(next_candidate):
backtrack(next_candidate)
N × N 체스판에 N개의 퀸을 서로 공격할 수 없도록 놓는 모든 경우의 수를 찾는 함수
def solve_n_queens(n):
# 해답을 저장할 리스트
solutions = []
# 현재 체스판 상태 (각 행의 퀸 위치를 저장)
board = [-1] * n
# 백트래킹 탐색 시작
backtrack(0, n, board, solutions)
return solutions
def backtrack(row, n, board, solutions):
# 5. 해답: 모든 행에 퀸을 놓는 데 성공했다면, 해답을 찾은 것
if row == n:
solutions.append(board[:])
return
# 2. 다음 단계: 현재 행(row)의 모든 열(col)에 대해 퀸을 놓아보기
for col in range(n):
# 3. 유망성 검사: 현재 위치(row, col)가 유망한지 확인
if is_promising(row, col, board):
# 퀸을 현재 위치에 놓음
board[row] = col
# 4. 다음 행으로 이동하여 재귀 호출
backtrack(row + 1, n, board, solutions)
# 백트래킹이 일어난 후, 다음 열을 시도하기 위해 상태 복원
# board[row]는 다음 반복에서 덮어쓰여지므로 명시적 복원 불필요
def is_promising(row, col, board):
# 이전 행들을 검사하며 퀸의 위치를 확인
for prev_row in range(row):
# 같은 열에 퀸이 있는지 확인
if board[prev_row] == col:
return False
# 대각선에 퀸이 있는지 확인 (row 간 거리 == col 간 거리)
if abs(board[prev_row] - col) == abs(prev_row - row):
return False
return True
# 실행 예제: N=4인 경우
n = 4
solutions = solve_n_queens(n)
print(f"N = {n} 일 때, 총 {len(solutions)}개의 해답을 찾았습니다.")
for i, sol in enumerate(solutions):
print(f"해답 {i+1}: {sol}")
# 퀸이 놓인 체스판 시각화 (선택 사항)
for r in range(n):
row_str = ["."]*n
row_str[sol[r]] = "Q"
print(" ".join(row_str))
print()
N개의 퀸을 놓는 모든 해를 찾는 문제
주어진 집합에서 특정 조건을 만족하는 모든 조합을 찾는 문제
미로의 출구를 찾는 모든 경로를 탐색하는 문제