• 沒有找到結果。

Programming II Dynamic

N/A
N/A
Protected

Academic year: 2022

Share "Programming II Dynamic"

Copied!
41
0
0

加載中.... (立即查看全文)

全文

(1)

Programming II

Michael Tsai 2013/10/10

(2)

連串矩陣相乘問題

Matrix multiplication is associative.

(( A1𝐴2 𝐴3)𝐴4)

( A1 𝐴2𝐴3 )𝐴4

A1𝐴2 𝐴3𝐴4

𝐴1( 𝐴2𝐴3 𝐴4)

𝐴1 𝐴2 𝐴3𝐴4

以上算出來答案都一樣

𝐴1 𝐴2 𝐴3 𝐴4 …… 𝐴𝑛

題目: 求𝐴1𝐴2 … 𝐴𝑛矩陣相乘之解.

𝐴1.cols=𝐴2.rows

𝐴1and 𝐴2are compatible.

(3)

連串矩陣相乘問題

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

(4)

看一個例子

𝐴1𝐴2 𝐴3 花費之乘法數目=10 × 100 × 5 + 10 × 5 × 50 = 7500

𝐴1 𝐴2𝐴3 花費之乘法數目=100 × 5 × 50 + 10 × 100 × 50 = 75000

差十倍!!

10

100 100 5

5

50

(5)

連串矩陣相乘問題-正式版

給一連串的矩陣 𝐴1, 𝐴2, … , 𝐴𝑛 , 其中矩陣𝐴𝑖的大 小為𝑝𝑖−1 × 𝑝𝑖 (𝑖 = 1, 2, … , 𝑛), 找出一種乘法可 以使計算時的乘法數目最少

沒有真的要算結果, 而只是找出能最快算出結果 的方法.

因為算”怎麼算比較快”多花的時間, 比”用爛方 法直接算”多花的時間少很多

𝐴1 𝐴2 𝐴3 𝐴4 …… 𝐴𝑛

𝑝0

𝑝1

𝑝2

𝑝1 𝑝2

𝑝3

𝑝3

𝑝4

𝑝𝑛−1

𝑝𝑛

(6)

暴力法有多暴力

全部到底有幾種算法呢?

P(n): 代表n個矩陣相乘共有幾種算法

用遞迴定義:

P(n)之解為Catalan numbers, Ω 4𝑛

𝑛

3 2

, or is also Ω 2𝑛

𝑃 𝑛 =

1

𝑘=1 𝑛−1

𝑃 𝑘 𝑃(𝑛 − 𝑘)

if 𝑛 = 1,

if 𝑛 ≥ 2.

假設先這樣分: 𝐴1𝐴2 … 𝐴𝑘 𝐴𝑘+1𝐴𝑘+2 … 𝐴𝑛

(7)

所以不耍暴力了.

使用dynamic programming

正規步驟:

1. 找出最佳解的”結構”

2. 使用遞迴來定義最佳解的花費

3. 計算最佳解的花費

4. 使用已經計算的資訊來構築最佳解

(8)

找出最佳解的”結構”

總花費=𝐴𝑖. . 𝐴𝑘的花費+𝐴𝑘+1. . 𝐴𝑗的花費+把𝐴𝑖. . 𝐴𝑘和𝐴𝑘+1. . 𝐴𝑗 乘起來的花費

最佳解的結構: 假設有𝐴𝑖. . 𝐴𝑗的最佳解, 此一方法為在k切一刀.

則在此𝐴𝑖. . 𝐴𝑗最佳解中, 𝐴𝑖. . 𝐴𝑘的相乘方法一定是𝐴𝑖. . 𝐴𝑘的最 佳相乘方法

假設𝐴𝑖. . 𝐴𝑘不是最佳解, 則我們可以在𝐴𝑖. . 𝐴𝑗中把𝐴𝑖. . 𝐴𝑘換成 更好的方法, 則可以找到一個更好的𝐴𝑖. . 𝐴𝑗的相乘方法矛盾.

子問題的最佳解可以導出大問題的最佳解!

最後結論: 分成兩個子問題, 並嘗試所有可以切分的地方(k值)

𝐴𝑖𝐴𝑖+1… 𝐴𝑘 𝐴𝑘+1𝐴𝑘+2… 𝐴𝑗 𝑖 ≤ 𝑗

𝑖 ≤ 𝑘 < 𝑗 在k切一刀

(9)

使用遞迴來定義最佳解的花費

遞迴定義:使用子問題最佳解的cost來定義大問 題最佳解的cost

定義: 𝑚[𝑖, 𝑗]為𝐴𝑖. . 𝐴𝑗所需花的最少乘法數

𝐴𝑖..𝑘𝐴𝑘+1..𝑗所花乘法數=𝑝𝑖−1𝑝𝑘𝑝𝑗

𝐴𝑖..𝑘 𝐴𝑘+1..𝑗

𝐴𝑖.rows=𝑝𝑖−1

𝐴𝑘.cols=𝑝𝑘

𝐴𝑘+1.rows=𝑝𝑘

𝐴𝑗.cols=𝑝𝑗

(10)

使用遞迴來定義最佳解的花費

𝑚 𝑖, 𝑗 = 𝑚 𝑖, 𝑘 + 𝑚 𝑘 + 1, 𝑗 + 𝑝𝑖−1𝑝𝑘𝑝𝑗

但是我們不知道最佳解中的k的值

因此我們必須找所有𝑘 = 𝑖, 𝑖 + 1, … , 𝑗 − 1

最後版本:

𝑚 𝑖, 𝑗 = 0

𝑖≤𝑘<𝑗min {𝑚 𝑖, 𝑘 + 𝑚 𝑘 + 1, 𝑗 + 𝑝𝑖−1𝑝𝑘𝑝𝑗}

if 𝑖 = 𝑗, if 𝑖 < 𝑗.

(11)

計算最佳解的花費

純recursive解法: exponential time

使用前面教的Bottom-up填表方法: 每個不同的 subprogram僅需解1次

有幾個不同的問題?

1 ≤ 𝑖 ≤ 𝑗 ≤ 𝑛, 幾個i和j的組合?

答案: 𝑛

2 + n = Θ 𝑛2

𝑖 ≠ 𝑗 𝑖 = 𝑗

(12)

計算最佳解的花費

如何決定填表的順序呢? (這次有i,j兩個變數)

𝑚 𝑖, 𝑗 = 0

𝑖≤𝑘<𝑗min{𝑚 𝑖, 𝑘 + 𝑚 𝑘 + 1, 𝑗 + 𝑝𝑖−1𝑝𝑘𝑝𝑗}

if 𝑖 = 𝑗, if 𝑖 < 𝑗.

𝑘 − 𝑖 + 1個矩陣相乘 𝑗 − 𝑘個矩陣相乘

都小於𝑗 − 𝑖 + 1個

我們可以把j-i+1(也就是要相乘的matrix個數) 當作problem size的定義

(13)

計算最佳解的花費

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]+pi−1𝑝𝑘𝑝𝑗 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)

(14)

計算最佳解的花費

用一個例子來trace code比較快

Matrix

Dimension 30 x 35 35 x 15 15 x 5 5 x 10 10 x 20 20 x 25

(15)

使用已經計算的資訊來構築最佳 解

前面只印出了花費, 不是真正的解

怎麼乘才是最後的解

使用s陣列的資訊

(16)

使用已經計算的資訊來構築最佳 解

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 “)”

(17)

使用已經計算的資訊來構築最佳 解

所以該怎麼括?

(18)

看了兩個例子以後…

問: 一個問題要有什麼要件才能使用dynamic programming?

答:

1. Optimal substructure

2. Overlapping Subproblems

(19)

什麼是Optimal substructure?

Definition: A problem exhibits optimal substructure if an

optimal solution to the problem contains within it optimal

solutions to subproblems.

怎麼尋找optimal substructure呢?

(20)

怎麼尋找optimal substructure呢?

1. 要得到問題的解答有許多選擇(砍在哪邊, 切在哪 邊), 而做這個選擇之後, 我們有一些subproblem要 解決.

2. 我們假設對於一個問題, 我們可以找到那個選擇

3. 知道這個選擇以後, 我們找出哪個subproblem可以 被拿來應用, 及剩下的問題(沒有對應到subproblem 的)怎麼解決

4. 證明大問題的最佳解中可以直接應用(剪下貼上)子 問題的最佳解.

(21)

Optimal substructure越簡單越好

𝑟𝑖=? 𝑟𝑛−𝑖=?

𝑝𝑖 𝑟𝑖=?

這一段砍下來就不再砍

成更小的了(拿去賣) 這一段是subproblem, 找遞迴朋友去解 versus

(22)

Optimal substructure越簡單越好

𝐴1𝐴𝑖+1… 𝐴𝑘 𝐴𝑘+1𝐴𝑘+2 … 𝐴𝑗 1 ≤ 𝑗

1 ≤ 𝑘 < 𝑗

在k切一刀 假設把問題定義成𝐴1 … 𝐴𝑗就好 (少一個變數)

此為一個子問題 此不為一個子問題!

除非k一直都是j-1, 否則…

(23)

Optimal substructure的變化

1. 原始問題的最佳解用了多少個子問題

2. 大問題有多少選擇(選擇用不同的子問題們來 獲得最佳解)

大略來說, 以上兩者決定dynamic programming algorithm的執行時間.

(之前說的Subproblem graphs是另外一種算法)

多少個子問題 有多少選擇 執行時間

鐵條資源回收 Θ(𝑛) n 𝑂 𝑛2

連串矩陣相乘 Θ(𝑛2) n-1 𝑂 𝑛3

(24)

複習: Overlapping Subproblems

舉個例子: 連串矩陣問題的遞迴樹

1..3

1..1 2..3 1..2 3..3

2..2 3..3 1..1 2..2

橘色的是overlap的部分!

(25)

例子: 有沒有optimal substructure

給一個graph 𝐺 = 𝑉, 𝐸 . 𝑢, 𝑣 ∈ 𝑉. Edge沒有weight.

問題1:找出𝑢 → 𝑣沒有loop最短路徑.

問題2:找出𝑢 → 𝑣沒有loop最長路徑.

問題1有沒有optimal substructure?

假設找到𝑢到𝑣的最短路徑p, 則我們可以將其分解為 𝑢 →𝑝1 𝑤 →𝑝2 𝑣 (𝑤可以是𝑢或𝑣). 則其中𝑝1一定是𝑢到𝑤的最 短路徑.

不然的話, 我們可以找到一個𝑝1′比𝑝1還短的𝑢到𝑤路徑, 那麼𝑝1′和𝑝2組合起來就變成一條比p更短的𝑢到𝑣路徑 (矛盾)

(26)

例子: 有沒有optimal substructure

問題2有沒有optimal substructure?

沒有! 來舉一個反例.

𝑞到𝑡的最長路徑: 𝑞 → 𝑟 → 𝑡

但是𝑞到𝑟的最長路徑為𝑞 → 𝑠 → 𝑡 → 𝑟

並不是𝑞到𝑡的最長路徑中間的一部分!

𝑟到𝑡的最長路徑為𝑟 → 𝑞 → 𝑠 → 𝑡

也不是q到𝑡的最長路徑中間的一部分!

q r

s t

(27)

例子: 有沒有optimal substructure

為什麼問題1和問題2相差這麼多?

問題2缺乏”獨立性”(subproblem的解互相之間不會影響)

𝑢 →𝑝1 𝑤 →𝑝2 𝑣出現在𝑝1的vertex就不能出現在𝑝2 (否則就會有 loop了) subproblem的解互相影響!

問題1有”獨立性”

在最短路徑𝑢 →𝑝1 𝑤 →𝑝2 𝑣中, 出現在𝑝1的vertex本來就不可能出 現在𝑝2

假設𝑝1, 𝑝2中除了w以外出現了一個一樣的vertex x. 則可以將 最短路徑拆解成𝑢 𝑝𝑢𝑥 𝑥 𝑝𝑥𝑤 𝑤 𝑝𝑤𝑥 𝑥 𝑝𝑥𝑣 𝑣.

因為x和w不同, 所以|𝑝𝑥𝑤 ≥ 1, |𝑝𝑤𝑥 ≥ 1. 則𝑝𝑢𝑥和𝑝𝑥𝑣變成比 原本更短的u到v的路徑 (矛盾)

(28)

DNA比對問題

DNA序列可表示為以{A,C,G,T}組合而成的 一字串

𝑆1

= 𝐴𝐶𝐶𝐺𝐺𝑇𝐶𝐺𝐴𝐺𝑇𝐺𝐶𝐺𝐶𝐺𝐺𝐴𝐴𝐺𝐶𝐶𝐺𝐺𝐶𝐶𝐺𝐴𝐴 𝑆2

= 𝐺𝑇𝐶𝐺𝑇𝑇𝐶𝐺𝐺𝐴𝐴𝑇𝐺𝐶𝐶𝐺𝑇𝑇𝐺𝐶𝑇𝐶𝑇𝐺𝑇𝐴𝐴𝐴

比較兩者有多相像??

親屬關係?

你是我爸?!

(29)

DNA比對問題

多相像找出兩者中都出現的最長子序列看最長子序 列有多長, 越長越相像

子序列:

順序相同

但不一定要連續.

簡單的例子:

X=ABCBDAB, Y=BDCABA

子序列之一: BCA

最長共同子序列: BCBA

𝑆1 = 𝐴𝐶𝐶𝐺𝐺𝑇𝐶𝐺𝐴𝐺𝑇𝐺𝐶𝐺𝐶𝐺𝐺𝐴𝐴𝐺𝐶𝐶𝐺𝐺𝐶𝐶𝐺𝐴𝐴

𝑆2 = 𝐺𝑇𝐶𝐺𝑇𝑇𝐶𝐺𝐺𝐴𝐴𝑇𝐺𝐶𝐶𝐺𝑇𝑇𝐺𝐶𝑇𝐶𝑇𝐺𝑇𝐴𝐴𝐴

最長共同子序列=? 答案在課本p.391

(30)

DNA比對問題最長共同子序列

問題: 給兩字串𝑋 = 𝑥1, 𝑥2, … , 𝑥𝑚 , 𝑌 = 𝑦1, 𝑦2, … , 𝑦𝑛 , 找出最長共同子序列.

最長共同子序列=Longest Common Subsequence=LCS

問: 暴力法有多暴力?

(31)

暴力法有多暴力?

找出所有X之子序列, 與Y比較檢驗看看是不是Y 的子序列.

X有幾個子序列?

2𝑚

Running time: Ω(2𝑚)

(32)

Dynamic Programming出招

先來個小定義, 對𝑋 = 𝑥1, 𝑥2, … , 𝑥𝑚 , 𝑋𝑖 = 𝑥1, 𝑥2, … , 𝑥𝑖 , 0 ≤ 𝑖 ≤ 𝑚

先證明以下三個小定理. 給定兩字串𝑋 =

𝑥1, 𝑥2, … , 𝑥𝑚 , 𝑌 = 𝑦1, 𝑦2, … , 𝑦𝑛 , 及𝑍 = 𝑧1, 𝑧2, … , 𝑧𝑘 為X 和Y的LCS(之一)

1. If 𝑥𝑚 = 𝑦𝑚, then 𝑧𝑘 = 𝑥𝑚 = 𝑦𝑛 and 𝑍𝑘−1 是𝑋𝑚−1及𝑌𝑛−1 的LCS之一

2. If 𝑥𝑚 ≠ 𝑦𝑛, then 𝑧𝑘 ≠ 𝑥𝑚表示𝑍是𝑋𝑚−1及𝑌𝑛的LCS之一

3. If 𝑥𝑚 ≠ 𝑦𝑛, then 𝑧𝑘 ≠ 𝑦𝑛表示𝑍是𝑋𝑚及𝑌𝑛−1的LCS之一

1. 找出Optimal Substructure

(33)

1. If 𝑥𝑚 = 𝑦𝑛, then (1) 𝑧𝑘 = 𝑥𝑚 = 𝑦𝑛 and (2) 𝑍𝑘−1 是 𝑋𝑚−1及𝑌𝑛−1的LCS之一

(1) Z最後一個字元一定是𝑥𝑚(= 𝑦𝑛), 否則可以把 𝑥𝑚加到Z的最後面成為比LCS更長的CS (矛盾)

(2)𝑍𝑘−1一定是𝑋𝑚−1和𝑌𝑛−1的LCS. 假設不是, 則 可以找到一個長度>k-1的LCS, 但是加上𝑥𝑚 = 𝑦𝑛這一個 字元, 表示可以找到一個𝑋𝑚和𝑌𝑛的LCS長度>k (矛盾)

𝑋𝑚−1 𝑌𝑛−1

𝑥𝑚

𝑦𝑛

𝑍𝑘−1 𝑍𝑘

(34)

2. If 𝑥𝑚 ≠ 𝑦𝑛, then 𝑧𝑘 ≠ 𝑥𝑚表示𝑍是𝑋𝑚−1及𝑌𝑛的LCS之 一

假設Z不是𝑋𝑚−1和𝑌𝑛的LCS, 則有W為𝑋𝑚−1和𝑌𝑛 的LCS, 長度>k, 則W亦為𝑋𝑚和𝑌𝑛的LCS, 長度>k (矛盾)

3. If 𝑥𝑚 ≠ 𝑦𝑛, then 𝑧𝑘 ≠ 𝑦𝑛表示𝑍是𝑋𝑚及𝑌𝑛−1的LCS之 一

證明類似上面2.的證明.

𝑋𝑚−1 𝑌𝑛

𝑥𝑚

𝑍𝑘−1 𝑍𝑘

(35)

Optimal Substructure

給定兩字串𝑋 = 𝑥1, 𝑥2, … , 𝑥𝑚 , 𝑌 = 𝑦1, 𝑦2, … , 𝑦𝑛 , 及𝑍 = 𝑧1, 𝑧2, … , 𝑧𝑚 為X和Y的LCS(之一)

1. If 𝑥𝑚 = 𝑦𝑚, then 𝑧𝑘 = 𝑥𝑚 = 𝑦𝑛 and 𝑍𝑘−1 是𝑋𝑚−1及𝑌𝑛−1的LCS之一

2. If 𝑥𝑚 ≠ 𝑦𝑛, then 𝑧𝑘 ≠ 𝑥𝑚表示𝑍是𝑋𝑚−1及𝑌𝑛的LCS之一

3. If 𝑥𝑚 ≠ 𝑦𝑛, then 𝑧𝑘 ≠ 𝑦𝑛表示𝑍是𝑋𝑚及𝑌𝑛−1的LCS之一

大問題的解裡面有小問題的解!

(36)

Overlapping subproblem

給定兩字串𝑋 = 𝑥1, 𝑥2, … , 𝑥𝑚 , 𝑌 = 𝑦1, 𝑦2, … , 𝑦𝑛 , 及𝑍 = 𝑧1, 𝑧2, … , 𝑧𝑚 為X和Y的LCS(之一)

1. If 𝑥𝑚 = 𝑦𝑛, then 𝑧𝑘 = 𝑥𝑚 = 𝑦𝑛 and 𝑍𝑘−1 是𝑋𝑚−1及𝑌𝑛−1的LCS之一

2. If 𝑥𝑚 ≠ 𝑦𝑛, then 𝑧𝑘 ≠ 𝑥𝑚表示𝑍是𝑋𝑚−1及𝑌𝑛的LCS之一

3. If 𝑥𝑚 ≠ 𝑦𝑛, then 𝑧𝑘 ≠ 𝑦𝑛表示𝑍是𝑋𝑚及𝑌𝑛−1的LCS之一

𝑋𝑚和𝑌𝑛的𝐿𝐶𝑆 𝑋𝑚−1和𝑌𝑛的𝐿𝐶𝑆

𝑋𝑚和𝑌𝑛−1的𝐿𝐶𝑆 𝑋𝑚−1和𝑌𝑛−1的𝐿𝐶𝑆 不同問題需要同樣子問題的解!

(37)

Dynamic Programming出招

𝑐 𝑖, 𝑗 =

0

𝑐 𝑖 − 1, 𝑗 − 1 + 1

max(𝑐 𝑖, 𝑗 − 1 , 𝑐 𝑖 − 1, 𝑗 )

2. 列出遞迴式子 (表示花費)

if i=0 or j=0

if 𝑖, 𝑗 > 0 and 𝑥𝑖 = 𝑦𝑗 if 𝑖, 𝑗 > 0 and 𝑥𝑖 ≠ 𝑦𝑗

𝑋𝑖 and Yj 𝐿𝐶𝑆的長度 兩種選擇

條件不同, 使用的subproblem不同

(38)

Dynamic Programming出招

使用dynamic programming填表

共有多少個entry? Θ(𝑚𝑛)

3. 計算花費

0 1 2 3

0 1 2 3 i j

每一格只用到左、

左上、上三格的資訊

使用bottom-up方法 兩層迴圈依序填入即可

(39)

0 1 2 3 4 5 6

0 0 0 0 0 0 0 0

1 0 0 0 0 1 1 1

2 0 1 1 1 1 2 2

3 0 1 1 2 2 2 2

4 0 1 1 2 2 3 3

5 0 1 2 2 2 3 3

6 0 1 2 2 3 3 4

7 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

(40)

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紀錄選擇結果

Θ(𝑚𝑛)

(41)

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結果

O(𝑚 + 𝑛)

參考文獻

相關文件

debug 題:請問右邊這份 code 錯在哪( 題目在此).. What

• 我們通常用 nD/mD 來表示一個狀態 O(N^n) ,轉移 O(N^m) 的 dp 演算法. • 在做每題

• 也就是 ”我的dp是n^3”這句話本身不夠表示你的dp演算法,必須 要說“我的dp是個狀態n^2,轉移n”才夠精確. •

[r]

[r]

• 有一個可以耐重 W 的背包,及 N 種物品,每種物品有各自的重量 w[i] 和價值 v[i] ,且數量為 k[i] 個,求在不超過重量限制的情 況下往背包塞盡量多的東西,總價值最大為多少?.

依賴背包問題 and

creted by howard41436 edited by