データ構造とアルゴリズム
第十一回 (2008年12月
12日)
動的計画法
http://www.sw.it.aoyama.ac.jp/2008/DA/lecture11.html
Martin J. Dürst
duerst@it.aoyama.ac.jp
© 2008 Martin
J. Dürst 青山学院大学
目次
- 先回の残り・修正・追加
- 応用例: 行列の連鎖乗算の順番
- 動的計画法の概要
- アルゴリズムの設計方針
- Ruby による動的計画法
- 宿題
Rabin-Karp アルゴリズムの修正と追加
誤: ハッシュ関数は hf (p) =
(p0·bm-1+p1·bm-2+...+pm-2·b1+pm-1·b0)
mod d
(b はアルファベットの基数、d
は適切に選んだ数字)
正: ハッシュ関数は hf (p) =
(p[0]·bm-1+p[1]·bm-2+...
+p[m-2]·b1+p[m-1]·b0)
mod d
(b はアルファベットの基数、d
は適切に選んだ数字)
追加: Excell による Rabin-Karp のアルゴリズムの例: ARabinKarp.xls
行列の乗算
- r0 × r1 の行列
M1 と
- r1 × r2 の行列
M2 の乗算の結果は
- r0 × r2 の行列
- 乗算の計算量は
r0r1r2
の掛け算と
それより少し少ない足し算で
O(r0r1r2)
三行列の連鎖乗算
- 三つ (以上) の行列の乗算: M1
M2 M3
- 行列の乗算において結合律が成立
- 順番は複数: (M1 (M2
M3)) 又は ((M1
M2) M3)
- r0=100, r1=2, r2=200,
r3=3 の場合、
それぞれの順番の掛け算の数:
(M1 (M2
M3)):
((M1 M2)
M3):
乗算の順番の数
乗算の数 |
順番の数 |
0 |
1 |
1 |
1 |
2 |
2 |
3 |
5 |
4 |
14 |
5 |
42 |
6 |
132 |
7 |
429 |
8 |
1430 |
9 |
4862 |
- 最初少なく見えるが、爆発
- パスカルの三角形のまん中の数 (1, 2, 6, 20, 70,...)
を整数 (1, 2, 3, 4, 5,...) で割ったもの
- カタラン数 Cn =
(2n)!/(n!(n+1)!) =
Ω(4n/n3/2)
(Catalan number)
- 応用が豊富:
- 括弧対の組み合わせの数
- 二分木の数
- (凸) 多角形の三角分割
乗算の最適な順番
- 総当たりで決めるのが無理
- 最低の計算量 (スケーラ乗算の数):
- mincost(a,c) = 0 if a+1 =
c,
- mincost(a,c) = minb
(cost(a,b,c)) if a+1 <
c
(ただし、a<b<c)
- cost(a,b,c) =
mincost(a,b) +
mincost(b,c) +
rarbrc
- mincost(a,c): ra
から rc まで
- cost(a,b,c):
ra から
rc までの乗算を
rb で行うときの計算量
最適化の順番と途中結果の記憶
- mincost(0, n) から再帰的に計算が可能
(下向き、top-down)
- 同じ mincost(x,y)
が何回も計算される
- 下から計算 (上向き、ボトムアップ、bottom-up):
- 長さ k (k が順番に 2,...,n)
の連鎖乗算の最低コストを計算
- 計算結果を記憶、再利用
計算の実例
n=5, r0=2, r1=3,
r2=4, r3=2,
r4=4, r5=5
mincost |
0 |
1 |
2 |
3 |
4 |
5 |
b (分岐点) |
0 |
(r0=2) |
0 |
24 |
|
|
|
|
|
|
|
|
1 |
|
(r1=3) |
0 |
24 |
|
|
|
|
|
|
2 |
|
|
(r2=4) |
0 |
32 |
|
|
|
|
3 |
|
|
|
(r3=2) |
0 |
40 |
|
|
4 |
|
|
|
|
(r4=4) |
0 |
|
5 |
|
|
|
|
|
(r5=5) |
連鎖乗算の最適化の計算量
- 一つの mincost の値の計算は O(n)
- 合計で O(n2) の mincost
の計算が必要
- 合計の計算量は O(n3)
動的計画法では問題によって
O(n2),
O(nm)
等さまざまな計算量がある
動的計画法の概要
(dynamic programming)
- 最適解の構造を調査、明記
- 最適解の値を再帰的に定義
- ボトムアップで最適解の値を算出
- 計算した情報から最適解を構築
動的計画法の基本要素
- 部分構造の最適性 (optimal substructure)
全体の最適解が部分問題の最適解から構築可能
- 部分問題の重複性 (overlapping subproblems)
- 履歴管理 (memoization)
動的計画法の応用
- 探索木の最適化
- (欧文の) 組版で段略を行に分割 (TEX)
- Knappsack 問題
- ...
Ruby による履歴管理
- 関数の変更:
- 引数をキーに結果をハッシュ等に記録
- 実際の計算の前に記録を確認、使用
- この技法は memoize と言う
- Ruby ではメタプログラミングによって実装可能
アルゴリズムの設計方針
- 総当たり方 (腕力方、虱潰し、brute force)
- 貪欲アルゴリズム (greedy algorithm)
部分的な選択で最適な解を得る
- 分割統治法 (divide and conquer)
重複しない部分問題に分割
- 動的計画法
- ネットワークフロー (network flow)
コストをグラフ上に移動しながら最適化
宿題 (レポート)
提出: 12月26日 (金) 19:00、O棟 529号室の前の箱;
3ページ程度; A4 両面左上ホチキス止め;
名前と学籍番号は一ページ目上部に記載 (表紙無し)
動的計画法
(貪欲アルゴリズムやネットワークフローでも可)
のアルゴリズムで解決できる問題を調べて、一つ選んで、その問題と一般の方法を詳しく説明しなさい。
注意点:
- 授業で習ったこと
(アルゴリズムの記述方法、計算量など) を使用
- 調査に使った文献等を必ず明記