1. 그리디 알고리즘이란?


그리디 알고리즘은 직관적인 알고리즘이다.


직관적으로 문제를 여러 조각으로 쪼개고, 각 단계마다의 답으로 최종 답을 쌓아간다는 점에서,


그리디는 재귀 호출, 완전 탐색, 동적 계획법 알고리즘과 다를 게 없다.


하지만 위의 세 가지 알고리즘들은 모든 방법을 고려해보고 그 중 가장 좋은 답을 찾는 방법이지만,


그리디만은 특별하게 각 단계마다 당장 가장 좋은 답을 선택한다는 것이 차이점이다.


즉, 최적의 답은 최적의 부분답들로 이루어진다는 것이다.


따라서 그리디 알고리즘을 적용시킬려면, 위의 조건이 지켜지는 문제여야만 한다.



2. 어디에 적용시킬까?


2-1) 백준 1931. 회의실 배정

https://www.acmicpc.net/problem/1931


각 팀들은 회의하고 싶은 시간을 제출했을 때, 서로 겹치지 않는 회의들만을 골라서 진행해야 한다.


이 때, 최대 몇 개의 회의들을 선택할 수 있을까?


탐욕적으로 해결하기 위해, 가장 짧은 회의부터 보면서 앞의 선택과 겹치지 않는 회의를 추가하는 방법을 생각해보았다.

이 방법은 "탐욕적"으로 회의실이 사용되는 시간을 최대화려는 점에서 꽤나 그럴싸한 방법이다.


 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 0

 2

 4

 6

 8

 10

 12

 14


하지만 위와 같은 입력이 주어진다면 앞의 방법으로는 짧은 회의 하나만을 선택해버린다.

이처럼 그럴듯 하다고 정답이 되지는 않는다. 그리디가 어려운 이유 중 하나다.


다른 탐욕적인 방법으로 길이와 상관없이 가장 먼저 끝나는 회의를 고르기로 해보자.

가장 먼저 끝나는 회의를 고르고, 겹치는 회의들은 리스트에서 지우고, 나머지 중에 가장 먼저 끝나는 회의를 고르는 것을 반복한다.


결론부터 말하자면, 위의 방법이 정답중에 하나다.

덜 직관적인 방법이라서, 가장 많은 회의를 고르는 방법인지 의심이 간다. 

그래서 그리디 알고리즘의 정당성을 증명해야 하는데, 두 가지 속성을 증명해야 한다.


첫째로, 동적 계획법 처럼 모든 방법을 고려하지 않고 탐욕적인 방법으로도 최적해를 구할 수 있다는 속성이다.

이를 탐욕적 선택 속성, greedy choice property 라고 부른다.

위를 증명하면, 각 단계에서의 탐욕적인 선택은, 최적해로 가는 길 중 하나임이 보장된다.

회의실 문제에 대입해보면, 가장 종료 시간이 빠른 회의를 포함하는 최적해가 반드시 존재한다는 뜻이다.

최적해가 존재하므로 그리디 방법을 적용시킬 수 있다는 뜻으로 받아드리면 되겠다.


증명은 귀류법처럼 진행된다. 최적해 중에 가장 종료 시간이 빠른 회의를 고르지 않는 방법이 있다고 해보자.

이 방법을 써서 고른 회의들 중에, 첫 번째로 개최되는 회의(A)를 빼고, 대신 가장 종료시간이 빠른 회의(B)를 대신 추가한다고 하면,

B는 모든 회의들 중에 가장 빨리 끝나는 회의이기 때문에, A는 B보다 종료시간이 빠를 수가 없다.


따라서 최적해는 항상 B같이 가장 종료시간이 빠른 회의를 포함할 수 밖에 없다.


둘째로 증명해야 하는 속성은, 나머지 문제들도 항상 최적의 선택을 해야하는 문제라는 속성, 최적 부분 구조(optimal substructure)이다.

부분 문제의 최적해에서 전체 문제의 최적해를 만들 수 있다는 뜻이다.


다행히 회의실 문제의 이 속성은 매우 자명하다. 첫 번째 회의를 고르고나면, 당연히 겹치는 회의들은 고를 수 없고,

남은 문제들도 여전히 최대한 많은 회의를 고르는 문제이기 때문이다.


따라서 최종답은 부분문제의 최적해로 이주어진다는 것을 증명하였다.

즉, 우리는 회의실 문제가 탐욕적으로 가장 빨리 끝나는 회의들을 골라야하는 문제라는걸 알게 된 것이다.


코드 : http://js1jj2sk3.tistory.com/11


2-2) 백준 11047. 동전 0

https://www.acmicpc.net/problem/11047


임의의 액수 X가 주어지고, 동전들을 가장 적게 써서 X를 만드는 방법을 찾는 문제다.


가장 작은 동전은 항상1이고, 다음으로 작은 동전은 그 이전 동전의 배수다. 따라서 X를 못 만드는 경우는 없다.


매우 직관적으로 당신이 떠올린 방법, 그것이 정답이다.

가장 큰 동전을 최대한으로 쓰고, 남은 액수는 다음으로 큰 동전을 최대한으로 쓰는 방법이다.


정당성을 증명하자면,


첫째로, 가장 큰 동전(A)을 쓰지 않는 방법이 있다고 하자, 그 방법에서 가장 큰 동전(B)을 빼보면, (X - B*N1) 이고,

이 액수는 다시 A를 써서 X를 만들 수 있다. 이는 서로 배수인 점에서 가능하다. X - B*N1 + A*N2 = X

당연히 N1>N2 이므로 최적해는 가장 큰 동전을 쓰는 방법임이 증명되었다.


둘째로, 당연하게도 A를 써서 X를 일부 만들었다면, 남은 액수 X-A*N2 에 대한 문제는 가장 동전을 적게쓰는 문제다.


코드 : http://js1jj2sk3.tistory.com/7

'알고리즘 > Greedy 그리디' 카테고리의 다른 글

백준) 1931 회의실배정  (0) 2017.07.25
백준) 1946 신입 사원  (0) 2017.07.25
백준) 1744 수 묶기  (0) 2017.07.24
백준) 4796 캠핑  (0) 2017.07.23
백준) 11047 동전 0  (0) 2017.07.23

+ Recent posts