動態規劃之矩陣鏈相乘問題(演算法導論)

2021-06-26 05:35:40 字數 1917 閱讀 9733

問題描述

給定n個矩陣序列,(a1,a2,a3,a4,...,an). 計算他們的乘積:a1a2a3...an.

由於矩陣的乘法運算符合結合律,因而可以通過調整計算順序,從而降低計算量。

樣例分析

比如有三個矩陣分別為:a1: 10*100,a2: 100*5,a3: 5*50

假如現在按照(a1a2)a3的順序計算需要的計算量為:10*100*5+10*5*50=7500次運算。

若按照a1(a2a3)的順序計算,需要的計算量為:100*5*50+10*100*50=75000次運算。

上面兩種不同的運算順序所有的計算量相差十倍。

因而,一種最優的計算順序將能很大程度的減少矩陣連乘的運算量。

問題解析

此問題的目的是尋找一種最優的括號化方案。下面用動態規劃的思想來進行分析:

1、動態規劃的第一步:尋找最優子結構。為方便起見,使用ai..j表示aiai+1...aj的乘積結果矩陣。對於k(i<=k

2、設m[i][j]為ai..j的最優計算順序所要花費的代價。則其求解公式為:

if i == j, m[i][j] = 0; //因為只有乙個矩陣時計算**為0,即不需要計算。

m[i][j]=min i<=k

3、為了能夠輸出求解順序,需要儲存區間中的一些分割點。假如ai..j中的最優分割點為k,則我們使用s[i][j]=k。即在ai..j中,分別計算ai..k 和 ak+1..j 所用的計算開銷最小。

4、採用自底向上的**法。依次求解矩陣長度為2,3,...,n的最優計算順序。

演算法思想

1、對m[i][i]全部初始化為0.

2、在矩陣鏈a1..n中,依次計算長度len為2,3,...,n的m[i][j]大小。(j-i+1==長度len).

3、對於長度為len的m[i][j]初始化為+∞。然後根據以下公式計算m[i][j]的最小值。

m[i][j]=min

由於比長度len小的m[i][k],m[k+1][j]都已經提前計算了出來。所以就可以計算出最小的m[i][j],同時儲存相應的最優點。如:s[i][j] = k; //k為i~j的最優計算分割點。

4、根據以上儲存的結果,輸出。

具體**如下:(c**)

/**

動態規劃之矩陣鏈相乘,

輸入:有n個矩陣連乘,用一行有n+1個數陣列表示,表示是n個矩陣的行及第n個矩陣的列,它們之間用空格隔開.

輸出:每組測試資料的輸出佔一行,它是計算出的矩陣最少連乘積次數,輸出最優全括號結構

樣例輸入:10 100 5 50

上面一組資料分別代表: a1:10*100, a2:100*5, a3:5*50

樣例輸出:7500 ((a1a2)a3)

30 35 15 5 10 20 25 --> 15125 ((a1(a2a3))((a4a5)a6))

**/#include int m[1002][1002],s[1002][1002];

void matrix_chain(int a, int n)

{ int l, i, j, k, tmp;

for(l=2; l<=n; l++)

{ for(i=1; i<=n-l+1; i++) //長度為l的區間,其最小下標為1~n-l+1

{ j=i+l-1;

m[i][j] = 0x7fffffff;

for(k=i; k

動態規劃之矩陣鏈相乘

在看這張之前,最好看看我寫的 動態規劃詳解 裡面都是講理論基礎,我下面的分析都是在此基礎上進展的。問題描述 詳見演算法導論p197 p198 已知 給定n個矩陣構成的乙個矩陣鏈 a1,a2,an 矩陣ai的維數為pi 1 pi 求 決定該矩陣鏈的乘法結合順序 即加括號 使得矩陣鏈乘法的執行時間最短 ...

動態規劃之矩陣鏈相乘

題目 n個矩陣連乘,求最少的乘法運算次數以及結合方式 假設矩陣a為r1 r2,矩陣b為r2 r3,所以m a b r1 r2 r3。當有多個矩陣相乘的時候,矩陣以不同的方式結合的時候其運算次數是不同的。例如 m m1 m2 m3 m4 5 20 20 50 50 1 1 100 m1 m2 m3 m...

動態規劃 矩陣鏈相乘

實驗題目3 矩陣鏈乘法 11.1日實驗 要求 1 設計暴力法,產生所有矩陣鏈相乘以組合情況,寫出 並除錯成功 2 設計動態規劃演算法,寫出 尋找最小乘法次數和對應相乘的順序,並除錯成功 3 隨機產生由10個矩陣,測試 2 的 輸出最小乘法次數和相乘的順序。from random import def...