해를 찾는 도중 해가 절대 될 수 없다고 판단되면, 되돌아가서 해를 다시 찾아가는 기법을 말한다. (되추적)
알고리즘 기법 중 하나로 재귀적으로 문제를 해결하되 현재 재귀를 통해 확인 중인 상태가 제한 조건에 위배가 되는지 판단하고, 해당 상태가 위배되는 경우 해당 상태를 제외하고 다음 단계로 넘어간다.
말이 어렵지만, 위에서 말한 대로 해를 찾는 도중 해가 절대 될 수 없다고 판단되면, 되돌아가서 다시 해를 찾는다고 생각하면 된다.
여기서 KEY POINT는 더 이상 탐색할 필요가 없는 상태를 제외한다는 것인데, 이를 가지치기라고 한다.
여기까지만 읽었다면... DFS와 백트래킹은 무슨 관계가 있는걸까? 라고 의문을 가질 수 있다.
백트래킹은 모든 경우의 수에서 조건을 만족하는 경우를 탐색하는 것이기 때문에 완전탐색기법인 DFS(깊이우선탐색), BFS(너비우선탐색)로 모두 구현이 가능하다.
백트래킹 특성에서 조건에 부합하지 않으면 이전 수행으로 돌아가야 함으로 BFS보다는 DFS이 구현하기 더 편하기 때문에 주로 DFS를 사용한다. (이에 대한 설명은 아래의 사진을 보면 이해할 수 있을 것이다.)
이미지 출처 : https://velog.io/@vagabondms/DFS-vs-BFS
# import java.io.*;
public class Main {
static int[][] list;
static boolean[] check;
public static void main(String[] args) throws IOException {
list = new int[][]{{2, 4, 3}, {1, 3, 7}, {6, 5, 6}}; //3X3 행렬
check = new boolean[]{false, false, false}; //조건 판별 체크
backTracking(0,0);
}
static void backTracking(int row, int score) {
if (row == 3) { //재귀함수 마치는 조건
System.out.println(score);
return;
}
for (int i = 0; i < 3; i++) {
if (check[i] == false) {
check[i] = true;
backTracking(row+1, score + list[row][i]); //자식노드 방문
check[i] = false; //자식노드 방문했으면 부모노드 다시 방문기록지움
}
}
}
}