휴리스틱 알고리즘 차이 - hyuliseutig algolijeum chai

휴리스틱 알고리즘(Heuristic Algorithm)

  • 2020.12.27 22:40
  • Koala - 1기

* 이 글은 "알고리즘 문제 해결 전략(종만북)" 中 11장 조합 탐색에 나온 내용을 바탕으로 작성하였습니다.

우리가 문제 해결 시 흔히 사용하는 동적 계획법(DP) 또는 분할 정복과 같은 완전 탐색에 기초한 디자인 패러다임

사실 실생활에서 쓰기엔 매우 한정적이다. 

예를 들어, 인공지능 체스 프로그램을 알고리즘으로 짠다고 할 때 우리가 가장 먼저 떠올릴 수 있는 것은

브루트 포스(brute force) 방식이다. 즉, 가능한 모든 말의 움직임을 다 해보는 것이다.

하지만 이 방식은 어림도 없는게 움직일 수 있는 말과 이동 가능한 칸이 너무 많기 때문에 만약 이 방식으로 프로그램을 개발했다고 하면, 죽을 때까지 게임이 끝나지 않을 것이다. (경우의 수가 10^120 가지라고 합니다.)

그렇다고 해서 분할 정복 기법을 사용하자니 적절한 분할 방법이 생각나질 않고

동적 계획법을 사용하자니 메모리가 턱없이 모자르다.

결국 우리는 모든 경우의 수를 확인하지 않고도 답을 찾아낼 수 있는 방식을 사용해야 한다.

(주의 - 이분 탐색은 당연히 모두 확인하지 않아도 되는 것이지만 휴리스틱은 모두 확인해야 정확하게 찾을 수 있는데 안 하는 것입니다!)

* 위에서 극단적인 예시로 체스 프로그램을 예로 들었지만 실제 문제 풀이에서는 체스처럼 엄청 큰 입력이 들어오진 않고 동적 계획법으로 최적화가 되지 않을 정도의 입력이 들어오는 것으로 알고 있습니다!

휴리스틱 알고리즘이란?

* 휴리스틱(heuristics)이란 불충분한 시간이나 정보로 인하여 합리적인 판단을 할 수 없거나, 체계적이면서 합리적인 판단이 굳이 필요하지 않은 상황에서 사람들이 빠르게 사용할 수 있게 보다 용이하게 구성된 간편 추론의 방법이다.

(출처 : 위키백과 - 휴리스틱 이론)

휴리스틱 알고리즘은 기본적으로 모두 최적해가 될 가능성이 없는 답들을 탐색하는 것을 방지하여 만들어 봐야 할 답의 수를 줄이는 것을 목표로 한다.

하지만 어떠한 방법으로 경우의 수를 최적화할지는 매우 어렵고 실제로 고수분들도 문제 풀이에 대해 확신하지 못하기 때문에 가장 나중에 풀거나, 부분 점수를 노리는 경우가 많다고 한다.

휴리스틱 관련 이론

  • 가지치기(pruning) 기법
  • Simulated Annealing (담금질 기법)
  • Genetic Algorithms (유전 알고리즘)

휴리스틱이라고 할 수 있는 기법들은 보통 이 정도인 것 같다. 

여기서 담금질과 유전은 머신러닝에서 자주 등장하는 걸로 알고 있는데

휴리스틱 관련 문제에 대한 해답을 찾던 중 볼츠만 상수와 온도 감률을 정해 simulated annealing로 푸시는 구사과님의 풀이를 보고는 역시 여기는 내 길이 아니구나 싶었다... (https://koosaga.com/3)

하지만 좌절하지 말고 이번 scpc에서 휴리스틱이 나오면 10점이라도 얻어가기 위해 가지치기만 살펴보자!

가지치기(pruning) 기법

가지치기 기법은 탐색 과정에서 최적해로 연결될 가능성이 없는 부분들을 잘라낸다.

예를 들어 길이가 10인 경로를 이미 찾았는데, 이후 다른 경우의 수를 구하는 과정에서 도착점에 도착하기도 전에

길이가 10이 넘어가면 마저 탐색하지 않고 종료해버리는 방법이 될 수도 있고

중간까지 와서 목적지까지 경로를 어림짐작했는데 지금까지 구한 최단 거리보다 먼 경우 종료해버릴 수도 있다.

이 방법을 사용하면 존재하는 답 중 일부는 아예 만들지 않기 때문에 프로그램의 동작 속도가 빨라지게 된다.

효율성을 극대화하기 위해선 가장 좋은 답의 상한을 빨리 찾아내서 얼토당토않는 경우를 탐색 초기에 종료해버려야 한다.

외판원 순회(TSP)에서의 가지치기

종만북에서는 외판원 순회 문제를 휴리스틱을 이용해 도시의 수가 20개일 때 3초 만에 해결할 수 있게 만들어 준다.

이 과정을 모두 설명할 수는 없고, 그중 단순한 가지치기 기법에 대해 살펴보자.

외판원 순회에서 가지치기는 '어림짐작' 기법을 이용한다.

즉, 한 상태가 주어질 때 아직 남은 도시들을 방문하기 위한 경로가 얼마나 길지를 적당히 '어림짐작' 하는 것이다.

이 결괏값은 항상 정확할 필요는 없고, '적당히 그럴 듯' 해 보여야 한다.

휴리스틱 알고리즘 차이 - hyuliseutig algolijeum chai

예를 들어 6개의 도시가 있을 때 어떤 한 도시에서 출발하여 모든 도시를 거쳐 다시 출발지로 돌아오는 최단 경로를 계산하는 TSP 문제가 주어졌고 우린 이미 1-2-5-6-4-3-1로 이동하는 거리 11인 답을 발견한 상태라고 해보자.

하지만 아직 답이 확정되지 않았기 때문에 우리는 다른 경로도 조사해봐야 한다.

우리가 이용해볼 방법은 아직 방문하지 않은 도시들에 대해 인접한 간선 중 가장 짧은 간선의 길이를 더하는 것이다.

아직 방문하지 않은 도시를 방문하려면 인접한 간선 중 하나를 타고 가야 하므로, 이들 중 가장 짧은 간선의 길이들을

모두 더하면 실제 최단 경로 이하의 값이 될 수밖에 없기 때문이다.

만약 5-3 또는 3-5로 이동했을 때 아직 방문하지 않은 도시들에 대해 인접한 간선 중 가장 짧은 간선의 길이들을 더 해보면 총 5의 거리가 산출된다.

(노드 1 = 1, 노드 2 = 1, 노드 4 = 1, 노드 6 = 2 -> 총 5)

하지만 이미 우린 10만큼을 이동했고, 거기에 5를 더하면 지금까지 구한 최단 거리인 11보다 크게 된다.

즉, 5-3 또는 3-5를 거치는 답은 절대 나오지 않는다는 것이니 가지치기가 가능하게 된다.

실제로 종만북에서는 MST 등 다양한 알고리즘을 휴리스틱 기법으로 해석해 TSP 문제 해결 시간을 줄여나가니 궁금하면

종만북을 통해 보는 것을 추천한다.

관련 문제

  • 백준 2582 동전 뒤집기 - https://www.acmicpc.net/problem/2582
  • 2018 scpc 1차 예선 4번 선형배치
  • 2019 scpc 1차 예선 4번 파이프
  • 2019 scpc 2차 예선 4번 폭격

scpc 문제는 코드그라운드(https://www.codeground.org/) 에서 확인 가능합니다.

결론

휴리스틱 알고리즘은 구글링해도 자료가 거의 없을 정도로 글로 설명하기 어려운 알고리즘인 것 같다.

명확한 답이나 해결 방법이 존재하는 것도 아니고, 관련 문제가 많지도 않다.

하지만 휴리스틱 문제는 보통 "이 중 몇 개의 테스트 케이스를 통과하면"이나 "정답 범위 안으로 출력 시" 등 

항상 최적해를 구할 수 없다는 것에 대한 힌트가 문제에 주어지거나 (백준에서)

완전 탐색이나 dp로 풀지 못하는 입력 조건이 있고, 어찌 저찌~ 잘 배치해라 ~ 라는 문제가 주로 나온다.

나와 비슷한 수준의 분들이 이런 문제를 보셨다면

최대한 가지치기를 해보던지 아니면 입력 범위보다 모자라게 dp를 사용하여 부분 점수라도 얻어가는 편이 좋아 보인다.


=>알고리즘 ( algorithm )

유한한 단계를 통해 문제를 해결하기 위한 절차나 방법으로 원래는 인도에서 아랍를 거쳐 유럽에 보급된 필산(筆算)을 뜻하며, 아랍의 수학자인 알콰리즈미의 이름에서 유래한다. 또한, 알고리즘은 수학용어와 컴퓨터 용어 두 가지로 나누어 설명할 수 있다.

먼저 수학용어로서 알고리즘은 잘 정의되고 명백한 규칙들의 집합 또는 유한 번의 단계 내에서 문제를 풀기 위한 과정이다. 예를 들면, 주어진 정확도에 맞도록 x의 코사인 값을 계산하기 위한 대수적인 과정도 알고리즘에 해당된다. 경험적 지식(heuristic)과 반대되는 용어이다.

그리고 컴퓨터용어로서 알고리즘은 어떤 문제의 해결을 위해 컴퓨터가 사용 가능한 정확한 방법을 말한다. 쉽게 표현하면 프로그램의 이용법을 익히는 것이 아니고, "만들수 있는 능력을 가지는 것[창조능력]" 이라 할 수 있다. 이는 보통 프로그래밍언어인 파스칼(Pascal), 시(C, C++), Quick Basic 등으로 표현한다.
알고리즘은 여러 단계의 유한한 집합으로 구성되는데, 여기서 각 단계는 하나 또는 그 이상의 연산을 필요로 한다. 이 때 컴퓨터가 각 연산들을 수행하기 위해서는 다음의 조건을 만족해야 한다.

*명확성:각 연산들은 명확한 의미를 가져야 한다.
*효율성:각 연산은 원칙적으로 일정한 시간 내에 사람이 연필로 할
수 있어야 한다.
*입력:외부 입력자료가 있을 수 있다.
*출력:하나 이상의 결과가 나온다.
*종결성:유한 번의 연산 후에는 끝나야 한다.

예를 들어 알고리즘을 쉽게 설명해보면 만약에 A라는 사람이 어떤 프로그램을 만든다고 가정을 해보자.
그럼 A는 프로그램을 만들기 위해서는 프로그램의 구조가 머리 속에 있어야 될 것이다.
만약 10개의 숫자 중에서 최대값을 구하는 프로그램을 만든다고 하고 그럼 먼저 최대값을 구하기 위해서 A는 어떤 조치를 취해야 할까?
사람들은 숫자를 보면 이게 제일 큰 수다 알수있지만 컴퓨터는 알수없다. 따라서 하나씩 비교를 해봐야 할 것이다. 이 비교하는 것을 프로그래밍 코드로 구현하는 것이 바로 알고리즘이라고 할 수 있다.
즉, 어떤 문제를 풀기위해서 프로그래밍 언어의 코드로 그 문제를 기술해서 돌파구를 만들어주는것이 바로 알고리즘이라고 할 수 있다.

=>휴리스틱스(heuristics)

휴리스틱스는 설명가능한 ‘경험에 의한 방법(rule of thumb)’과 ‘표준적 실천’ 등으로 구성된다..

이는 불확실한 조건에서 판단을 내릴 때 인간은 확률이나 효용극대화 이론을 복잡하게 따지려 들기보다는 경험 법칙에 비추어 어림짐작으로 가장 그럴듯하게 여겨지는 방법에 의존한다는 것이다.

즉, 경험이나 직관으로 기대한 것보다 효율적으로 해를 얻을수 있는 방법을 의미한다. 이를 뒷받침하는 전형적인 예는 '택시 시나리오'이다. 어느 날 밤 어느 택시가 행인을 치고 달아났는데, 한 노인이 자신의 집 창문 너머로 파란색 택시가 뺑소니를 치는 장면을 목격했다. 피해자의 변호사는 사건을 성립시키기 위해 다음의 2가지 사실을 제시했다. 첫째, 이 도시에 택시 회사라고는 '블루택시', '블랙택시' 두 곳밖에 없는데, 사건 당시 운행된 택시의 85%는 검은색, 나머지 15%는 파란색이며, 둘째, 사건 당일 밤과 비슷한 조건에서 목격자의 시력을 면밀히 검사한 결과 사건 당시 뺑소니 택시의 색상에 대한 목격자의 판단 정확도가 80%라는 것이었다. 주어진 조건에서 뺑소니 차량이 파란색일 수학적 확률은 절반도 안 되는 0.41, 즉 41%에 불과하고 뺑소니 차량이 실제로 검은색일 확률이 더 높지만, 배심원은 목격자의 진술이 옳을 확률이 0.8, 즉 80%이므로 뺑소니 택시가 파란색이었다고 판단하고 블루택시 회사에 손해배상 책임을 묻기 십상이고, 대부분의 사람들도 배심원의 평결을 옳다고 받아들인다. 또한 평결 후 배심원에게 수학적 확률을 제시한다 하더라도 배심원의 생각은 쉽게 바뀌지 않는다는 것이다.

엄밀한 의미에서 휴리스틱 기법은 위에서말한 명확히 정해진 절차에 의하는 알고리즘적 기법과 구별된다. 휴리스틱 기법의 주된 용도는 정의하기 힘든 문제, 예를 들어 여러개의 직업중 어떤것이 좋은가, 혹은 예산을 어떻게 쓰는것이 바람직한가 하는 따위의 문제들을 풀거나 맹목적인 기법으로 풀기에는 너무나 많은 시간과 기억공간이 필요하여 현실적으로 답을 얻는것이 불가능한 경우가 된다.
넓은 문제 영역을 지닌 문제의 해답을 찾기 위해 탐색의 방식을 극도로 간략화시킨 일종의 주먹구구의 방식이다.

휴리스틱스 방식은 정해진 시간에 적절한 해답을 찾을 수 있으나 최선의 해답이 보증되지 않는다. 해답이 보증되는 알고리즘 방식과 대비된다.