모든 경우의 수를 시도하는 방법. 무식하게 모든 경우의 수를 탐색해보는 알고리즘이다. 브루트-포스 알고리즘(Brute-Force) 라고도 한다.
직관적이어서 이해가 쉽고 문제의 정확한 결과값을 얻어낼 수 있는 가장 확실하며 기초적인 방법이다.
특별한 알고리즘이라기보단, 문제를 푸는 방법 이라고 생각하는게 편하다.
하지만 문제 해결 알고리즘을 사용할 때, 기본적으로 중요한 두가지 규칙 있다.
1. 문제를 해결할 수 있는가
2. 효율적으로 동작하는가
무식한 브루트포스 방식으로 1번은 만족하겠지만, 경우의 수와 실행 시간이 비례하기 때문에 2번을 만족하는 것이 어려울 수 있다.
따라서 완전탐색 기법을 사용할 때에는 그 문제에 대한 파악이 중요하다.
위의 2번에 적용할 수 있는 기법에 대해 알아보자.
1. 단순 브루트포스
2. 비트마스크
3. 순열
4. BFS/DFS
5. 재귀 함수
6. 백트래킹(Backtracking)
[1,2,3]
과 [3,2,1]
이 차이가 있듯이, 같은 데이터가 입력된 수열이지만 그 순서에 따라 의미가 있고 이 순서를 통해 연결되는 이전/다음 수열을 찾아낼 수 있는 경우를 계산할 수 있다가지치기(Pruning)
라고도 표현하는데, 불필요한 가지를 쳐내면서 답을 찾아내서 붙은 이름백트래킹
은 해결책을 찾아가는 도중에 막히게 되면 다시 돌아가 다른 경로로 탐색을 하여, 결국 모든 가능한 경우의 수를 탐색해 해결책을 찾아가는 방식으로 사용된다. 보통 완전 탐색 문제는 난이도가 쉬워 초급자들도 큰 어려움을 겪지 않는다. 하지만 약간의 난이도가 있는 문제에서, 알고리즘 공부를 어느정도 한 사람들이 "이게 완전 탐색이라고?" 하는 반응을 보이는 경우가 꽤나 있다.
문제를 봤을 때 완전 탐색이지 않을까?라는 생각을 한 번 정도는 해볼 만한 경우들을 보자.
1. 입력으로 주어지는 데이터(N)의 크기가 매우 작다.
보통 n = 10만, 20만 같은 크기를 주는 경우가 많다.
하지만 대부분 완전 탐색 문제는 N의 크기가 매우 작다.
순열, 조합 같은 문제들은 완전탐색이므로 기본적으로 시간복잡도가 O(2^n)이거나 O(N!)이므로 N의 크기가 매우 작아야 한다.
2. 답의 범위가 작고, 임의의 답을 하나 선택했을 때 문제 조건을 만족하는지 역추적할 수 있다.
답의 범위가 제한적인 경우에, 답을 고정시켜 놓고 주어진 조건들이 답에 적합한지 역으로 확인해보는 방법이다. 가능한 답을 모두 확인하는 과정에서 완전 탐색이 이용된다.
3. 여러 문제 조건 중 한 조건을 고정시키면 문제 풀이가 간단해진다.
조건에 따라 가지 수가 바뀌기 때문에, 하나의 조건을 고정하여 문제를 해결한 후 범위를 좁게 설정하여 문제를 해결하는 것이다.
https://hongjw1938.tistory.com/78
https://rebro.kr/59
https://chanhuiseok.github.io/posts/algo-23/