一,問題描述
給定n個矩陣{a1,a2,…,an},其中,ai與ai+1是可乘的,(i=1,2 ,…,n-1)。不同的計算次序計算量(乘法次數)是不同的,要求通過輸入矩陣的個數和每個矩陣的規模大小,從而確定矩陣連乘積的計算次序和最少數乘次數使得矩陣連乘的次數最小。
分析:
矩陣連乘的條件:第乙個矩陣的列等於第二個矩陣的行,此時兩個矩陣是可乘的;
多個矩陣連乘的結果矩陣,其行列等於第乙個矩陣的行和最後乙個矩陣的列;
兩個矩陣相乘的計算量:
例如:
可知總執行次數為:324=24.
所以矩陣amn和bnk的乘法運算次數為:mnk;
矩陣連乘aiai+1ai+2……aj的最優解問題
假設在第k位置上找到最優解,則問題變成了兩個子問題:(aiai+1……ak),(ak+1……aj),用m[i][j]表示矩陣連乘的最優值,那麼兩個子問題對應的最優值變成m[i][k],m[k+1][j];,設矩陣am的行數為pm,列數為qm,矩陣是可連乘的,即相鄰矩陣qm=pm+1,所以(aiai+1……ak)可表示為pi * qk,(ak+1……aj)可表示為pk+1 * **,qk = pk+1.則兩個矩陣連乘的乘法次數為pi * pk+1 * **。
5.矩陣連乘最優值遞迴式
程式實現
```c
#include
#include
using namespace std;
const
int l =7;
//矩陣連乘的個數
intliancheng
(int n,
int*
*m,int
**s,
int*p)
;void
traceback
(int i,
int j,
int*
*s);
//構造最優解
intmain()
;int
**s = new int
*[l]
;int
**m = new int
*[l]
;//矩陣的維數為11*22,22*33,...66*77
for(
int i=
0;icout<<
"矩陣的最少計算次數為:"
<<
liancheng(6
,m,s,p)
<
cout<<
"矩陣最優計算次序為:"
<
traceback(1
,6,s);
return0;
}int
liancheng
(int n,
int*
*m,int
**s,
int*p)
for(
int r=
2; r<=n; r++
)//r為當前計算的鏈長(子問題規模) }}
}return m[1]
[l-1];
}void
traceback
(int i,
int j,
int*
*s)}
實驗結果與分析
用動態規劃迭代方式解決此問題,可依據其遞迴式自底向上的方式進行計算。在計算過程中,儲存已解決的子問題的答案。每個子問題只計算一次,而在後面需要時只需簡單檢查一下,從而避免了大量的重複計算,最終得到多項式時間的演算法。
演算法動態規劃問題之矩陣連乘
給定n個矩陣,考察通過加括號,這n個矩陣相乘的最少需要多少次乘法 假設有六個矩陣連乘,如下 a1 a2 a3 a4 a5 a6 30 35 35 15 15 5 5 10 10 20 20 25 想要求得這六個矩陣相乘的最優解,可以使用動態規劃的方法解決。動態規劃是指將待求解問題分解成若干個子問題,...
演算法設計與分析 矩陣連乘順序問題
define n 50 include include class matrix 建構函式,作變數初始化工作,為指標分配記憶體空間 matrix matrix p new int n 析構函式,釋放記憶體 matrix matrix delete m delete s delete p 處理鍵盤輸入...
演算法設計 矩陣連乘問題
白天什麼也沒學,晚上才終於拿著筆,對著 寫寫畫畫,終於看明白是怎麼計算的了。以這6個矩陣連乘作為例子 a1a2 a3a4 a5a6 30 35 35 15 15 5 5 10 10 20 20 25 1 首先,要明白兩個矩陣相乘所需要做的乘法次數 2 由於連乘的矩陣必須滿足,前乙個矩陣的列數 後乙個...