한양과학기술고등학교

에듀테크 프로젝트 대시보드

백트래킹 (Backtracking)

백트래킹 (Backtracking / 되추적 탐색)

후보를 하나씩 채워 나가다가, 지금까지의 선택으로는 절대 정답을 만들 수 없다는 걸 알게 되는 순간 즉시 되돌아가(backtrack) 다른 선택을 시도하는 방법이다. 가능성 없는 가지를 미리 잘라내는 가지치기(pruning) 덕분에, 모든 경우를 다 만들어 보는 완전 탐색보다 훨씬 적은 노드만 방문한다. 대표 예제인 N-퀸 문제는 N×N 체스판에 퀸 N개를 서로 공격하지 못하게 놓는 문제다 (퀸은 같은 행·열·대각선을 모두 공격).

N-퀸 백트래킹 시각화

판 크기 N
실행 을 눌러 퀸을 한 행씩 놓아 보세요. 막히면 앞 행으로 되돌아갑니다.
현재 행
–
시도한 칸
0
가지치기 (거부)
0
되돌아간 횟수
0
찾은 해
0

핵심 코드 (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 가 같으면 같은 대각선.
  • 전진할 때 상태(집합)에 표시를 추가하고, 되돌아올 때 정확히 그만큼 취소한다 → 상태를 항상 깨끗하게 유지.
  • 가지치기가 빠를수록 방문 노드가 급감한다. N-퀸은 비트마스크로 열·대각선을 정수 3개로 표현하면 더 빨라진다.

왜 되돌아가면 빨라질까 — 탐색 트리와 가지치기

시작 c=0 c=1 c=2 … 해! 막힘 ✕ ✕ 빨간 가지 = 놓는 순간 공격당해 통째로 잘림 (그 아래는 방문조차 안 함)
방법 (N=8)만들어 보는 배치 수설명
모든 칸에 자유롭게64 C 8 ≈ 4.4×10⁹행 제한도 없음
행마다 1개, 열 순열8! = 40,320대각선 충돌은 끝까지 놓아 봐야 앎
백트래킹 + 가지치기≈ 2,057 노드첫 해까지 방문한 트리 노드 수
  • DFS와의 관계: 백트래킹은 "상태 공간 트리"를 깊이 우선으로 도는 것 + 불가능한 가지 즉시 포기.
  • 완전 탐색과의 차이: 완전 탐색은 잎(완성된 후보)에서만 판정, 백트래킹은 중간에서도 판정해 잘라낸다.
  • 같은 뼈대로 스도쿠, 미로 경로, 부분집합 합, 순열·조합 생성, 그래프 색칠 등을 푼다.