矩陣連乘問題
問題描述:
給定n個矩陣:a1,a2,…,an,其中ai與ai+1是可乘的,i=1,2…,n-1。確定計算矩陣連乘積的計算次序,使得依此次序計算矩陣連乘積需要的數乘次數最少。輸入資料為矩陣個數和每個矩陣規模,輸出結果為計算矩陣連乘積的計算次序和最少數乘次數。
問題分析:
1.分析最優解的結構
設計求解具體問題的動態規劃演算法的第一步是刻畫該問題的最優解的結構特徵。我們將矩陣連乘積aiai+1…aj簡記為a[ i : j ]。考察計算a[ 1: n]的最優計算次序。設這個計算次序在矩陣ak和ak+1之間將矩陣鏈斷開,1<=k2.建立遞迴關係
從連乘矩陣個數為2開始計算每次的最小乘次數m[i][j]: m[0][1] m[1][2] m[2][3] m[3][4] m[4][5] //m[0][1]表示第乙個矩陣與第二個矩陣的最小乘次數
然後再計算再依次計算連乘矩陣個數為3:m[0][2] m[1][3] m[2][4] m[3][5]
連乘矩陣個數為4:m[0][3] m[1][4] m[2][5]
連乘矩陣個數為5:m[0][4] m[1][5]
連乘矩陣個數為6:m[0][5] //即最後我們要的結果
m[i][j]給出了最優值,即計算a[i:j]所需的最少數乘次數。同時還確定了計算a[i:j]的最優次序中的斷開位置k,也就是說,對於這個k有
m[i][j]=m[i[k]+m[k+1][j] + pi-1*pk*pj
若將對應於m[i][j]的斷開位置k記為s[i][j],在計算最優值m[i][j]後,可以遞迴地有s[i][j]構造出相應的最優解。
計算最優值
根據計算m[ i ][ j ]的遞迴式,容易寫乙個遞迴演算法計算m[ 1 ][ n ]。但是簡單地遞迴將好費指數計算時間。在遞迴計算時,許多子問題被重複計算多次。這也是該問題可以用動態規劃演算法求解的又一顯著特徵。
用動態規劃演算法解決此問題,可依據其遞迴是以自底向上的方式進行計算。在計算的過程中,儲存以解決的子問題答案。每個子問題只計算一次,而在後面需要時只要簡單查一下,從而避免大量的重複計算。
#include
#include
using
namespace std;
const
int maxsize =
100;
int p[maxsize]
;int m[maxsize]
[maxsize]
, s[maxsize]
[maxsize]
;//m[i][j]儲存最優解
int n =6;
void
matrixchain()
for(r =
2; r <= n; r++
)//矩陣連乘的規模為r ,從2開始}}
}}void
print
(int i,
int j)
cout <<
"(";
print
(i, s[i]
[j])
;print
(s[i]
[j]+
1, j)
;//遞迴1到s[1][j]
cout <<
")";
}int
main()
矩陣連乘問題
矩陣連乘問題 應用動態規劃演算法,將前面計算的重複值儲存,一次來推進下一步的計算,直到得到m 1 n 的值,為最少的乘法次數 m i j 表示計算a i.j 所需的最少數乘次數 m i j min i s i j 記錄斷開位置,也就是最少計算次數的中間位置。include using namespa...
矩陣連乘問題
由於矩陣的乘法滿足結合律,故計算矩陣的連乘積可以有許多不同的計算次序。這中計算次序 可以用加括號的方式來確定。例如,矩陣連乘積a1a2a3a4可以有5種不同的完全加括號方式 a1 a2 a3a4 a1 a2a3 a4 a1a2 a3a4 a1 a2a3 a4 a1a2 a3 a4 矩陣a和b可乘的條...
矩陣連乘問題
矩陣連乘問題 問題分析 最優子結構性質假設n個矩陣連乘的最優加括號方案為 a1.ak ak 1.an 注 此處省略了a1.ak,ak 1.an兩個子矩陣內部的括號 則加括號方案 a1.ak 是子矩陣鏈a1.ak的最優加括號方案,ak 1.an 是ak 1.an的最優加括號方案。證明略。但可證明該假設...