mming II
Michael Tsai
2013/10/10
連串矩陣相乘問題
Matrix multiplication is associative.
以上算出來答案都一樣
�
1�
2�
3�
4 ……�
�題目 : 求矩陣相乘之解 .
.cols=.rows
and are compatible.
連串矩陣相乘問題
Matrix-Multiply(A,B) if A.columns != B.rows
error “incompatible dimensions”
else let C be a new A.rows x B.cols matrix for i=1 to A.rows
for j=1 to B.cols
=0
for k=1 to A.cols return C
主要花費時間在這邊 !
�
�
p
q
q
r
共花費 pqr 次乘法的時間 p
r
q
看一個例子
花費之乘法數目 =
花費之乘法數目 =
差十倍 !!
10
100 100 5
5
50
連串矩陣相乘問題 - 正式版
給一連串的矩陣 , 其中矩陣的大小為 (, 找 出一種乘法可以使計算時的乘法數目最少
沒有真的要算結果 , 而只是找出能最快算出結 果的方法 .
因為算”怎麼算比較快”多花的時間 , 比”用 爛方法直接算”多花的時間少很多
�
1�
2�
3�
4 ……�
��
0�
1�
2�
1�
2�
3�
3�
4�
�−1�
�暴力法有多暴力
全部到底有幾種算法呢 ?
P(n): 代表 n 個矩陣相乘共有幾種算法
用遞迴定義 :
P(n) 之解為 Catalan numbers, , or is also
� (� )=
{
� =1� − 1∑ � (�) � (� −�) 1
if
if .
假設先這樣分 :
所以不耍暴力了 .
使用 dynamic programming
正規步驟 :1.
找出最佳解的”結構”2.
使用遞迴來定義最佳解的花費3.
計算最佳解的花費4.
使用已經計算的資訊來構築最佳解找出最佳解的”結構”
總花費 = 的花費 + 的花費 + 把和乘起來的花費
最佳解的結構 : 假設有的最佳解 , 此一方法為在 k 切一刀 . 則在此最佳解中 , 的相乘方法一定是的最佳相乘方法
假設不是最佳解 , 則我們可以在中把換成更好的方法 , 則 可以找到一個更好的的相乘方法矛盾 .
子問題的最佳解可以導出大問題的最佳解 !
最後結論 : 分成兩個子問題 , 並嘗試所有可以切分的地方 (k 值 )
�
��
� +1… �
�
�
�+1�
� +2… �
��≤ �
�≤ �< �
在 k 切一刀
使用遞迴來定義最佳解的花費
遞迴定義 : 使用子問題最佳解的 cost 來定義大 問題最佳解的 cost
定義 : 為所需花的最少乘法數
所花乘法數 =
�
�..��
�+1.. �.rows=
.cols=
.rows=
.cols=
使用遞迴來定義最佳解的花費
但是我們不知道最佳解中的 k 的值
因此我們必須找所有
最後版本 :
� [ � , � ] =
{
� ≤ �< �min {� [ � , � ] + � [ �+1, � 0 ] + �
� −1�
��
�}
if
if .
計算最佳解的花費
純 recursive 解法 : exponential time
使用前面教的 Bottom-up 填表方法 : 每個不同 的 subprogram 僅需解 1 次
有幾個不同的問題 ?
, 幾個 i 和 j 的組合 ?
答案 :
�≠ �
�= �
計算最佳解的花費
如何決定填表的順序呢 ? ( 這次有 i,j 兩個變 數 )�
[
� , �]
={
� ≤ �< �min {�[
� , �]
+�[
� +1, �0]
+�� −1��� �}if
if .
個矩陣相乘
個矩陣相乘
都小於個
我們可以把 j-i+1( 也就是要相乘的 matrix 個數 ) 當作 problem size 的定義
計算最佳解的花費
n=p.length-1
let m[1..n,1..n] and s[1..n-1,2..n] be new tables for i=1 to n
m[i,i]=0
for l=2 to n
for i=1 to n-l+1 j=i+l-1
m[i,j]=
for k=i to j-1
q=m[i,k]+m[k+1,j]+
if q<m[i,j]
m[i,j]=q s[i,j]=k
return m and s
大 problem 的解只會用到小 problem 的解 . 因此慢慢往上長 . 邊界條件先設好 .
把同樣 problem size 的所有 i,j 組合都依 序做過
使用遞迴式找出最佳切點 k
Θ(�
3)
計算最佳解的花費
用一個例子來 trace code 比較快Matrix
Dimension 30 x
35 35 x 15 15 x 5 5 x 10 10 x 20 20 x 25
使用已經計算的資訊來構築最 佳解
前面只印出了花費 , 不是真正的解
怎麼乘才是最後的解
使用 s 陣列的資訊使用已經計算的資訊來構築最佳解
Print-Optimal-Parens(s,i,j) if i==j
print else
print “(“
Print-Optimal-Parens(s,i,s[i,j]) Print-Optimal-Parens(s,s[i,j]+1,j) print “)”
使用已經計算的資訊來構築最佳解
所以該怎麼括 ?看了兩個例子以後…
問 : 一個問題要有什麼要件才能使用 dynamic programming?
答 :1.
Optimal substructure2.
Overlapping Subproblems什麼是 Optimal substructure?
Definition: A problem exhibi ts optimal substructure if a n optimal solution to the pr oblem contains within it opt imal solutions to subproblem s.
怎麼尋找 optimal substructur e 呢 ?怎麼尋找 optimal substructure 呢 ?
1. 要得到問題的解答有許多選擇 ( 砍在哪邊 , 切在 哪邊 ), 而做這個選擇之後 , 我們有一些 subpro blem 要解決 .
2. 我們假設對於一個問題 , 我們可以找到那個選擇
3. 知道這個選擇以後 , 我們找出哪個 subproblem 可 以被拿來應用 , 及剩下的問題 ( 沒有對應到 subp roblem 的 ) 怎麼解決
4. 證明大問題的最佳解中可以直接應用 ( 剪下貼上 ) 子問題的最佳解 .
Optimal substructure 越簡單越好
=?
=?
�
� =?這一段砍下來就不再砍
成更小的了 ( 拿去賣 ) 這一段是 subproblem, 找遞迴朋友去 解
versus
Optimal substructure 越簡單越好
�
1�
�+ 1… �
�
�
�+1�
� +2… �
�1 ≤ �
1 ≤ �< �
在 k 切一刀 假設把問題定義成就好 ( 少一個變數 )
此為一個子問題 此不為一個子問題 !
除非 k 一直都是 j-1, 否則…
Optimal substructure 的變化
1. 原始問題的最佳解用了多少個子問題
2. 大問題有多少選擇 ( 選擇用不同的子問題們來 獲得最佳解 )
大略來說 , 以上兩者決定 dynamic programming a lgorithm 的執行時間 .
( 之前說的 Subproblem graphs 是另外一種算法 )
多少個子問題 有多少選擇 執行時間
鐵條資源回收 n
連串矩陣相乘 n-1
多少個子問題 有多少選擇 執行時間
鐵條資源回收 n
連串矩陣相乘 n-1
複習 : Overlapping Subproblem s
舉個例子 : 連串矩陣問題的遞迴樹1..3
1..1 2..3 1..2 3..3
2..2 3..3 1..1 2..2
橘色的是 overlap 的部分 !
例子 : 有沒有 optimal substructure
給一個 graph . Edge 沒有 weight.
問題 1: 找出沒有 loop 最短路徑 .
問題 2: 找出沒有 loop 最長路徑 .
問題 1 有沒有 optimal substructure?
假設找到的最短路徑 p, 則我們可以將其分解為 ( 可 以是或 ). 則其中一定是的最短路徑 .
不然的話 , 我們可以找到一個比還短路徑 , 那麼和 組合起來就變成一條比 p 更短的路徑 ( 矛盾 )
例子 : 有沒有 optimal substructure
問題 2 有沒有 optimal substructure?
沒有 ! 來舉一個反例 .
的最長路徑 :
但是的最長路徑為
並不是的最長路徑中間的一部分 !
的最長路徑為
也不是的最長路徑中間的一部分 !
q r
s t
例子 : 有沒有 optimal substructure
為什麼問題 1 和問題 2 相差這麼多 ?
問題 2 缺乏”獨立性” (subproblem 的解互相之間不會影 響 )
出現在的 vertex 就不能出現在 ( 否則就會有 loop 了 ) subproblem 的解互相影響 !
問題 1 有”獨立性”
在最短路徑中 , 出現在的 vertex 本來就不可能出現在
假設中除了 w 以外出現了一個一樣的 vertex x. 則可以將 最短路徑拆解成 .
因為 x 和 w 不同 , 所以 . 則變成比原本更短的 u 到 v 的路 徑 ( 矛盾 )
DNA 比對問題
DNA 序列可表示為以 {A,C,G,T} 組合而成的 一字串
比較兩者有多相像 ??
親屬關係 ?
你是我爸 ?!
DNA 比對問題
多相像找出兩者中都出現的最長子序列看最長子序列有 多長 , 越長越相像
子序列 :
順序相同
但不一定要連續 .
簡單的例子 :
X=ABCBDAB, Y=BDCABA
子序列之一 : BCA
最長共同子序列 : BCBA
最長共同子序列 =?
答案在課本 p.391
DNA 比對問題 最長共同子序列
問題 : 給兩字串 , 找出最長共同子序列 .
最長共同子序列 =Longest Common Subsequenc e=LCS
問 : 暴力法有多暴力 ?
暴力法有多暴力 ?
找出所有 X 之子序列 , 與 Y 比較檢驗看看是不 是 Y 的子序列 .
X 有幾個子序列 ?
個
Running time:
Dynamic Programming 出招
先來個小定義 , 對 ,
先證明以下三個小定理 . 給定兩字串 , 及為 X 和 Y 的 LCS( 之一 )1.
If , then and 是及的 LCS 之一2.
If , then 表示是及的 LCS 之一3.
If , then 表示是及的 LCS 之一
1. 找出 Optimal Substructure
1.
If , then (1) and (2) 是及的 LCS 之一(1) Z 最後一個字元一定是 , 否則可以把加到 Z 的最後面成為比 LCS 更長的 CS ( 矛盾 )
(2) 一定是和的 LCS. 假設不是 , 則可以找到一 個長度 >k-1 的 LCS, 但是加上這一個字元 , 表示可 以找到一個和的 LCS 長度 >k ( 矛盾 )
�
� − 1
�
� − 1
�
��
��
� − 1
�
�2.
If , then 表示是及的 LCS 之一假設 Z 不是和的 LCS, 則有 W 為和的 LCS, 長度 >
k, 則 W 亦為和的 LCS, 長度 >k ( 矛盾 )
3.
If , then 表示是及的 LCS 之一 證明類似上面 2. 的證明 .
�
� − 1
�
�
�
��
� − 1
�
�Optimal Substructure
給定兩字串 , 及為 X 和 Y 的 LCS( 之一 )1.
If , then and 是及的 LCS 之一2.
If , then 表示是及的 LCS 之一3.
If , then 表示是及的 LCS 之一
大問題的解裡面有小問題的解 !
Overlapping subproblem
給定兩字串 , 及為 X 和 Y 的 LCS( 之一 )1.
If , then and 是及的 LCS 之一2.
If , then 表示是及的 LCS 之一3.
If , then 表示是及的 LCS 之一
�
�和��的 ����
�−1和��的 ����
�和�� −1的 ����
�−1和��−1的 ���不同問題需要同樣子問題的解 !
Dynamic Programming 出招
2. 列出遞迴式子 ( 表示花費 )
if i=0 or j=0 if and
if and
兩種選擇
條件不同 , 使用的 subproblem 不同
Dynamic Programming 出招
使用 dynamic programming 填表
共有多少個 entry?
3. 計算花費
0 1 2 3
0 1 2 3 i j
每一格只用到左、
左上、上三格的資訊
使用 bottom-up 方法 兩層迴圈依序填入即可
0 1 2 3 4 5 6
0
0 0 0 0 0 0 01
0 0 0 0 1 1 12
0 1 1 1 1 2 23
0 1 1 2 2 2 24
0 1 1 2 2 3 35
0 1 2 2 2 3 36
0 1 2 2 3 3 47
0 1 2 2 3 4 4例題
0 1 2 3 4 5 6
0 1 2 3 4 5 6 7
B D C A B A
A B C B D A B
LCS_Length(X,Y) m=X.length
n=Y.length
let b[1..m,1..n] and c[0..m,0..n] be new tables for i=1 to m
c[i,0]=0
for j=0 to n c[0,j]=0
for i=1 to m for j=1 to n if
c[i,j]=c[i-1,j-1]+1 b[i,j]= 左上
elseif c[i-1,j]c[i,j-1]
c[i,j]=c[i-1,j]
b[i,j]= 上 else
c[i,j]=c[i,j-1]
b[i,j]= 左
return c and b
邊界起始值
填表 : 兩層迴 圈
c 紀錄 LCS 長度 , b 紀錄選擇 結果
Θ(��)
Dynamic Programming 出招
Print_LCS(b,X,i,j) if i==0 or j==0 return
if b[i,j]== 左上
Print_LCS(b,X,i-1,j-1) print
elseif b[i,j]== 上 Print_LCS(b,X,i-1,j) else
Print_LCS(b,X,i,j-1)
4. 印出 LCS 結果