Ch04-1

advertisement
Ch.04
Greedy Method (탐욕적 방법)
[CPA340] Algorithms and Practice
Youn-Hee Han
http://link.kut.ac.kr
탐욕적 알고리즘 개요

Origin
 Charles Dickens’ classic character ‘Ebenezer Scrooge’


He is the most greedy person ever

He never considered the past or future

He greedily grab as much as gold as he could

“Ghost of Christmas Past” reminded him of the past

“Ghost of Christmas Future” warned him of the future

Finally, he changed his greedy ways
Greedy method for algorithm design
 It determines something, each time taking the one that is deemed “best”
according to some criterion, without regard for the choices it has made
before or will in the future.
Page 2
탐욕적 알고리즘 개요

탐욕적 알고리즘(Greedy Algorithm)은 무엇인가를 결정을 해야 할 때마
다 그 순간에 가장 좋다(최적이다)고 생각되는 것을 선택함으로써 최종적
인 해답에 도달한다.

알고리즘 설계의 많은 경우에 있어서 탐욕적인 방법은 매우 효율적이고
(거의) 정확한 해답을 산출한다.
Page 3
탐욕적 알고리즘 개요

개념적으로 탐욕적 알고리즘은 동적 프로그래밍과 정반대의 전략이다.
 동적 프로그래밍은 매우 엄격한 계획하에 ‘재귀적 속성’을 찾아서 그것을 기본
으로 최종적인 (global) 해답을 Bottom-up 전략으로 찾아낸다.

하지만, 탐욕적 알고리즘은 매순간 선택의 과정을 거치는데… 그 선택은
국부적(local)으로 최적이다.
 최적이라고 생각했던 해답들을 모아서 최종적인(global)해답을 만들었다고 해
서, 그 해답이 궁극적으로 최적이라는 보장이 없다.
 따라서 탐욕적인 알고리즘은 항상 최적의 해답을 주는지를 반드시 검증해야 한
다.
 많은 경우 직관적으로 검증 없이 최종적인 해답을 올바른 답으로 간주한다.
Page 4
탐욕적 알고리즘의 설계 절차
1. 선정과정(selection procedure)
- 현재 상태에서 가장 좋으리라고 생각되는(greedy) 부분 해답을 선택
2. 적정성 점검(feasibility check)
- 선택한 부분 해답이 최종 해답모음 (solution set) 에 포함되는 것이
알고리즘이 풀고자 하는 목적에 비추어 적절한지를 결정한다.
- 적절하다면 최종 해답모음에 포함 (Union) 시킨다.
3. 해답점검(solution check)
- 새로 얻은 해답모음이 풀고자하는 문제의 해답인지를 결정한다.
Page 5
탐욕적 알고리즘의 설계 절차
 대략적인 알고리즘 구성법
// Algorithm takes an array a of n elements as input
algorithm greedy ( a, n ) {
solution = {}; // Initially empty
do {
for ( i = 0; i < n; i++ ) {
// Select an input from a and remove it
// from further consideration
x = select ( a );
if ( feasible ( solution, x ) )
solution = solution + x; // Union
}
} while ( !check ( solution ) );
return ( solution );
}
Page 6
Example - 거스름돈 계산하기
 [쉬어가기] 미국과 한국의 동전 (Coins) 시스템
One dollar ($1) – Andrew Johnson
오백원 (₩500)- 두루미
Half dollar ($0.50) - John F. Kennedy
백원 (₩100) – 이순신
Quarter ($0.25) - George Washington
오십원 (₩50) – 쌀
Dime ($0.10) - Franklin D. Roosevelt
Nickel ($0.05) - Thomas Jefferson
Penny or Cent ($0.01) - Abraham Lincoln
십원 (₩10) – 다보탑
오원 (₩5) – 거북선
일원 (₩1) – 무궁화
Page 7
Example - 거스름돈 계산하기
 교재의 문제: 가지고 있는 동전 중에서 거스름 돈을 줄 때에 동전의 개수가
최소가 되도록 거스름 돈을 주는 문제
 탐욕적인 알고리즘 (A Greedy Algorithm)
• 거스름돈을 x라 하자.
• 먼저, 가치가 가장 높은 (액면가가 높은) 동전부터 x가 초과되지 않도록
계속 내준다.
: At each step, take the largest possible coin that does not overshoot x
: 만약 초과가 되면 도로 집어넣는다.
• 이 과정을 총액이 정확히 x가 될 때까지 계속한다.
Page 8
Example - 거스름돈 계산하기
Greedy solution – Example 1

가지고 있는 돈
 Quarter ($0.25) – 1, Dime ($0.10) – 2, Nickel ($0.05) – 1, Penny
($0.01) – 2

거스름돈: $0.36
Add quarter($0.25) to
change
$0.25
Remaining: $0.36 – $0.25 = $0.11
Add dime($0.10) to change
Remaining : $0.11 – $0.10 = $0.01
Delete dime($0.10)
Delete nickel($0.05)
Add penny($0.01) to change

Remaining: $0.01 – $0.01 = $0.00
Optimal Solution
 {one quarter($0.25), one dime($0.10), one penny($0.01)}
Page 9
Example - 거스름돈 계산하기
 탐욕 알고리즘 설계 과정에 따른 분석
• 선정과정: (지닌 동전 중 가치가 가장 높은) 동전을 선택한다.
• 적정성 검사: 거스름돈 총액을 넘는지 확인한다.
• 해답 점검: 현재까지의 금액이 거스름돈 총액에 도달했는지 확인한다.
 현재 미국이나 한국에서 유통되고 있는 동전만을 가지고, 이
알고리즘을 적용하여 거스름돈을 주면, 항상 동전의 개수는
최소가 된다. 따라서 이 알고리즘은 최적(optimal)!
 증명 생략
 하지만, 동전 시스템이 조금 다르다면 앞에 앞에 소개한 탐욕
알고리즘을 적용하여 거스름돈을 주었을 때, 항상 동전의
개수가 최소가 된다는 보장이 없다.
Page 10
Example - 거스름돈 계산하기
Greedy solution – Example 2

가지고 있는 돈
 New coin ($0.12) – 1, Dime ($0.10) – 1, Nickel ($0.05) – 1, Penny
($0.01) – 4

거스름돈: $0.16
Add new coin($0.12)$0.25
to change
Remaining: $0.16 – $0.12 = $0.04
Delete dime($0.10)
Delete nickel($0.05)
Add four fenny($0.01) to change

Remaining: $0.04 – $0.04 = $0.00
Is it optimal?
 No.
 {One dime($0.10), One Nickel($0.05), One Penny($0.01)} is
optimal solution
Page 11
그래프 용어 – 좀 더 복습하기
 비방향성 그래프(undirected graph) G = (V,E)
• V는 정점(vertex)의 집합
• E는 이음선(edge)의 집합
 경로(path): 두 노드 사이에 이음선으로 연결된 노드의 나열
 연결된 그래프(connected graph)
: 임의의 두 노드 사이에 경로가 존재
 부분그래프(subgraph)
 가중치 포함 그래프(weighted graph)
 순환(cycle)
 순환적그래프(cyclic graph), 비순환적그래프(acyclic graph).
 트리(tree): 비순환적이며, 비방향성 그래프
 뿌리 있는 트리(rooted tree): 한 정점이 뿌리로 지정된 트리
Page 12
신장트리 (Spanning Tree)
 연결된 비방향성 그래프 G에서, 순환경로(cycle)가 없어 지도록 이음선을
제거하여 구성한 연결된 부분그래프를 신장트리(spanning tree)라 한다.
 따라서 신장트리는 G안에 있는 모든 정점을 다 포함하되 트리가 되는(i.e.,
순환경로가 존재하지 않는) 연결된 부분그래프이다.
최소비용신장트리
Page 13
최소비용 신장트리(Minimum Spanning Tree)
 G의 부분그래프인 여러 신장트리 중에서 가중치의 합이 최소가 되는 부분
그래프를 최소비용신장트리(minimum spanning tree, MST)라고 한다.
 관찰
•
모든 신장트리가 최소비용신장트리는 아니다.
•
주어진 그래프에서 최소비용신장트리는 1개 이상 존재할 수 있다.
Page 14
최소비용 신장 트리의 응용(Applications)
 도로건설:
도시들을 모두 연결하면서 도로의 길이가 최소가 되도록 하는 문제
 통신(telecommunications):
전화선의 길이가 최소가 되도록 전화 케이블 망을 구성하는 문제
 배관(plumbing):
파이프의 총 길이가 최소가 되도록 연결하는 문제
Page 15
MST – Brute-Force 알고리즘
 알고리즘
• 모든 신장트리를 다 고려해 본다(계산해 본다).
• 그 중에서 최소비용이 드는 것을 신장트리를 고른다.
 분석
• 최악의 경우, 지수보다도 나쁘다.
• 이유?
( 완전 연결이면… 대략적으로 생각해도 n!에 해당한다.)
Page 16
비방향 그래프와 신장 트리의 형식적 정의
 비방향 그래프 (Undirected Graph)
• 비방향그래프 G는 정점의 유한집합 V와 V에 속한 정점의 쌍의 집합 E
로 구성된다.
• G는 G=(V, E)로 표현
• V의 원소는 vi로 표시하고 vi와 vj를 연결하는 간선은 (vi, vj)로 표시
 신장 트리
• G의 신장 트리는 T = (V, F)로 표현
• T의 정점 집합 V는 G의 정점 집합인 V와 같지만
• T의 간선 집합 F는 G의 간선 집합인 E의 부분 집합이다. (E  F)
Page 17
비방향 그래프와 신장 트리의 형식적 정의
 예제 4.1 (p. 139)
Page 18
MST – 추상적인 탐욕적 알고리즘
 문제: 비방향성 그래프 G = (V,E)가 주어졌을 때, F  E를 만
족하면서, T=(V,F)가 G의 MST가 되는 F를 찾는 문제.
 개략적인 알고리즘:
1. F := 0;
2. 최종해답을 얻을 때까지 다음 절차를 계속 반복
(a) 선정 절차: 적절한 최적 (국부적으로 최적인) 해 선정절차에 따라서
하나의 이음선을 선정
(b) 적정성 점검: 선정한 이음선을 F에 추가시켜도 순환경로가 생기지
않으면, F에 추가시킨다.
(c) 해답 점검: T = (V,F)가 신장트리이면, T가 최소비용신장 트리 이다.
Page 19
MST – Prim 알고리즘 (추상적)
1. F := 0;
2. Y := {v1}; //정점들의 부분 집합
3. 최종해답을 얻을 때까지 다음 절차를 계속 반복하라
(a) 선정 절차/적정성 점검: Y 에 속한 임의의 정점과 가장 가까운 (즉,
가중치가 가장 낮은) V  Y 에 속한 정점 하나를 선정한다.
(자연스럽게 순환은 생기지 않는다.)
(b) 두 정점을 연결하는 이음선을 F에 추가한다.
(c) 선정한 정점을 Y에 추가한다.
(d) 해답 점검: Y = V가 되면, T = (V,F)가 최소비용 신장
트리이다.
위 알고리즘은 사람이 그래프를 보고 답을 구하기에는 적합하지
만 컴퓨터 프로그램으로 구현하기에는 적합하지 않다.
Page 20
MST – Prim 알고리즘 (추상적)
Y := {v1}
F := {}
Y := {v1, v2, v3}
F := {(v1, v2), (v1, v3)}
Y := {v1, v2, v3, v5}
F := {(v1, v2), (v1, v3), (v3, v5)}
Y := {v1, v2}
F := {(v1, v2)}
Y := {v1, v2, v3, v5, v4}
F := {(v1, v2), (v1, v3), (v3, v5), (v3, v4)}
Page 21
MST – Prim 알고리즘 (구체적)
 그래프의 인접행렬식 표현
이음선의 가중치 vi에서 v j 로 이음선이 있는 경우

W [i ][ j ]  
vi에서 v j 로 이음선이 없는 경우
0
i  j 인 경우

 추가적으로 nearest[2..n]과 distance[2..n] 배열 유지
• nearest[i] = vi 에서 가장 가까운 Y 에 속한 정점의 인덱스
• distance[i] = vi와 nearest[i]를 잇는 이음선의 가중치
Y
vj
vi
wi,j
nearest[i] = j
distance[i] = wi,j
Page 22
MST – Prim 알고리즘 (구체적)
 Prim 알고리즘 (1/2)
// 출력: 그래프의 MST에 속한 이음선의 집합
set_of_edge prim(int n,
// 입력: 정점의 수
number[][] W){ // 입력: 그래프의 인접행렬식 표현
index i, vnear;
number min;
edge e;
set_of_edges F;
index[] nearest = new index[2..n];
number[] distance = new number[2..n];
F = empty_set;
for(i=2 ; i <= n ; i++) { // 초기화
nearest[i] = 1;
// 초기에는 Y에 노드가 v1밖에 없음
distance[i] = W[1][i]; // (v1,vi)의 가중치로 초기화
}
// see the next page
Page 23
MST – Prim 알고리즘 (구체적)
 Prim 알고리즘 (2/2)
repeat(n-1 times) {
// n-1개의 정점을 Y에 차례로 추가한다
min = ;
for(i=2 ; i <= n; i++) {
// 각 정점에 대해서
if (0 <= distance[i] < min) { // distance[i]를 검사하여
min = distance[i];
// 가장 가까이 있는 vnear을
vnear = i;
// 찾는다.
}
}
e = vnear와 nearest[vnear]를 잇는 이음선;
e를 F에 추가;
distance[vnear] = -1;
// 찾은 노드를 Y에 추가한다.
for(i=2; i <= n; i++)
if (W[i][vnear] < distance[i]) { // Y에 없는 각 노드에 대해서
distance[i] = W[i][vnear];
// distance[i]와
nearest[i] = vnear;
// nearest[i]를 갱신한다.
}
}
return F;
}
Page 24
MST – Prim 알고리즘 (구체적)
 Prim 알고리즘의 동작과정
vnear=2
F={(1,2)}
vnear=3
F={(1,2), (1,3)}
vnear=5
F={(1,2), (1,3), (3,5)}
Page 25
MST – Prim 알고리즘 (구체적)
 Prim 알고리즘의 동작과정
vnear=4
F={(1,2), (1,3), (3,5), (3,4)}
Page 26
MST – Prim 알고리즘의 분석
 단위연산: repeat-루프 안에 있는 두 개의 for-루프 내부에
있는 명령문(비교문 및 지정문)
 입력크기: 노드의 개수, n
 모든 경우 분석:
• repeat-루프가 n-1번 반복되고,
• 각 루프마다 for-루프가 n-1번씩 수행되므로 (모든 경우의)
시간복잡도는 다음과 같다.
• T(n) = 2(n-1)(n-1)  (n2)
Page 27
MST – Prim 알고리즘의 최적 여부 검증 (1/3)
 Prim의 알고리즘이 찾아낸 신장트리가 최소비용(minimal)인
지를 검증해야 한다. 다시 말하면, Prim의 알고리즘이 최적
(optimal)인지를 보여야 한다.
 탐욕적 방법의 문제점은 이것이다.
즉, 알고리즘을 개발하기는 비교적 용이하나,
개발한 알고리즘의 최적성을 보이는 작업이 어렵다.
Page 28
MST – Prim 알고리즘의 최적 여부 검증 (2/3)
 정의 4.1: 비방향성 그래프 G = (V,E)가 주어졌을 때, 만약 E의 부분
집합 F에 최소비용 신장트리가 되도록 이음선을 추가할 수 있으면
(즉, F에 이음선들을 추가하여 MST가 되면) F는 유망하다
(promising)라고 한다.
• 옆의 그림에서 F1={(v1, v2), (v1, v3)}는 유망 하고
F2={(v2, v4)}는 유망하지 않다.
• “유망”의 의미는 “지금까지 구성한 집합을 사용하여 최적의 솔루션을
구성할 수 있음”을 말한다.
• Prim의 알고리즘에서 구성되는 각 단계의 F들이 유망함을 보이면, 최적
임을 보일 수 있게 된다.
Page 29
MST – Prim 알고리즘의 최적 여부 검증 (3/3)
 보조정리 4.1: G = (V,E)는 가중치 포함 비방향성 연결 그래프라고
하자. E의 부분집합인 F는 유망하며, Y는 F안에 있는 이음선 들에
의해서 연결이 되어 있는 정점의 집합이라고 가정 하자. 이때, Y에
있는 어떤 정점과 V - Y에 있는 어떤 정점을 잇는 이음선 중에서 가
중치가 가장 작은 이음선을 e라고 하면, F  {e}는 유망하다. (즉,
Prim의 방법을 사용한 F  {e}는 유망하다.)
 증명 생략
 정리 4.1: Prim 알고리즘은 항상 MST를 만들어 낸다.
 개략적인 증명
 귀납법을 사용하여 repeat 루프가 매번 수행 후에 집합 F가 유망하다는 것
을 증명함
 구체적 증명 생략
Page 30
Download