모든 경우의 수를 시도하는 방법. 무식하게 모든 경우의 수를 탐색해보는 알고리즘이다. 브루트-포스 알고리즘(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/