[Algorithm] BackTracking
jane1choi opened this issue · 0 comments
BackTracking이란?
BackTracking = Back(뒤) + Tracking(추적)
백트래킹은 기본적으로 “가능한 모든 방법을 탐색한다"의 아이디어를 가진다.
가능한 경우를 전부 탐색 하면서, 더 이상 나아갈 수 없는 경우를 만났을 때 이전으로 돌아가 다시 다른 경우를 탐색하는 유형으로, 모든 경우의 수를 고려하는 브루트포스보다 더 시간을 절약할 수 있다.
→ 어떤 노드의 유망성을 점검후, 유망하지 않으면 부모노드로 돌아가 다른 자식 노드를 검사하는 방식으로 탐색
State Space Tree (상태 공간 트리)
백트래킹에서 고려해야할 경우의 수를 트리로 나타낸 것
상태공간 트리에서 점진적으로 자식 노드로 향하면서 유망성(제약 조건에 맞는지)을 검사하고, 만약 유망성이 없다면 더 이상 탐색하지 않고 다시 부모노드로 돌아간다.
→ 백트래킹은 가지치기를 통해 효율을 극대화한다. 가능성이 없는 루트를 가지치기로 쳐내서 탐색하는 기법이다.
시간 복잡도
그림 출처: https://dudri63.github.io/2019/02/09/algo40/
일반적으로 상태 공간 트리의 노드 수에 비례한다.
위 트리의 경우 O(N!) == 사실상 완전 탐색 이지만,
백트래킹은 중간 중간 가지치기를 하기 때문에 실제로 브루트포스로 풀 때보다 훨씬 효율적이다.
어떤 방식으로 풀까?
주로 백트래킹 문제는 재귀함수를 이용해 푼다!
func backtracking(current_node) {
if 현재 해답에 도달했다면 {
print(current 상태)
return
}
if 유망성 검사 조건 {
for i in 1...노드개수 {
backtracking(child) // 재귀
}
} else {
return // 유망하지 않으면 바로 종료하고 돌아감
}
}
백트래킹 문제 유형
완전 탐색으로 풀 수 있는 입력 제한이 작은 문제 + 가능한 경우의 수들이 모두 어떤 제약 조건을 통과할 때
대표적인 문제들 → 스도쿠, N-Queens, 0-1 knapsack problem 등