에듀테크 프로젝트 대시보드
백트래킹 (Backtracking)
후보를 하나씩 채워 나가다가, 지금까지의 선택으로는 절대 정답을 만들 수 없다는 걸 알게 되는 순간
즉시 되돌아가(backtrack) 다른 선택을 시도하는 방법이다. 가능성 없는 가지를 미리 잘라내는
가지치기(pruning) 덕분에, 모든 경우를 다 만들어 보는 완전 탐색보다 훨씬 적은 노드만 방문한다.
대표 예제인 N-퀸 문제는 N×N 체스판에 퀸 N개를 서로 공격하지 못하게 놓는 문제다
(퀸은 같은 행·열·대각선을 모두 공격).
def solve(n): cols, diag, anti = set(), set(), set() # 이미 쓴 열 / ↘대각선(r-c) / ↙대각선(r+c) res = [] def backtrack(r, board): if r == n: # 모든 행에 퀸을 놓았다 → 정답 하나 완성 res.append(board[:]); return for c in range(n): if c in cols or (r - c) in diag or (r + c) in anti: continue # 가지치기: 이 칸은 공격당함 → 시도조차 안 함 cols.add(c); diag.add(r - c); anti.add(r + c) board.append(c) backtrack(r + 1, board) # 다음 행으로 전진 board.pop() # ← 되돌리기(backtrack): 방금 놓은 퀸을 치운다 cols.discard(c); diag.discard(r - c); anti.discard(r + c) backtrack(0, []) return res
↘ 방향은 r - c 가, ↙ 방향은 r + c 가 같으면 같은 대각선.비트마스크로 열·대각선을 정수 3개로 표현하면 더 빨라진다.| 방법 (N=8) | 만들어 보는 배치 수 | 설명 |
|---|---|---|
| 모든 칸에 자유롭게 | 64 C 8 ≈ 4.4×10⁹ | 행 제한도 없음 |
| 행마다 1개, 열 순열 | 8! = 40,320 | 대각선 충돌은 끝까지 놓아 봐야 앎 |
| 백트래킹 + 가지치기 | ≈ 2,057 노드 | 첫 해까지 방문한 트리 노드 수 |