Introduction To Algorithms.
§15. Dynamic Programming
2010 / 06
What is DP ?
最適化問題に使う
Divide-and-conquer method に似てる
Programming → tabular method
Difference (いめーじ)
Divide and conquer : 分割統治法
トップダウン + 似た小問題
Dynamic Programming : 動的計画法
ボトムアップ + 同じ形の小問題
Step of DP(簡単に)
Characterize
Recursively define
Compute
Construct an optimal solutions
Step of DP(詳しく)
最適解の構造を特徴付ける
再帰的に最適解を定義する
ボトムアップ的に解を計算する
結果から最適解を構築する
とりあえず例題
§15.1 Rod Cutting
長い鋼鉄の棒を切って売る
切るのはタダ
価格表が与えられる
高く売りたい
§15.1 Rod Cutting
価格表の例
長さ n = 4 の場合…
4 , 3-1 , 2-2 , 1-3 , 1-1-2 , 1-2-1 , 2-1-1 , 1-1-1-1
L 1 2 3 4 5 6 7 8 9 10
P 1 5 8 9 10 17 17 20 24 30
パターン。
§15.1 Rod Cutting
4 = 1 + 1 + 2
一般に n = i1 + i2 + … + ik
収入は rn = pi1 + pi2 + … + pik
切り方の表現
R <- Revenue : 収入
§15.1 Example Revenue
最大収入の例
4 = 2 + 2 , 5 = 2 + 3 , 7 = 2 + 2 + 3
8 = 2 + 6 , 9 = 3 + 6
N 1 2 3 4 5 6 7 8 9 10
P 1 5 8 9 10 17 17 20 24 30
R 1 5 8 10 13 17 18 22 25 30
Step of DP
Characterize
Recursively define
Compute
Construct an optimal solutions
how to get the optimal revenue
Rnを求めるために、Rn-1を求めてる
長さnからiだけ切る … n = i + ( n - i )
右の破片からだけ切るようにする
how to get the optimal revenue
R1 = p1
R2 = max( p2 , r1 + r1 ) = max( p2 , 2p1 )
R3 = max( p3 , r1 + r2 , r2 + r1 )
= max( p3 , p1 + max( p2, 2p1 ) )
how to get the optimal revenue
R1 = p1
R2 = max( p1 + r1 , p2 ) = max( 2p1 , p2 )
R3 = max( p1 + r2 , p2 + r1 , p3 )
= max( p1 + max( 2p1 , p2 ) , p1 + p2 , p3 )
= max( p1 + max( 2p1 , p2 ) , p3 )
Step of DP
Characterize
Recursively define
Compute
Construct an optimal solutions
Implement 1.
Features of Implement 1.
小さい問題を
たくさん解いている 4
3 2 1 0
01 0
0
012
001
0
Analysis 1.
CutRodの実行時間 T(n) の再帰方程式
計算する
Improvement.
Memoize : メモ化
過去に解いた小問題を記録しておく
Bottom-up approach
小さいのから上へ積み上げる
Dynamic Programmingの特徴
Bottom-up
Analysis 2.
ButtomUpCutRod
O( n^2 ) : for for
MemoizedCutRod
O( n^2 ) らしい。
※Subproblem Graph.
小問題同士の関係をグラフ化
XからYに矢印がある : Xを解くのにYを使う
4 3 2 1 0
Step of DP
Characterize
Recursively define
Compute
Construct an optimal solutions
Construct an optimal solution
例えばBottom-upを拡張する。
どの長さを選択するのか、記録する
一番最初の切断長だけ記録
7=2+2+3 -> 2を記録
7=2+5 と 5の解を利用すればいい
Extended Buttom-up Cut Rod
Output
出力例
N 1 2 3 4 5 6 7 8 9 10
P 1 5 8 9 10 17 17 20 24 30
R 1 5 8 10 13 17 18 22 25 30
S 1 2 3 2 2 6 1 2 3 10
7 = 1 + 6 = 2 + 2 + 3
最初の切断点が小さい方が優先
Caution
一般的に・・・
Speed – memory , trade off
Memoizeすれば確かに高速だけど・・・
§15.2 Matrix-chain multiplication
行列の列
例 < A1 , A2 , A3 , A4 >
A1 A2 A3 A4 を求める
求め方
例 ( A1 ( A2 ( A3 A4 ) ) )
Matrix Multiply (A, B) #01
A of (n,m) * B of (m, s) = AB of (n, s)
for I = 1 to n
for J = 1 to s
for K = 1 to m
c[I,J] += a[I,K] * b[K,J]
Matrix Multiply (A, B) #02
1ブロック:乗算2+加算2
ブロック数:2 * 3 = 6
Matrix Multiply (A, B) #03
A : ( P , Q ) , B : ( Q , R ) , AB : ( P , R )
ブロック数 : PR
乗算の数: Q , 全体で PQR
加算の数: Q : とりあえず無視
Matrix Multiply (A, B) #04
A1 : ( 10 , 100 ) , A2 : ( 100 , 5 ) , A3 : (5 , 50 )
A1 A2 A3 : ( 10 , 50 )
A1 A2 : 5000回の乗算 -> * A3 : 2500回の乗算
A2 A3 : 25000回の乗算 -> A1 * : 50000回の乗算
(A1 A2) A3 : 7500 << A1 (A2 A3) : 75000
Matrix-Chain Multiplication Problem
Matrices ( A1 A2 … An ) が与えられる
行列 Ai : ( pi-1, pi ) 型の行列
乗算回数を最も少なくするようにしたい
Number of Parenthesize
Parenthesize : 括弧をつける
括弧の付け方 ≒ 乗算のやり方
括弧の付け方の数:カタラン数
2nk)P(nP(k)P(n)
1P(1)
1n
1k
Number of Parenthesize
N=1 : ()
N=2 : (()) , ()()
N=3 : ((())) , (()()) , (())() , ()(()) , ()()()
Step of DP
Characterize
Recursively define
Compute
Construct an optimal solutions
Split Product #01
I < K < J のとき
Ai Ai+1 … Aj = ( Ai … Ak ) ( Ak+1 … Aj)
このときの乗算回数は?
例題を思い出せば部分積での回数の和
Split Product #02
最適解を二つに分けても最適解?
最適解
もし部分和でより最適な部分解があれば
そもそも元の最適解が最適じゃない
構造がわかった
Step of DP
Characterize
Recursively define
Compute
Construct an optimal solutions
Recursive Solution #01
積 Ai … Aj ( 1 <= I <= j <= n )
M[i][j] : 最小な積の回数
全体の問題の解 : M[1][n]
Recursive Solution #02
M[i][j]をどう定義するか (Rod Cutのように)
M[i][i] = 0
Ai … Aj = ( Ai … Ak ) ( Ak+1 … Aj)
M[i][j] = M[i][k] + M[k+1][j] + Pi-1 Pk Pj
Recursive Solution #03
分割位置 k は任意 ( I <= k <= J)
実際はMが最小になるような k が必要
}PPP1][j]M[k{M[i][k]M[i][j]
0M[i][i]
jk1ijki
min
Recursive Solution #04
本当に必要な情報はMではない
切断位置 k の情報が必要
S[i][j]にでも格納しておけばいい
Step of DP
Characterize
Recursively define
Compute
Construct an optimal solutions
Computing #01
式を普通に計算する?
指数関数時間・・・
Keyword: Tabular and Bottom-up
Computing #02 – Imprement
実装はP375.
式より → M[i][i] = 0
For for で計算
S[i][j]に括弧の位置も記憶する
Step of DP
Characterize
Recursively define
Compute
Construct an optimal solutions
Constructing
分離箇所の情報 S を使う
詳しくはP376,377
例題終わり
一般的なこと
§15.3 Elements of DP
DPをどういうときに使うか
2つの要素( ingredients )
1. Optimal Substructure
2. Overlapping Subproblem
Optimal Substructure
Step1で最適化問題をCharacterizeしている
最適解の中に小問題の最適解を含んでいた
Optimal Substructure と呼ぶ
これを見つけることがStep1の仕事
How to discover
見つけるときにどんなことをしている?
小問題に分けるための選択・切り分け
部分空間に分けている
Cut-and-paste
Cut-and-paste
Cut-out と Paste-in という技法
最適でない部分を取り除く
最適な解を取り入れる
全体として better な解になる
Space of Subproblems
出来るだけシンプルに保つ
Rod-cutting (Length n)
-> Rod-cutting (Length i)
Matrices (A1 … Aj)
-> (A1 … Ak) , (Ak+1 … Aj)
Optimal Substructure
全体の最適解のために、いくつの部分解を使うか
どの小問題を使うかをどれだけ選択するか
RodCut(n) -> 1つの小問題(length n-i) + iの選択(n)
Matrices(I,J) -> 2つの小問題 + 選択(j-i)
Runnnig Time
一般的な要因は2つ
全体での小問題の個数
選択の回数
Subproblem graphで解析できる
Graph -> Running Time
頂点(vertex)の個数 -> 小問題の個数
辺(edge)の個数 -> 選択の回数
4 3 2 1 0
N vertices, N edges / vertex. -> O(n^2)
Cost
ボトムアップ
小問題のコスト+それ自身を選ぶコスト
Rod-cuttingの例
小問題 n 個(Length 0,1,….,n-1)
Nのどこで切るかを選択 ( nパターン )
切断しない、というコスト (pn)
Without optimal substructure
最適解を分割して求められない
部分最適解の和が全体の最適解にならない
例はグラフのLongest Simple Path (P381)
Independentかどうかが大切(P383)
資源とか情報を使うかどうか・・・
Overlapping Subproblem
小問題は元の問題より小さくなる
同じ問題が何度も出てくる
Overlapping Subproblem
Divide-and-conqureとの違い
Divide-and-conquer
分割の時に似た問題を作る
同じ問題は出てこないかも( quick sort )
Tabularが使えない
DPでは表に結果を蓄積して高速化
※ Memoize
トップダウン用の技術
過去の計算情報を保存
上手く使えば効率的
詳しくは第三版P387-389
例題ラッシュ
§15.4 LCS
Longest Common Subsequence
例えばDNA配列のLCSを求める
Sequence X := < x1 , x2 , … , xm >
Subsequence Z of X := < z1 , z2 , … , zk >
Increasingly <i1 , i2 , … ik >が存在すること
Example
X = < A , B , C , B , D , A , B >
Z = < B , C , A >
Z は X の Subsequence ( I = < 2 , 3 , 6 >)
Common and Longest
Common Sequence Z of X and Y
Z は X と Y の両方のSubsequence
Longest Common Subsequence Z of X and Y
CS の中でもっとも長いもの
Step of DP
Characterize
Recursively define
Compute
Construct an optimal solutions
Characterize LCS #01
X ( Length m ) -> 2^m パターン
X = < x1 , x2 , … , xm > とするとき
Xi = < x1 , x2 , … , xi > とする ( I <= m)
Characterize LCS #02
Theorem 15.1 ( P392 ) LCS’s optimal substructure
X = < x1 , … , xm > , Y = < y1 , … , yn >
Z を X と Y のLCSとする。 Z = < z1 , … , zk >
Theorem 15.1
xm=yn -> zk=xm=yn で Zk-1 が Xm-1 と Yn-1 の LCS
xm != yn
zk != xm -> Z は Xm-1 と Y の LCS
zk != yn -> Z は X と Yn-1 の LCS
証明はP392
Step of DP
Characterize
Recursively define
Compute
Construct an optimal solutions
C[i][j] : LCS の 長さ
再帰的に定義する(式15.9)
C[0][0] = 0
xi = yi -> c[i][j] = c[i-1][j-1] + 1
xi != yi -> c[i][j-1]とc[i-1][j]の大きい方
Step of DP
Characterize
Recursively define
Compute
Construct an optimal solutions
Compute / Imprement
P394
For for で計算
長さの情報C[i][j]と向きの情報B[i][j]を確保
向きの情報はStep4で使う
Step of DP
Characterize
Recursively define
Compute
Construct an optimal solutions
Constructing
図はP395
§15.5 Optimal binary search tree
昇順でK=<k1, k2, … , kn>が与えられる
二分探索木を作りたい
N個の接点とN+1個のダミーの値を持つ
接点kiに対する確率piが与えられる
Binary Search Tree
n = 5 の例
k2
k1 k3
k5k4d0 d1
d2 d3 d4 d5
i 0 1 2 3 4 5
pi - 0.15 0.10 0.05 0.10 0.20
qi 0.05 0.10 0.05 0.05 0.05 0.10
ダミー(Kに入ってない)
kiへの探索確率 pi diへの探索確率 qi
Problem
二分探索木の形は一意に決まるわけではない
kiへの探索が成功、diへの探索が失敗
確率が与えられてるから期待値が出せる
n
1i
n
0i
n
1i
n
0i
idepth(di)qidepth(ki)p1
qi1)depth(di)(1)pi(depth(ki)
Problem
期待値が最良になる二分探索木を求める
Step1. ~ Step4. (P399~404)
問題
Problem. of DP. #01
Ex15-1 : Longest simple path in a directed acyclic
graph
Ex15-2 : Longest Palindrome subsequence
Ex15-3 : Bitonic euclidean traveling-salesman
problem
Ex15-4 : Printing neatly
Problem. of DP. #02
Ex15-5 : Edit distance
Ex15-6 : Planning a company party
Ex15-7 : Viterbi algorithm
Ex15-8 : Image Compression by seam carving
Problem. of DP. #03
Ex15-9 :Breaking a string
Ex15-10 : Planning a investment strategy
Ex15-11 : Inventory planning
Ex15-12 : Signing free-agent baseball players
問題ラッシュおしまい
History of DP.
1955. R. Bellman (1920-1984)
動的計画法(最適性の原理)
次元の呪い
Top Related