동적 계획 (dynamic programming)

Post on 31-Dec-2015

205 Views

Category:

Documents

0 Downloads

Preview:

Click to see full reader

DESCRIPTION

동적 계획 (Dynamic Programming). 동적 계획법. 분할정복식 알고리즘 설계법 나누어진 문제가 연관이 없을 경우 Cf) 피보나찌 알고리즘 동적계획법 (Dynamic programming) 상향식 해결법 (bottom-up approach) 분할정복식 방법과 마찬가지로 문제를 나눈 후 , 나누어진 부분들을 먼저 푼다 . 그러나 이미 풀어서 답을 알고 있는 부분의 결과가 다시 필요한 경우에는 반복하여 계산하는 대신에 이미 계산된 결과를 그냥 사용한다. 동적 계획법. 전략 - PowerPoint PPT Presentation

TRANSCRIPT

동적 계획 (Dynamic Programming)

동적 계획법

분할정복식 알고리즘 설계법 나누어진 문제가 연관이 없을 경우 Cf) 피보나찌 알고리즘

동적계획법 (Dynamic programming) 상향식 해결법 (bottom-up approach) 분할정복식 방법과 마찬가지로 문제를 나눈 후 , 나누어진 부분들을 먼저 푼다 . 그러나 이미 풀어서 답을 알고 있는 부분의 결과가 다시

필요한 경우에는 반복하여 계산하는 대신에 이미 계산된 결과를 그냥 사용한다 .

동적 계획법

전략 재귀 관계식을 정립 상향식 방법 고안 => 프로그래밍

1. 작은 사례를 먼저 푼다 .

2. 그 값을 배열에 저장한다 .

3. 나중에 그 값을 사용한다 .

( 복습 ) 피보나찌 수열 재귀적 방법

int fib (int n) { if (n <= 1) return n; else return fib(n-1) + fib(n-2);}

동적 계획법int fib2 (int n) { index i; int f[0..n];

f[0] = 0; if (n > 0) { f[1] = 1; for (i = 2; i <= n; i++) f[i] = f[i-1] + f[i-2];} return f[n];}

O(2n)

O(n)

이항계수

-==

knkn

Ck

nkn )!(!

!

==

<<-

+-

-=

nk k

nkk

n

k

n

k

n

or 0 1

0 1

1

1

알고리즘 : 분할 정복법

int bin(int n,k)

{

if k=0 or k=n then bin=1;

else bin(n,k)= bin(n-1,k-1)+bin(n-1,k);

}

==

<<-+--

=nk k

nkkn

kn

kn

or 0 1

0 111

시간 복잡도 분석

간단하다 . 그러나 비효율적이다 . 왜 ?

를 구하기 위해 , 계산하는 항의 개수 :

증명 귀납출발점 : n=1; 귀납 가정 : n < N 일때 성립 귀납 절차 :

계산하는 항의 개수 :

n

k

2 1n

k

2 1 1n

k

1 1

1

n n n

k k k

2 1n

k

1 1: 2 1 2 1 1 2 1

1

n n n n

k k k k

1 1: 1

1

n n n

k k k

알고리즘 : 동적 계획법

1. 재귀 관계식 (recursive property) 정립

2. 상향식으로 해결

==

<<-+--=

i or jj

ijjiBjiBjiB

0 1

0 ],,1[]1,1[],[

0 1 2 3 4 j k

01234

in

11111

11

1234

136

14 1

B[i-1,j-1] B[i-1,j]

의사 코드

int bin2(int n,k)

{

index i,j;

int B[0..n,0..k];

for (i=0; i≤n; i++)

for (j=0; j ≤ min(i,k); j++)

if (j=0 or j=i) B[i,j]=1;

else B[i,j] = B[i-1,j-1] + B[i-1,j];

return B[n,k];

}

알고리즘 분석

단위 연산 : B[i,j] = B[i-1,j-1] + B[i-1,j]; 입력 크기 : n, k j- 루프의 수행 횟수

총 수행회수

토의

과제 : 개선방법 배열크기 ? 또 다른 특성

n n

k n k

최단 경로 찾기

하기 전에…

그래프 기초

가중치 방향 그래프 정점 (vertex, node) 이음선 (edge, arc) 가중치 (weight) 경로 (path)

단순 경로 (Simple path) 순환 (cycle)

순환 (cyclic) 그래프 비순환 (acyclic) 그래프

길이 (length) 인접 정점 (adjacent vertex)

최단 경로 (Shortest Path)

보기 : 한 도시에서 다른 도시로 직항로가 없는 경우 가장 빨리 갈 수 있는 항로를 찾는 문제

문제 : 가중치 포함 , 방향성 그래프에서 최단경로 찾기

최적화문제 (optimization problem) 주어진 문제에 대하여 하나 이상의 많은 해답이 존재할 때 ,

이 가운데에서 가장 최적인 해답 (optimal solution) 을 찾아야 하는 문제

최단 경로 : 무작정 알고리즘 (brute-force algorithm)

한 정점에서 다른 정점으로의 모든 경로의 길이를 구한 뒤 , 그들 중에서 최소길이를 찾는다 .

분석 그래프가 n개의 정점을 가지고 있고 , 모든 정점들 사이에 이음선이

존재한다고 가정하자 . 그러면 한 정점 i에서 어떤 정점 j로 가는 경로들을 다 모아 보면 ,

그 경로들 중에서 나머지 모든 정점을 한번씩 은 꼭 거쳐서 가는 경로들도 포함되어 있는데 , 그 경로들의 수만 우선 계산해 보자 .

i에서 출발하여 처음에 도착할 수 있는 정점의 가지 수는 n-2 개이고 , 그 중에 하나를 선택하면 , 그 다음에 도착할 수 있는 정점의 가지 수는 n-3 개 이고 , 이렇게 계속하여 계산해 보면 , 총 경로의 개수는 (n-2)(n-3)…1 = (n-2)! 이 된다 .

이 경로의 개수만 보아도 지수보다 훨씬 크므로 , 이 알고리즘은 절대적으로 비효율적이다 !

동적계획식 설계 전략 - 자료구조

그래프의 인접행렬 (adjacent matrix) 식 표현 : W

최단 경로 길이 표현( )

1 2[ ][ ] { , ,..., } kk iD i j v v v v v j의정점들 만을 통해서 에서 로 가는 최단 경로의길이

(0) ( ), nD W D D

(0) ( ) ?nD D

동적 계획식 설계절차

1.

2.

( 1) ( ) k kD D 로 부터 를 계산할 수 있도록 재귀관계식 설립

(0) ( ) nD D상향식 방법으로 로 부터 까지차례로 구함

Floyd 알고리즘

모든 경우를 고려한 분석 단위연산 ? 입력크기 ?

void floyd(int n, const number W[][], number D[][]) { int i, j, k;

D = W; for(k=1; k <= n; k++) for(i=1; i <= n; i++)

for(j=1; j <= n; j++) D[i][j] = min(D[i][j], D[i][k]+D[k][j]);

}

Floyd 의 알고리즘

void floyd2(int n, const number W[][],number D[][], index P[][]) {

index i, j, k; for(i=1; i <= n; i++) for(j=1; j <= n; j++) P[i][j] = 0; D = W; for(k=1; k<= n; k++) for(i=1; i <= n; i++) for(j=1; j<=n; j++) if (D[i][k] + D[k][j] < D[i][j]) { P[i][j] = k; D[i][j] = D[i][k] + D[k][j]; }}

최단 경로의 출력

Path(5,3)

void path(index q,r) { if (P[q][r] != 0) { path(q,P[q][r]); cout << “ v” << P[q][r]; path(P[q][r],r); }}

동적계획법에 의한 설계 절차

1. 문제의 입력에 대해서 최적 (optimal) 의 해답을 주는 재귀 관계식 (recursive property) 설정

2. 상향적으로 최적의 해답 계산

3. 상향적으로 최적의 해답 구축

최적의 원칙

어떤 문제의 입력에 대한 최적 해가 그 입력을 나누어 쪼갠 여러 부분에 대한 최적 해를 항상 포함하고 있으면 , 그 문제는 최적의 원칙 (the principle of optimality) 이 적용된다 라고 한다 .

보기 ) 최단경로 문제

최적의 원칙이 적용되지 않는 예

최장경로 (Longest Path) 문제

연쇄 행렬 곱셈 (Matrix-chain Multiplication)

(ixj) 행렬 x (jxk) 행렬 : 몇 번 곱셈이 있을까 ? ixjxk

29=1x7+2x2+3x6 이런 계산을 ixk 번 수행

연쇄행렬곱셈 : 무작정 알고리즘

알고리즘 : 가능한 모든 순서를 구한 다음에 그 중에 가장 최적인 순서를 선택한다 .

시간복잡도 : 지수시간 왜 ?

tn: n 개의 행렬 (A1, A2, …, An) 을 곱할 수 있는 가능한 모든 순서의 수

tn 의 부분집합으로서 A1 을 맨 마지막으로 곱하는 경우 : tn-1

tn 의 부분집합으로서 An 을 맨 마지막으로 곱하는 경우 : tn-1

연쇄행렬곱셈 : 동적계획식 전략

최적의 원칙 적용 가능 ?

재귀 관계식 구축

연쇄행렬곱셈 : 동적 계획식 전략

최적의 순서

예 )

최적의 순서 구축

P[i][j]

모든 경우 분석

루프 몇 개 ? k- 루프 : (j-1)-i+1=i+diagonal-1-i+1=diagonal i- 루프 : n-diagonal

최적의 해 순서 출력

P[i][j] 이용void order(index i, index j) { if (i == j) cout << “A” << i; else { k = P[i][j]; cout << “(”; order(i,k); order(k+1,j); cout << “)”; }}

더 나은 방법은 ?

Yao(1982)

Hu and Shing(1982,1984)

2( )n

( lg )n n

트리의 기본

트리 (tree) 루트 (root) 자식 노드 (child node) 루트에서 각 노드까지의 경로가 유일한 구조 재귀 구조 (recursive structure)

이진 트리 (binary tree) 깊이 (depth)= level

트리의 기본

균형 이진 트리 (balanced binary tree) 트리의 모든 노드의 왼쪽 부분트리와 오른쪽 부분트리의

깊이가 최대 하나 차이가 나는 트리

이진 검색 트리 (binary search tree)

순서가 정의되어 있는 항들로 구성된 이진 트리 각 노드에는 키가 있다 . 키값은 왼쪽 부분 트리에 있는 모든 키보다 크고 , 오른쪽

부분 트리에 있는 모든 키보다 작다 . 최적의 이진 검색 트리

키를 찾기 위한 평균 시간 최소화

이진 검색 트리

모든 키를 검색할 확률이 같을 경우 ? 다를 경우 ?

이진 검색 트리

검색 시간 (search time) 키를 찾기 위한 비교 횟수 : depth(key)+1

pi: keyi 를 검색할 확률 ci: 검색시간 평균 검색 시간 ?

1

n

i ii

c p

최적의 이진 검색 트리

최적 이진 트리

무작정 알고리즘의 시간복잡도 ? 동적 계획법 이용 가능 ?

최적의 원칙이 적용될까 ? 부분으로 나누어 보자 . keyi 에서 keyj 로 구성된 트리에서 최적값

[ ][ ]j

m mm i

A i j c p

[ ][ ] ?A i i

부분해답이다 !

동적 계획법 : 최적 이진 검색 트리

keyk 가 루트에 있을 때 , 평균 검색 시간

동적 계획법 : 최적 이진 검색 트리

예 ) 최적 이진 검색 트리

의사 코드

모든 경우 분석

k- 루프 : min 계산 j-1+1=i+diagonal-i+1=diagonal+1

i- 루프 : n-diagonal

외판원 문제 (Traveling Salesperson Problem)

오일러 순환 (Euler cycle): 정점을 한번씩 방문 해밀턴 순환 (Hamiltonian cycle): 정점을 한번씩 방문하고

돌아옴 외판원 문제

가장 짧은 해밀턴 순환을 찾음 ( 최적 일주 경로 ; optimal tour)

Length[1,2,3,4,1]=22

Length[1,3,2,4,1]=26

Length[1,3,4,2,1]=21

외판원 문제

무작정 알고리즘 (n-1)!

최적의 원칙 적용 가능 ? 동적 계획법으로 풀어보자 .

W[i,j]: 인접행렬 V: 모든 정점의 집합 A: A V⊆ D[vi,A]: A 에 속한 정점을 한

번씩만 거쳐서 vi 에서 v1 로 가는 최단 경로의 길이 vi v1

외판원 문제

A={v3} D[v2,A] = length[v2,v3,v1] = ∞

A={v3,v4} D[v2,A] = min(length[2,3,4,1],length[2,4,3,1])

= min(20,∞) = 20

Length of an optimal tour = min(W[1,j] + D[vj,V-{v1,vj}])

2≤j≤n

D[vi,A] = min(W[i,j] + D[vj,A-{vj}]) if A ≠

vj A∈

D[vi,] = W[i,1]

의사코드

void travel(int n, const number W[], number& minlength){

index i,j,k; number D[1..n, subset of V-{v1}]; for i=2 to n D[i,0] = W[i,1]; for k=1 to n-2

for all subsets A ⊆ V-{vi} s.t. |A|=k

for i s.t. i≠1 & vi A { D[i,A] = min(W[i,j] + D[j,A-{vj}]);}

j:vj A∈

D[1,V-{v1}] = min(W[1,j] + D[j,V-{v1,vj}]); 2≤j≤n

minlength = D[1,V-{v1}];}

복잡도 분석

시간 복잡도

공간 복잡도

별로 안 좋은 것 아닌가 ? 그래도 무작정보다는 좋다 .

n = 20 n ≥ 30

더 빠른 알고리즘 ? NP 문제

2( 2 )nn

( 2 )nn

top related