研究生課程系列文章參見索引《在信科的那些課》
設a1,a2,…,an為矩陣序列,ai為pi-1×pi階矩陣,i = 1,2,…,n. 確定乘法順序使得元素相乘的總次數最少.
輸入:向量p =
例項:
p = <10, 100, 5, 50> a1: 10 × 100, a2: 100 × 5, a3: 5 × 50
乘法次序:
(a1 a2)a3: 10 × 100 × 5 + 10 ×5 × 50 = 7500
a1(a2 a3): 10 × 100 × 50 + 100 × 5 × 50 = 75000
先將矩陣鏈加括號分為兩部分,即p=a1*a2*...*an=(a1*a2...*ak)*(ak+1*...an),則有f(n)=f(1)*f(n-1)+f(2)*f(n-2)+...+f(n-1)*f(1)種方法。f(n)為乙個
catalan數,所以一般的方法要計算
輸入p=< p0, p1, …, pn>,ai..j 表示乘積 aiai+1…aj 的結果,其最後一次相乘是:
m[i,j] 表示得到ai..j的最少的相乘次數。
遞推方程:
為了確定加括號的次序,設計表s[i,j],記錄求得最優時最一位置。
由上面的遞迴公式,很容易得到演算法的遞迴實現:
const int n=5;
int m[n][n]; //m[i][j]儲存ai到aj的最小乘法次數
int s[n][n];//s[i][j]儲存ai到aj之間加括號的位置
int recurmatrixchain(int p,int i,int j)
{ m[i][j]=100000;
s[i][j]=i;
if(i==j)
m[i][j]=0;
else{
for(int k=i;k複雜性滿足遞推關係:
由數學歸納法可得:
可見遞迴實現的複雜性雖然較一般演算法有改進,但還是較高。分析原因,主要是子問題重複程度高。如下圖所示:
1..4表示計算ai..j中i=1,j=4的子問題,其子問題包括a1..1,而a1..2,a1..3中都包括子問題a1..1,所以很多子問題被重複計算了多次。
於是,我們想到用自底向上的迭代實現。
迭代實現主要思想是子問題由小到大,每個子問題只計算一次,並且把結果儲存起來,後來用到這個子問題時,直接代入。
void matrixchain(int p,int n)
{ int r,i,j,k,t;
for(i=0;i行7,9,16的迴圈為o(n),外層迴圈為o(1),所以演算法複雜度w(n)=o(n^3)
子問題由小到大的計算過程如下圖所示:
再寫乙個列印結果,以及列印優化函式備忘錄m和標記函式的s的函式:
void printmatrixchain(int s[n],int i,int j)
{ if (i==j)
{ cout的簡單例項,執行上述**:
*注意:上述**與解釋中的下標不同,即**中s[i-1][j-1]表示實際中的s[i,j]
演算法設計 矩陣乘法
研究生課程系列文章參見索引 在信科的那些課 設a1,a2,an為矩陣序列,ai為pi 1 pi階矩陣,i 1,2,n.確定乘法順序使得元素相乘的總次數最少.輸入 向量p 例項 p 10,100,5,50 a1 10 100,a2 100 5,a3 5 50 乘法次序 a1 a2 a3 10 100 ...
演算法分析設計實踐 矩陣鏈乘法
設n個矩陣序列,其中第i個矩陣式p i 1 p i 階矩陣,給定矩陣的向量p,求一種乘法次序,使得基本運算總次數最小 設a i j 為 j k ia k 設cnt i j 為a i j 的最少運算次數 cnt i j min cnt i k cnt k 1 j p i 1 p k p j 1 for...
矩陣乘法AC演算法
總時間限制 1000ms 記憶體限制 65536kb 描述 計算兩個矩陣的乘法。n m階的矩陣a乘以m k階的矩陣b得到的矩陣c 是n k階的,且c i j a i 0 b 0 j a i 1 b 1 j a i m 1 b m 1 j c i j 表示c矩陣中第i行第j列元素 輸入第一行為n,m,...