1. 백트래킹 (Backtracking) 정의
•
임의의 집합에서, 주어진 기준(criterion)대로 원소의 순서를 선택하는 문제를 해결하는 알고리즘 설계 방법.
•
대표적 사례: n-Queens 문제, 부분집합의 합 문제(sum of subsets problem).
•
해답 후보 공간을 트리 구조(상태공간트리)로 모델링하고, 가지치기(pruning)를 통해 불필요한 경로를 제거.
2. 상태공간트리와 깊이우선검색(DFS)
•
상태공간트리(state space tree):
모든 가능한 상태(해답 후보)를 트리로 표현.
뿌리에서 잎 노드까지의 경로가 해답 후보를 나타냄.
•
DFS:
뿌리 노드에서 시작하여 가능한 한 깊게 내려간 뒤, 더 이상 진행할 수 없으면 이전 노드로 돌아가 탐색을 계속.
3. 백트래킹의 핵심 논리
•
유망성(promising):
현재 노드가 해답의 일부가 될 가능성이 있으면 유망(promising), 그렇지 않으면 비유망(non-promising).
•
가지치기(pruning):
비유망한 노드에서 즉시 탐색을 중단하고 부모로 돌아감.
해답 가능성이 없는 부분공간을 검색하지 않음.
4. n-Queens 문제
4.1 문제정의
•
n × n 체스판에 n개의 여왕말(Queen)을 서로 잡아먹히지 않도록 배치.
•
한 행에 하나씩 Queen을 두면서,
같은 열/대각선에 있는지 검사(유망성 판단).
4.2 백트래킹 알고리즘(알고리즘 5.1)
•
각 깊이(depth) i에서 i번째 행에 Queen을 둘 column을 선택.
•
col[i] = i번째 행에 Queen이 위치한 column 값.
void queens(index i) { // i: 현재 행 번호
if(promising(i)) {
if (i==n) {
// 해답 col[1] ~ col[n] 출력
}
else {
for (j=1; j<=n; j++) {
col[i+1] = j;
queens(i+1);
}
}
}
}
bool promising(index i) {
for (k=1; k<i; k++) {
if(col[i] == col[k] || abs(col[i] - col[k]) == i - k)
return false;
}
return true;
}
C++
복사
•
promising: 같은 열, 대각선에 있는지 검사.
5. n-Queens 백트래킹 시간복잡도 분석
•
상태공간트리의 전체 노드 수는 nⁿ(모든 행에 대해 모든 열 시도)이나,
가지치기를 통해 탐색 노드 수가 대폭 감소.
•
같은 열에 Queen을 둘 수 없으므로, 유망 노드의 상한은 n!개.
•
실제 탐색 노드 수는 대각선 조건까지 포함하면 더 작아짐.
•
시간복잡도는 최악 O(n!)보다 작으나, 정확한 분석은 불가능(실행을 통한 경험적 추정 필요).
•
몬테카를로 방법 등 확률적 추정 기법으로 복잡도 추정 가능.
6. 부분집합의 합 문제 (Sum of Subsets Problem)
6.1 문제정의
•
n개의 아이템 무게 w₁, ..., wₙ과 목표 무게 W가 주어질 때,
무게의 합이 W가 되는 부분집합을 구하는 문제.
6.2 상태공간트리 및 가지치기
•
각 깊이에서 아이템 포함/불포함 두 갈래로 분기(2진 트리).
•
무게 합이 초과하면 그 경로는 가지치기(pruning).
6.3 백트래킹 알고리즘(알고리즘 5.4)
void sum_of_subsets(index i, int weight, int total) {
if (promising(i)) {
if (weight == W) {
// 해답 출력
} else {
include[i+1]=1;
sum_of_subsets(i+1, weight + w[i+1], total - w[i+1]);
include[i+1]=0;
sum_of_subsets(i+1, weight, total - w[i+1]);
}
}
}
bool promising(index i) {
return (weight + total >= W) && (weight == W || weight + w[i+1] <= W);
}
C++
복사
•
promising 조건:
(1) 남은 아이템을 모두 더해도 W 미만이면 가지치기
(2) weight + w[i+1]이 W를 넘으면(초과 시) 가지치기
7. 부분집합의 합 문제 시간복잡도
•
상태공간트리의 최대 노드 수: 2ⁿ⁺¹ – 1 = O(2ⁿ)
•
백트래킹/가지치기를 통해 많은 노드 생략 가능
•
최악의 경우 여전히 지수 복잡도,
평균적으로는 훨씬 적은 노드만 검사하게 됨
8. 몬테카를로 방법(Monte Carlo Algorithm)에 의한 복잡도 추정
•
표본 추출과 확률적 실험을 이용하여 실제 방문 노드 수의 기대값을 추정
•
n-Queens 등 백트래킹 적용 문제에서 평균 탐색량을 수치적으로 추정 가능
BackTracking#2
1. 지도색칠하기와 그래프 색칠하기
1.1 지도색칠하기 문제
•
인접한 지역(국가, 도, 구 등)이 서로 다른 색이 되도록 색을 칠하는 문제.
•
4색 정리(Four color theorem): 임의의 평면지도는 최대 4가지 색만으로 인접 지역을 모두 구분할 수 있다.
1.2 그래프 색칠하기 문제
•
각 지역을 그래프의 정점(vertex)으로, 인접 지역은 간선(edge)로 표현.
•
평면그래프(planar graph): 간선이 서로 교차하지 않고 평면상에 그려지는 그래프. 모든 지도는 평면그래프로 표현 가능.
•
비평면 그래프는 4색 정리를 적용할 수 없다.
1.3 m-색칠하기(m-coloring) 문제
•
최대 m가지 색을 사용하여 인접한 정점에 같은 색이 할당되지 않도록 그래프를 색칠.
•
인접행렬 W[i][j]=1이면 i, j 정점이 연결되어 있음.
•
백트래킹으로 해결 가능: 각 정점에 색을 할당하며 유망성을 검사(인접 정점과 색이 다르면 유망).
m-색칠하기 백트래킹 알고리즘 (알고리즘 5.5)
void m_coloring(index i) {
if(promising(i)) {
if(i==n) 출력;
else {
for(color=1; color<=m; color++) {
vcolor[i+1] = color;
m_coloring(i+1);
}
}
}
}
bool promising(index i) {
for(j=1; j<i; j++)
if(W[i][j] && vcolor[i]==vcolor[j]) return false;
return true;
}
C++
복사
•
상태공간트리에서 가지치기를 수행하여 불필요한 색 조합을 제외한다.
•
최악의 경우 상태공간트리의 노드 수는 mⁿ.
2. 0–1 배낭채우기 문제의 백트래킹
2.1 상태공간트리 구축
•
각 아이템을 포함/불포함으로 분기하는 2진 트리를 사용.
•
각 노드에서 누적 가치(profit), 누적 무게(weight)를 관리.
•
모든 해답 후보 경로를 따라 최적해(best)를 갱신해야 하므로, 최적화 문제로 분류된다.
2.2 유망성 판단과 가지치기
•
유망성(promising): 해당 노드의 bound(이론상 가능한 최대 이익)가 현재까지 찾은 최적 이익(maxprofit)보다 크면 유망.
•
bound 계산: 남은 용량이 있으면, 다음 아이템을 분할해서(무게당 가치로) 더해 최대로 만들 수 있는 이익의 상한선을 계산.
백트래킹 알고리즘 (알고리즘 5.7)
void knapsack(index i, int profit, int weight) {
if(weight <= W && profit > maxprofit){
maxprofit = profit;
bestset = include;
}
if(promising(i)) {
include[i+1]=1;
knapsack(i+1, profit+p[i+1], weight+w[i+1]);
include[i+1]=0;
knapsack(i+1, profit, weight);
}
}
bool promising(index i) {
int totweight = weight, j = i+1;
float bound = profit;
while(j <= n && totweight + w[j] <= W) {
totweight += w[j];
bound += p[j];
j++;
}
if(j <= n) bound += (W - totweight) * p[j] / w[j];
return (weight < W) && (bound > maxprofit);
}
C++
복사
•
profit: 현재까지 담은 아이템 가치 합
•
weight: 현재까지 담은 아이템 무게 합
•
bound: 추가로 얻을 수 있는 최대 이익의 상한
3. 시간복잡도
•
m-색칠하기 문제의 최악 시간복잡도: O(mⁿ) (m: 색의 개수, n: 정점 개수)
•
0–1 배낭문제의 백트래킹 알고리즘: 상태공간트리의 최대 노드수는 O(2ⁿ), 하지만 가지치기를 통해 실제 탐색량 감소.
•
최악의 경우에도 지수 복잡도(2ⁿ+1–1)이나, 실제로는 pruning으로 탐색 노드가 줄어듦.
4. 정리
•
백트래킹은 상태공간트리의 DFS와 가지치기를 결합한 해 공간 탐색 기법.
•
유망성 검사를 통해 비효율적인 탐색을 방지하고, 최적화/조합문제에서 효과적으로 사용됨.
•
대표적 예시: 그래프 색칠(m-coloring), 0–1 배낭문제, 부분집합의 합 등.