如果你對其他算法或者案例感興趣,請考慮閱讀我的以下文章。
遞歸案例-正整數劃分.
遞歸案例-漢諾塔.
遞歸案例-全排列.
動態規劃案例-最長公共子序列(含表格填寫、內容理解、問題分析、實例講解、例題答案).
遞歸案例-電路佈線(含表格填寫等超詳細,純人話講解).
動態規劃案例-矩陣連乘
問題
給定n個矩陣{A1, A2, …,An},其中,Ai與Ai+1是可乘的,計算這n個矩陣的連乘積。從中找出一種乘次數最少的計算次序。
問題分析
什麼是矩陣連乘
學過線性代數的肯定懂得什麼是矩陣連乘,但是在這裏我還是要說一下(因爲我學過線代,但是當時看見題目還是懵逼的一批)。
舉個例子:
一個A矩陣:2×2和一個B矩陣:2×1再和一個C矩陣:1×3的矩陣連乘:
這就是矩陣連乘了。
爲什麼會出現乘次數不一樣的情況
由於矩陣相乘滿足乘法結合律,即A×B×C=(A×B)×C=A×(B×C),我們從實際例子上來看一下。
1. 假如我們計算(A×B)×C,先算(A×B),此時乘法次數爲2×2×1=4次
2.我們再乘C矩陣,乘法次數爲4+2×1×3=10
1. 現在我們計算A×(B×C),先算(B×C),此時乘法次數爲2×1×3=6次
2.我們再用A矩陣乘以剛纔的結果,乘法次數爲6+2×2×3=18
通過上面的兩次運算,我們可以發現,在每次結合不同的矩陣,就能導致不同的乘法次數。
爲什麼要用動態規劃算法
1.首先,這個問題符合最優子結構性質:問題的最優解包含子問題的最優解。舉個簡單的例子來理解這句話:一個國家裏面最厲害的兵,
肯定是他所在的軍營裏面最厲害的兵;各個軍營裏面最厲害的兵,經過選拔(武舉考試?)就可以有人脫穎而出,成爲這個國家最厲害的
兵。
2.其次就是,重疊子問題性質:子問題之間不獨立的同時(這是區分分治算法的關鍵),少量子問題被重複解決了。說白了就是子問題之間有聯繫的同時有些計算重複了,我們可以在計算第一次的時候將結果記錄下來,以後再用到的時候,直接取值,不用再去花時間計算了。
記錄下來,以後再用到的時候,直接取值,不用再去花時間計算了。
如何用動態規劃算法求解
以A1:50×10 A2:10×40 A3:40×30 A4:30×5 爲例,計算最少的乘法次數
1.我們規定m[i,j]表示第i個矩陣到第j個矩陣之間的連乘(Ai×…×Aj)的最少乘法次數,那麼我們的問題就變成了求解m[1,n]。
2.我們數組p[i-1]×p[i]來表示維數矩陣的維數(也就是多少行,多少列),比如A矩陣是50行、10列,那麼矩陣A就可以表示爲:
(p[0]=50)×(p[1]=10)。因此可以列出下表。
p[0] | p[1] | p[2] | p[3] | p[4] |
---|---|---|---|---|
50 | 10 | 40 | 30 | 5 |
當我們準備好之後,就可以得到這麼一個式子:
我們來理解這個式子:
1.當i==j的時候,m[i,j]表示的就是一個矩陣的乘法次數,也就是0。
2.當i<j的時候,此時的m[i,j]表示多個矩陣的連乘,將i~j個矩陣從第k個位置切開,也就
是給第i ~ k個矩陣加括號,給k ~ j個矩陣加括號,那麼 矩陣連乘的次數 = 第一個矩陣連乘的次數 + 第二個矩陣連乘的次數 + 這兩個矩陣連乘的次數。
接下來就是動態規劃的重點環節了:填表。
i \ m[i,j] / j | 1 | 2 | 3 | 4 |
---|---|---|---|---|
1 | 0 | 20000 | 27000 | 10500 |
2 | 0 | 12000 | 8000 | |
3 | 0 | 6000 | ||
4 | 0 |
由此我們可以知道最小的乘法次數爲10500,那麼這個表是怎麼填,以及如何讀的呢?
i | j | m[i,j] |
---|---|---|
1 | 1 | 0 |
2 | 2 | 0 |
3 | 3 | 0 |
4 | 4 | 0 |
1 | 2 | min{m[1,1]+m[2,2]+p0p1p2}=20000 |
2 | 3 | min{m[2,2]+m[3,3]+p1p2p3}=12000 |
3 | 4 | min{m[3,3]+m[4,4]+p2p3p4}=6000 |
1 | 3 | min{m[1,1]+m[2,3]+p0p1p3 =27000 ,m[1,2]+m[3,3]+p0p2p3 =80000}=27000 |
2 | 4 | min{m[2,2]+m[3,4]+p1p2p3 =8000 ,m[1,2]+m[3,3]+p1p3p4=27000}=8000 |
1 | 4 | min{m[1,1]+m[2,4]+p0p1p4 =10500 ,m[1,2]+m[3,4]+p0p2p4 =36000 ,m[1,3]+m[4,4]+p0p3p4=34500}=10500 |
從這個表中我們看出填剛纔那個表的順序是按對角線進行填寫.
1.當i=1,j=4的時候最小乘法次數爲10500,對應的劃分爲m[1,1]+m[2,4]+p0p1p4 =10500 ,也就是(A1(A2A3A4))
2.我們繼續往下找m[2,4]對應的劃分m[2,2]+m[3,4]+p1p2p3 =8000 ,也就是(A2(A3A4))
3.最後我們就得到了最終的答案:(A1(A2(A3A4)))