一.矩陣鏈事例
矩陣鏈問題主要涉及的時在多個矩陣相乘,如何通過相乘的順序來減少程式執行。
二.例題分析
這次分析過程按照動態規劃的三個基本條件來逐步解答:
1、尋找最優子結構:假設我們已經找到父矩陣鏈最優解,當我們劃分到最後一步時都是兩個子矩陣鏈(分別被括號包圍)相乘,如(a1a2a3a4)(a5a6a7),此時顯然外括號為父矩陣的最優括號劃分。繼續往下劃分,((a1a2a3)a4)(a5(a6a7)),則兩個子矩陣鏈的劃分括號必須也為他們本身的最優括號劃分。因為如果子矩陣鏈的劃分括號不是他們本身的最優括號劃分時,兩個子矩陣鏈就有另一種最優括號劃分,如(a1(a2a3a4))(a5(a6a7))。那麼就與我們的假設相悖。((a1a2a3)a4)(a5(a6a7))不是我們父矩陣最優解。所以擁有最優劃分的父矩陣的子矩陣鏈顯然也擁有最優劃分。
2、子問題重疊:看到步驟一是不是感覺這個問題可以使用遞迴來解決?顯然可以。演算法導論給出如下遞迴公式:
但是我們發現遞迴公式中會有很多重複計算的子結構。由於k是未知,所以我們需要迴圈來找出最小的,但是,當k=i…..j時k每對應乙個值就得繼續往下遞迴,此時又得迴圈一遍k,在其中就會有許多子問題重複計算了。比如我們有這兩個括號劃分:
(a1(a2a3a4))(a5(a6a7))和(a1(a2a3a4))((a5a6)a7),此時前面子鏈括號劃分是相同的而後面子鏈劃分不同。如果我們使用15.12進行遞迴就會重複計算(a1(a2a3a4))。這正是動態規劃解決的問題。
3、自底向上方法:我們前面使用的迴圈使用的是自上向下的方法。而動態規劃使用的是自底向上的方法。也就是從最初向最後推理。如果我們簡單的一直劃分而不做比較的話,我們會發現劃分的分支越來越多。而動態規劃不同,它是在劃分中把一些明顯代價大的,可以比較的pk掉。從而減少分析次數,而且自底向上還避免了子問題的重複計算。而想要從底部開始就要求我們每次的劃分都是最優劃分,從而被下一次劃分最優劃分包含在所有下一次劃分方法之內,這也是我們為什麼首先要證明步驟一。
三.例題計算過程
有上述矩陣:
第一次:我們從最初開始劃分,也就是劃分兩個子矩陣,首先列出所有情況。
a1a2 30*35*15=15750
a2a3 35*15*5=2625
a3a4 15*5*10=750
a4a5 5*10*20=1000
a5a6 10*20*25=5000
由於我們不知道最優劃分方法使用了那些上述劃分,所以我們不能進行pk
第二次:劃分三個子矩陣
a1a2a3:此時注意a1a2a3有兩種子結構劃分,由於不管使用哪種子結構,劃分後都歸類到a1a2a3,也就是說a1a2a3無論有多少子結構,無論如何劃分,劃分後他都成為(a1a2a3)這乙個整體。因此此時我們可以進行pk。(a1(a2a3))2625+30*35*5=7875或((a1a2)a3)15750+30*15*5=18000,顯然選擇7875
a2a3a4:2625+35*5*10=4375或750+35*15*10=6000,顯然選擇4375
a3a4a5:750+15*10*20=3750或1000+15*5*20=2500,顯然選擇2500
a4a5a6:1000+5*20*25=3500或5000+5*10*25=6250,顯然選擇3500
第三次:劃分四個子矩陣
a1a2a3a4:(a1a2a3)a4:7875+30*5*10=9375或a1(a2a3a4):2500+35*10*30=13000或者(a1a2)(a3a4):15750+750+30*15*10=21000顯然選擇9375
a2a3a4a5:(a2a3a4)a5:4375+35*10*20=11375或者a2(a3a4a5):2500+15*20*35=13000或(a2a3)(a4a5):2625+1000+35*5*20=7125顯然選擇7125
a3a4a5a6:(a3a4a5)a6:2500+15*20*25=10000或者a3(a4a5a6):3500+5*25*15=5375或(a3a4)(a5a6):750+5000+15*10*25=9500顯然選擇5375
第四次:劃分五個子矩陣
同理得a1a2a3a4a5:11875和a2a3a4a5a6:10500
第五次:最後對整個矩陣鏈進行劃分。
a1(a2a3a4a5a6):30*35*25+18500=44750
(a1a2)(a3a4a5a6):157580+5375+30*5*25=32375
(a1a2a3)(a4a5a6):7875+3500+30*5*25=15125
(a1a2a3a4)(a5a6):9375+5000+30*10*25=21875
(a1a2a3a4a5)a6:15375+30*20*25=30375
綜上:最後選擇15125.知道整個矩陣鏈的分配,我們就知道接下來的分配,因為我們使用的子矩陣鏈都是最優子結構,只需要往前找就行。最後分配:(a1(a2a3))((a4a5)a6)。我們觀察第五次分配可以發現:最後一次矩陣相乘增加的代價分別為30*35*25,30*5*25,30*5*25,30*10*25,30*20*25。發現兩邊都是30,25.而中間在變化也就是先前k值得變化,中間值為5時比較小,而且按照子最優解必定屬於父最優解,那麼是不是我們一直按照最小中間值劃分,就能找到最優方法呢?
四.與裝配線排程對比
裝配線問題要比矩陣鏈問題簡單,但是其實我們可以將其對比,發現二者問題是相同的。根據矩陣鏈的遞迴公式我們發現其實n矩陣鏈的問題從上往下劃分時其實其問題出口有n-1個,也就是k=j-i=n-1個。所以我們在《例題計算過程》中在第五次劃分時有5個出口(算了5次),這個和裝配線最終出口只有兩個類似。
裝配線問題簡單在在考慮j裝配站問題時,我們只需要考慮j-1站問題就行了,因為不管怎樣考慮j-1站完成後就必須考慮j站,這是由於底盤加工流程決定的,你必須加工完成j-1後才能加工j。而矩陣鏈不同,矩陣鏈n劃分時我們不僅有可能考慮n-1問題,還有可能包含n-2,n-3的問題。比如對其劃分(a1a2a3a4)(a5a6),此時考慮的就是6-2,6-4兩個子結構,這在裝配線中是不能出現的。
五.**
六.類似問題
原文:動態規劃之矩陣鏈乘法理解 - 心之所向 - csdn部落格
矩陣連乘(動態規劃)
題目描述 給定n個矩陣 a1,a2,an 其中ai與ai 1是可乘的,i 1,2 n 1。如何確定計算矩陣連乘積的計算次序,使得依此次序計算矩陣連乘積需要的數乘次數最少。例如 a1 a2 a3 a4 a5 a6 最後的結果為 a1 a2a3 a4a5 a6 最小的乘次為15125。思路 動態規劃演算...
動態規劃 矩陣連乘
includeusing namespace std 無論括號怎麼分這些連續相乘的矩陣,最後括號都可以歸結到只有兩對括號,把整個連乘的矩陣分成兩部分 0 i j m i j min i 遞迴計算矩陣連乘 int liancheng int i,int j,int p,int s return min...
動態規劃 矩陣連乘
動態規劃常常用來解決,具有最優子結構,重疊子問題的物件。最優子結構 即通過分析問題,將問題分解為多個子問題。然後每個子問題繼續分解為更多子問題。從底往上求出最有值,由最優值確定最優解。重疊子問題 在計算過程中不同子問題可能都會計算某個值。若每個子問題都去求解同乙個值,浪費時間。動態規規劃對每乙個子問...