【問題】
給定n個矩陣的鏈,其中ai與是ai-1可乘的,矩陣ai的維數為pi-1*pi(1≤i≤n),
如何確定計算矩陣鏈乘積a1a2…an的計算次序(完全括號化方式),使得依此次序計算矩陣鏈乘積需要的數乘次數最少。
【演算法分析】
將矩陣連乘積aiai-1...aj簡記為a[i:j] ,i≤j 。
考察計算a[i:j]的最優計算次序。設這個計算次序在矩陣ak和ak+1之間將矩陣鏈斷開,i≤k加括號方式為:
(aiai+1...ak)(ak+1ak
+2...aj
)計算量:a[i:k]的計算量加上a[k+1:j]的計算量,再加上a[i:k]和a[k+1:j]相乘的計算量。
特徵:計算a[i:j]的最優次序所包含的計算矩陣子鏈 a[i:k]和a[k+1:j]的次序也是最優的。
矩陣連乘計算次序問題的最優解包含著其子問題的最優解,這種性質稱為最優子結構性質。
遞迴式如下:
【源**】
**(1)
#include using**(2)namespace
std;
void matrixchain(int p, int **m, int **s, int
n) }
}}//
找出s陣列中記錄的最優斷開點
void traceback(int i, int j, int **s)
cout
<< "("
; traceback(i, s[i][j], s);
traceback(s[i][j] + 1
, j, s);
cout
<< ")"
;}intmain() ;
int **m = new
int*[n+1
];
int **s = new
int*[n+1
];
for (int i = 0; i < n+1; i++)
matrixchain(p, m, s, n);
traceback(
1, n, s);
for (int i = 0; i < n+1; i++)
delete
m;
delete
s;
return0;
}
#include using【演算法複雜度分析】namespace
std;
void matrixchain(int p, int **m, int **s, int
n) }
}}//
找出s陣列中記錄的最優斷開點
void traceback(int i, int j, int **s)
cout
<< "("
; traceback(i, s[i][j], s);
traceback(s[i][j] + 1
, j, s);
cout
<< ")"
;}intmain() ;
int **m = new
int*[n];
int **s = new
int*[n];
for (int i = 0; i < n; i++)
matrixchain(p, m, s, n);
traceback(
0, n - 1
, s);
for (int i = 0; i < n; i++)
delete
m;
delete
s;
return0;
}
主要計算量取決於演算法中對r,i和k的3重迴圈。
演算法的計算時間上界為o(n3)。
演算法所占用的空間為o(n2)。
矩陣連乘問題
矩陣連乘問題 應用動態規劃演算法,將前面計算的重複值儲存,一次來推進下一步的計算,直到得到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的最優加括號方案。證明略。但可證明該假設...