jane1choi / TIL

Today I Learned #심야아요

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

[Algorithm] BackTracking

jane1choi opened this issue · comments

BackTracking이란?

BackTracking = Back(뒤) + Tracking(추적)
백트래킹은 기본적으로 “가능한 모든 방법을 탐색한다"의 아이디어를 가진다.

가능한 경우를 전부 탐색 하면서, 더 이상 나아갈 수 없는 경우를 만났을 때 이전으로 돌아가 다시 다른 경우를 탐색하는 유형으로, 모든 경우의 수를 고려하는 브루트포스보다 더 시간을 절약할 수 있다.

→ 어떤 노드의 유망성을 점검후, 유망하지 않으면 부모노드로 돌아가 다른 자식 노드를 검사하는 방식으로 탐색

State Space Tree (상태 공간 트리)

백트래킹에서 고려해야할 경우의 수를 트리로 나타낸 것
Untitled-5
상태공간 트리에서 점진적으로 자식 노드로 향하면서 유망성(제약 조건에 맞는지)을 검사하고, 만약 유망성이 없다면 더 이상 탐색하지 않고 다시 부모노드로 돌아간다.

→ 백트래킹은 가지치기를 통해 효율을 극대화한다. 가능성이 없는 루트를 가지치기로 쳐내서 탐색하는 기법이다.

시간 복잡도

Untitled-6

그림 출처: 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 등