動態規劃矩陣鏈(1)

2021-08-27 00:14:01 字數 2363 閱讀 5701

最近看研三的找工作,主要變成題目都是過程實現,模擬一下,稍微帶點技巧,演算法層面也就是動態規劃了,想想自己也一直忙於實驗室各種事情,也該回來看看演算法了,現在遷移一些以前寫過的內容,順便做複習。

矩陣鏈乘法也就為連續相乘的矩陣加括號,以最少的計算次數完成計算。即現有多個連續矩陣相乘a1a2a3...an,對於這樣的n個矩陣相連,採取暴力法,按照排列組合在矩陣之間插入分隔符,可以選擇的種類即有

動態規劃嘛,個人理解也就是無限貪心,打一張表,在改變一點結構後,總能找到上乙個最優結構,即最優解是可以遞迴定義的,這裡摘錄一下演算法導論上的原話:

如何制定動態規劃方案:

1. 刻畫乙個最優解的結構特徵

2. 遞迴的定義最優解的值

3. 計算最優解的值,通常採用自底向上方法

4. 利用計算出的資訊構造出乙個最優解

那麼先從整體的角度來看,假設說前面的分割都非常優秀了,就差最後一步,需要在第k個位置進行切割,那麼就是在a1-an之間選出乙個k,之後計算過程為(a1a2...ak)(ak+1ak+2...an)。那麼在a1-ak之間同樣可以繼續選k『,那麼,我們就可以列出式子:

其中m[i][j]表示ai和aj中間的最小計算次數,也就等於ai和ak之間的最小計算次數加上,ak+1和aj之間的最小計算次數,a[i].row*a[k].col*a[j].col也就是最後生成的左邊矩陣a[i].row行(m1)乘a[k].row列(n1),右邊矩陣a[k+1].row行(m2)乘a[j].col列(n2)的矩陣,左矩陣某一行乘右矩陣某一列是乙個數字的計算次數,總共即有m1*n1*n2次乘法運算。

已經寫出了遞迴式,我們開始計算最優解的值,採取自底向上方法,首先根據遞迴式,將m[i][i]全部填0。接下來設計自底向上填的方法。由遞迴式可以看出,我們要填寫m[i][j]就需要知道m[i][k], m[k+1][j]舉個例子m[2][4] 需要知道m[2][2],m[2][3], m[3][4], [m[4][4]。再舉乙個例子m[1][3],需要知道m[1][1], m[1][2], m[2][3], m[3][3]。

以五個元素為例,先畫出填0的部分

m[1][1] m[2][2] m[3][3] m[4][4] m[5][5]

根據上圖,現在考慮m[1][2],m[1][2]需要知道m[1][1],m[2][2], 那麼m[2][3]需要知道m[2][2],m[3][3]。由此,m[3][4]需要知道m[3][3],m[4][4],補充上圖

m[1][2] m[2][3] m[3][4] m[4][5]

m[1][1] m[2][2] m[3][3] m[4][4] m[5][5]

現在看這張圖就感覺好一些了,那麼跟著數字往上,現在考慮m[1][3],m[2][4],m[3][5],根據已經舉過的資料,來繼續畫圖

m[1][3] m[2][4] m[3][5]

m[1][2] m[2][3] m[3][4] m[4][5]

m[1][1] m[2][2] m[3][3] m[4][4] m[5][5]

可以看出來需要知道的資料是乙個小三角形,很好推測,接下來的資料會是什麼,那麼畫完這個大三角形吧

m[1][5]

m[1][4] m[2][5]

m[1][3] m[2][4] m[3][5]

m[1][2] m[2][3] m[3][4] m[4][5]

m[1][1] m[2][2] m[3][3] m[4][4] m[5][5]

根據遞迴式也能夠看出這個結果。最優解就是m[1][5]的取值。

接下來考慮程式怎麼編寫,從最下面開始,填完了m[same][same]。

開始第二層,容易看出這一層m[i][j]之間j – i = 1,實際每一層都是有相同的數字差。這個數字差值在意義上也就是長度

那麼我們設定乙個變數就叫len,它的變化應該放在最外層迴圈中,迴圈n次(n表示矩陣數目)接下來迴圈變化的就是變數i了,i每次從1開始一直到n-len之後是j, j總是= i + len;

現在,遍歷的迴圈任務就結束了,開始考慮如何計算,也就是怎麼樣做這個三角形。設定變數k,觀察三角形,根據遞迴式,k的值就是從i-j,那麼就這樣設定了。根據遞迴式,可以輕鬆寫下k這個最內層迴圈的內容,如此,這個程式核心部分就結束了,最後,貼上**。

#define num 10

int m[num][num];

int s[num][num];

struct matrix;

void print(int i, int j)

}void matrix_chain_order(struct matrixa[num], int index_max)}}

print(0, index_max);

printf("\n");

}int main()

動態規劃 矩陣鏈乘法

矩陣鏈乘法問題 給定n個矩陣的鏈,矩陣ai的規模為p i 1 p i 求完全括號化方案,使得計算乘積a1a2 an所需標量乘法次數最少。m i j 表示矩陣鏈ai j所需標量乘法次數的最小值。m i j 0 i j m i j m i k m k 1 j p i 1 p k p j i k s 1....

動態規劃 矩陣鏈乘法

兩個矩陣相乘的計算量,對於一般的矩陣乘法來說,如矩陣a m,n 與矩陣b n,p 相乘需要進行的加法次數為m n p次乘法 由於矩陣乘法滿足結合律,因此矩陣相乘的結合性,會影響整個計算表示式的乘法執行次數 如下面的例子,a b c三個矩陣相乘,其中a 10,5 b 5,20 c 20,3 1 ab ...

動態規劃 矩陣鏈乘法

def matrix multipy a,b 乘法得到的是乙個 a.rows,b.cols 的矩陣,相當於a.rows個向量的b.cols次的向量線性加權 ifnot a.shape 1 b.shape 0 a組中向量的維度與b組中向量的維度一致 print error else 將每乙個元素都初始...