
백트래킹은 문제를 해결하기 위한 중요한 알고리즘 기법 중 하나이다. 특히, 탐색 공간이 크고, 모든 가능한 해결책을 시도해봐야 하는 문제에서 효율적으로 사용될 수 있다. 백트래킹은 재귀적으로 문제를 해결하고, 가능성 있는 후보해를 만들어 나가다가, 해당 후보해가 문제의 재약 조건을 만족하지 않는 경우 되돌아가서 다른 후보해를 시도하는 방식이다.
개념
백트래킹은 문제를 해결하기 위해 가능한 모든 경로를 탐색하지만, 그 과정에서 필요 없는 경로를 빠르게 제거하는 방법이다. 이 알고리즘은 재귀적으로 작동하며, 아래 단계를 거친다.
- 결정 : 현재 상태에서 가능한 후보를 선택한다.
- 검사 : 선택한 후보가 제약 조건을 만족하는지 확인한다.
- 탐색 : 제약 조건을 만족한다면 다음 단계로 넘어가고, 만족하지 않으면 되돌아가(백트랙) 다른 후보를 시도한다.
- 해결 : 모든 후보를 시도한 후, 적합한 해결책이 발견되며 이를 반환한다.
특징
재귀적 접근 : 백트래킹은 주로 재귀를 사용하여 구현됩니다. 현재 상태에서 가능한 모든 후보를 고려한 후, 각 후보에 대해 재귀적으로 문제를 해결한다.
가지치기(Pruning) : 백트래킹의 핵심은 유망하지 않은 경로를 조기에 포기하는 가지치기 기법이다. 이를 통해 탐색해야 할 경로의 수를 줄여, 탐색의 효율성을 높인다.
완전 탐색 : 백트래킹은 가능한 모든 해답을 탐색하지만, 가지치기를 통해 일부 경로를 배제함으로써 효율성을 확보한다.
결과가 보장됨 : 백트래킹은 모든 가능한 해답을 탐색하므로, 유효한 해답이 존재하면 반드시 이를 찾는다.
문제 의존성 : 백트래킹의 효율성은 문제의 특성과 제약 조건에 따라 크게 달라질 수 있습니다. 잘못 설계된 가지치기 조건은 알고리즘의 성능을 저하시킬 수 있다.
python 구현
def is_valid(board, row, col): # 같은 열에 다른 퀸이 있는지 확인 for i in range(row): if board[i][col] == 1: return False # 왼쪽 대각선 위에 다른 퀸이 있는지 확인 for i, j in zip(range(row-1, -1, -1), range(col-1, -1, -1)): if board[i][j] == 1: return False # 오른쪽 대각선 위에 다른 퀸이 있는지 확인 for i, j in zip(range(row-1, -1, -1), range(col+1, len(board))): if board[i][j] == 1: return False return True def solve_n_queens(board, row): if row >= len(board): # 해결책을 찾았을 때 print_solution(board) return for col in range(len(board)): if is_valid(board, row, col): board[row][col] = 1 # 퀸 배치 solve_n_queens(board, row + 1) # 다음 행으로 이동 board[row][col] = 0 # 백트래킹: 퀸 배치 취소 def print_solution(board): for row in board: print(" ".join("Q" if x == 1 else "." for x in row)) print("\n") # N x N 체스판에서 N-Queens 문제를 해결합니다. N = 4 board = [[0] * N for _ in range(N)] solve_n_queens(board, 0)
출력
. Q . . . . . Q Q . . . . . Q . . . Q . Q . . . . . . Q . Q . .
코드 설명
- is_valid: 특정 위치에 퀸을 놓을 수 있는지 검사한다.
- solve_n_queens: 재귀적으로 퀸을 배치하며, 배치가 가능한 경우 다음 행으로 이동하고, 더 이상 배치할 수 없으면 백트래킹을 통해 이전 단계로 돌아가 다른 위치를 시도한다.
- print_solution: 유효한 해결책이 발견되면 이를 출력한다.