矩陣鏈乘法是動態規劃裡面使用到的乙個例子
1 兩個矩陣的計算
那麼對於乙個矩陣的乘法,首先如果是兩個矩陣的乘法,那麼如何實現呢?
注意到我們使用二維陣列表示矩陣,但是二維陣列不能作為函式的返回值。具體實現如下
1 #include 2 #include 3 #include 45#define a_rows 3
6#define a_columns 4
7#define b_rows 4
8#define b_columns 3910
void matrix_multiply(int a[a_rows][a_columns],int b[b_rows][b_columns],int
c[a_rows][b_columns])
1116
for (int i = 0; i < a_rows; i++)
1725}26
}27}28
29int
main()
30,,};
35int b[b_rows][b_columns]=,,,};
36int c[a_rows][b_columns]=;
37matrix_multiply(a,b,c);
38for (int i = 0; i < 3; i++)
3947}48
}49return0;
50 }
2 矩陣鏈問題
問題描述
給定n個矩陣構成的乙個鏈1,a2,a3,.......an>,其中i=1,2,...n,矩陣a的維數為pi-1pi,對乘積 a1a2...an 以一種最小化標量乘法次數的方式進行加全部括號。
換句話說,就是在矩陣鏈乘問題中,實際上並沒有把矩陣相乘,目的是確定乙個具有最小代價的矩陣相乘順序。找出這樣乙個結合順序使得相乘的代價最低。
一般的過程如下
(1)最優括號話方案的結構特徵
假設aiai+1....aj的乙個最優加全括號把乘積在ak和ak+1之間分開,則ai..k和ak+1..j也都是最優加全括號的。
(2)乙個遞迴求解方案
設m[i,j]為計算機矩陣ai...j所需的標量乘法運算次數的最小值,對此計算a1..n的最小代價就是m[1,n]。現在需要來遞迴定義m[i,j],分兩種情況進行討論如下:
當i==j時:m[i,j] = 0,(此時只包含乙個矩陣)
當i(3)計算最優代價
我們不採用遞迴實現,而是自下向上的借助輔助空間儲存中間量實現;
(4)構造乙個最優解
具體的實現過程如下面所示
還沒有調好,主要是二維陣列不能作為返回值
1 #include 2 #include 34#define n 6
5#define maxvalue 99999967
void recursive_matrix_chain(int *p,int i,int j,int m[n+1][n+1],int s[n+1][n+1
]);8
int memoized_matrix_chain(int *p,int m[n+1][n+1],int s[n+1][n+1
]);9
int lookup_chain(int *p,int i,int j,int m[n+1][n+1],int s[n+1][n+1
]);10
11//
我們首先採用遞迴來實現
12void recursive_matrix_chain(int *p,int i,int j,int m[n+1][n+1],int s[n+1][n+1
])13
18else
1930}31
32}33}
3435
//因為遞迴的計算量太大,所以我們可以採用備忘錄的方法,自頂向下實現
3637
int memoized_matrix_chain(int *p,int m[n+1][n+1],int s[n+1][n+1
])3846}
47return lookup_chain(p,1
,n,m,s);48}
4950
int lookup_chain(int *p,int i,int j,int m[n+1][n+1],int s[n+1][n+1
])51
56if (i==j)
5760
else
6169}70
}71return
m[i][j];72}
7374
75void print_optimal_parens(int s[n+1][n+1],int i,int
j)76
81else
8288}89
90int
main()91;
93int m[n+1][n+1]=;
94int s[n+1][n+1]=;
95int
i,j;
96 memoized_matrix_chain(p,n+1
,m,s);
97 printf("
m value is: ");
9899
for(i=1;i<=n;++i)
100112 printf("
the result is:\n");
113 print_optimal_parents(s,1
,n);
114return0;
115 }
現在再給出乙個c++的版本,乙個實現,我是看的別人的,自己可以修改
1 #include 2using
namespace
std;34
#define n 6
5#define maxvalue 100000067
void matrix_chain_order(int *p,int len,int m[n+1][n+1],int s[n+1][n+1
]);8
void print_optimal_parents(int s[n+1][n+1],int i,int
j);9
10int
main()11;
13int m[n+1][n+1]=;
14int s[n+1][n+1]=;
15int
i,j;
16 matrix_chain_order(p,n+1
,m,s);
17 cout<<"
m value is:
"<18for(i=1;i<=n;++i)
1924 cout<<"
s value is:
"<25for(i=1;i<=n;++i)
2631 cout<<"
the result is:
"<32 print_optimal_parents(s,1
,n);
33return0;
34}3536
void matrix_chain_order(int *p,int len,int m[n+1][n+1],int s[n+1][n+1
])3755}
56}57}
58}5960
//s中存放著括號當前的位置
61void print_optimal_parents(int s[n+1][n+1],int i,int
j)62
7273 }
動態規劃 矩陣鏈乘法
矩陣鏈乘法問題 給定n個矩陣的鏈,矩陣ai的規模為p i 1 p i 求完全括號化方案,使得計算乘積a1a2 an所需標量乘法次數最少。m i j 表示矩陣鏈ai j所需標量乘法次數的最小值。m i j 0 i j m i j m i k m k 1 j p i 1 p k p j i k s 1....
動態規劃 矩陣鏈乘法
兩個矩陣相乘的計算量,對於一般的矩陣乘法來說,如矩陣a m,n 與矩陣b n,p 相乘需要進行的加法次數為m n p次乘法 由於矩陣乘法滿足結合律,因此矩陣相乘的結合性,會影響整個計算表示式的乘法執行次數 如下面的例子,a b c三個矩陣相乘,其中a 10,5 b 5,20 c 20,3 1 ab ...
動態規劃 矩陣鏈乘法
def matrix multipy a,b 乘法得到的是乙個 a.rows,b.cols 的矩陣,相當於a.rows個向量的b.cols次的向量線性加權 ifnot a.shape 1 b.shape 0 a組中向量的維度與b組中向量的維度一致 print error else 將每乙個元素都初始...