알고리즘 수업에서 Greedy Algorithm 예시로 접하는 것이 바로 거스름돈 문제(Change-Making Problem) 이다.
"가장 적은 개수의 동전으로 거스름돈을 주려면 어떻게 해야 할까?"
가장 먼저 "가장 큰 단위의 동전부터 낼 수 있는 만큼 낸다"는 그리디(Greedy) 전략을 떠올릴 수 있다. 아주 직관적이며, 한국의 원화 나 미국의 달러 체계에서는 이 전략이 유효하다.
하지만 동전 체계가 라면 어떨까?
그렇다면 "언제 그리디 알고리즘이 잘 작동할까?"라는 의문이 생긴다.
하나의 추측은 동전들이 서로 배수 관계인 것이다. 실제 대부분의 통화 시스템의 공통점을 살펴보면 떠올릴 수 있는 추측이며, 서로 배수 관계일 때 그리디 알고리즘은 잘 작동한다.
- 배수 관계라는 것은 구체적으로 10의 배수 50, 50의 배수 100, 100의 배수 500처럼 바로 다음 크기의 동전이 배수인 것이다.
- 그런데 100이 5개 이상 있으면 500으로 대체되므로 100은 최대 4개 있을 수 있다. 마찬가지로 50은 1개, 10은 4개까지 가능하다.
- 그렇다면 500없이 만들 수 있는 금액은 최대 10×4 + 50×1 + 100×4 = 490으로 500을 넘을 수 없다.
- 따라서 500이상 금액을 만드려면 반드시 500을 포함해야하며, 반복적으로 적용하면 500을 최대한 많이 포함해야한다.
- 이것이 결국 그리디 알고리즘의 선택과 일치한다.
하지만 꼭 배수 관계여야하는 것은 아니다.
에서 25는 10의 배수가 아니지만 그리디 알고리즘이 잘 작동한다.
거스름돈 문제에서 그리디 알고리즘이 잘 작동하는 화폐 시스템을 Canonical Coin System라 부른다. 그런데 이를 판별하기 위한 필요충분조건은 배수 관계처럼 간단히 설명할 수 없다. 그 조건을 살펴보고 직관적으로 이해해보자.
가지 동전이 크기 순으로 있다.
어떤 금액 를 만들 때, 그리디 알고리즘으로 구한 동전 개수를 , 실제 최적 동전 개수를 라고 하자. 이때, 모든 자연수 에 대해 를 만족하는 동전 체계를 Canonical Coin System이라고 한다.
직관적으로 생각해보면, 반례(Counterexample, 인 경우)가 있는 지 확인할 때 적당한 범위 안에서만 확인하면 될 것 같다. Kozen과 Zaks(1994)이 반례가 존재할 수 있는 상한선을 수학적으로 증명해두었다.
그리디 알고리즘이 최적해를 보장하기 위한 필요충분조건은 다음과 같다.
"다음 범위 내에 반례 가 존재하지 않는다."
즉, 이 범위 안에서 반례가 발견되지 않으면, 그보다 큰 어떤 숫자에서도 반례는 나오지 않는다.
이 증명은 귀류법(Proof by Contradiction)과 공통 동전 제거(Reduction) 아이디어를 사용한다.
3-2.를 생각해보자.
는 아주 크므로(이상) 최적해()의 동전 일부 또는 전체를 선택하여 보다 크게 만들 수 있다. 그러한 조합 중 합이 가장 작은 조합을 생각해보자. 그 조합의 합을 라고 하면, 이다. 왜냐하면 동전 하나를 빼면 이하이다. 거기에 동전 하나를 더한다면 가장 큰 값이 이므로 이다.
가 보다 크므로, 가장 작은 반례라고 한 가 = 두 부분으로 나누어진다. 는 가장 작은 반례 보다 작으므로 그리디 알고리즘으로 최적해를 찾을 수 있고 이므로 의 최적 해는 을 포함한다. 따라서 = 의 최적 해는 의 그리디 해와 의 최적 해의 합으로 구할 수 있는데, 의 그리디 해에 이 포함된다. 결국 의 최적 해에 이 포함되므로 3-2가 일어날 수 없고 반드시 3-1이 된다.
Kozen & Zaks의 정리는 탐색 범위를 획기적으로 줄여주었다. Pearson(2005)은 이를 개선하여 범위 안의 모든 수가 아니라 검사해야하는 후보를 추려서 다항 시간() 내에 판별할 수 있는 방법을 제시했다.
반례는 아무 숫자에서나 뜬금없이 튀어나오지 않는다. 그리디 알고리즘이 실수를 범하는 순간은 "작은 동전들을 모아 큰 동전 하나로 바꿀 수 있는 경계" 근처이다.
Pearson은 반례가 될 수 있는 후보군(Test Set)이 두 동전의 합()과 밀접한 관련이 있음을 밝혔다.
예를 들어 시스템에서 은 보다 크다. 그리디 알고리즘이 을 선택하게 만들어 최적 해()를 깨뜨리는 결정적인 반례 후보가 된다. 을 모아서 보다 커지는 경우가 검사할 후보가 된다.
모든 를 다 뒤질 필요 없이, 아래와 같은 형태의 '위험군' 숫자들만 검사하면 된다.
우리가 흔히 사용하는 화폐 시스템은 그리디가 통하지만, 꼭 그렇지만은 않다.