CS/알고리즘
[알고리즘] 탐욕(Greedy) 알고리즘
ChaeHing
2023. 3. 22. 23:57
탐욕(Greedy)
- 사전적으로 '탐욕스러운, 욕심 많은' 이라는 뜻으로 선택의 순간마다 당장 눈앞에 보이는 최적의 상황만을 쫒는것
- 지금 이 순간 당장 최적인 답을 찾는다.
- 항상 최적의 결과를 도출하지는 않지만, 최적에 근사한 값을 빠르게 도출 할 수 있다.
탐욕 알고리즘 단계
- 선택 절차 : 현재 상태에서의 최적의 해답을 선택
- 적절성 검사 : 선택된 해가 문제의 조건을 만족하는지 검사
- 해답 검사 : 원래의 문제가 해결 되었는지 검사, 해결이 안되었다면 선택 절차로 돌아가 반복
탐욕 알고리즘 적용 예시
- 주로 거스름돈 문제가 나오는듯 하다.
- 편의점 알바중 물건의 값이 4230원이 나왔고 손님은 5000원을 냈다. 거스름돈을 줄때 동전의 갯수를 최소한으로 거슬러 줘야한다. 동전은 500,100,50,10원이 있다.
- 단순하게 생각하면 거스름돈은 770원이므로, 500원 1개, 100원 2개, 50원 1개, 10원 2개 이다.
- 선택 절차 : 가장 가치가 큰 동전을 먼저 고려한다. 500원
- 적절성 검사 : 선택절차에서 선택한 동전을 더할때 총합이 안넘는지 확인하고 넘으면 선택절차로 돌아가 한 단계 낮은 동전을 선택한다.
- 해답 검사 : 선택된 동전들의 합이 거스름돈과 일치하는지 검사. 아니라면 1번 부터 다시 반복
// 거스름돈 배열 coin{500,100,50,10}, 거스름돈 change
int greedy (int[] coin, change){
int i=0; // 인덱스
int total=0; // 동전의 합
int count=0; // 동전 갯수 카운팅
while(true){ // 반복문
if(total+coin[i] > change){ // 동전의 합이 거스름돈을 넘는다면
i++; // 다음동전 인덱스
continue; // 다시 반복문 처음으로
}
total += coin[i]; // 해당 동전의 값 합계에 더하기
count++; // 동전 카운팅
if (total == change) break; // 동전의 합이 거스름돈과 같아진다면 반복문 나오기
}
return count++; // 동전 카운트 반환
}
탐욕 알고리즘을 적용하기 위한 문제 조건
- 문제가 마시멜로 실험과 같다면 탐욕 알고리즘을 사용 할 수 없다.
- 마시멜로 실험이란 마시멜로를 1개를 주고 먹지않고 15분을 참으면 1개를 더 주기로하는 것인데
탐욕 알고리즘 매순간 최선의 선택만 하므로 15분을 기다리지 않고 1개를 먹게된다. - 탐욕 알고리즘을 적용하기 위한 문제의 조건은
- 탐욕적 선택 속성 : 앞의 선택이 이후의 선택에 영향을 주지 않는다.
- 최적 부분 구조 : 문제에 대한 최종 해결 방법은 부문 문제에 대한 최적 문제 해결 방법으로 구성된다.