演算法設計 矩陣乘法

2021-06-10 23:13:41 字數 1884 閱讀 2122

研究生課程系列文章參見索引《在信科的那些課》

設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,...