演算法13 動態規劃矩陣鏈乘法

2022-05-23 05:33:11 字數 3746 閱讀 8172

矩陣鏈乘法是動態規劃裡面使用到的乙個例子

1 兩個矩陣的計算

那麼對於乙個矩陣的乘法,首先如果是兩個矩陣的乘法,那麼如何實現呢?

注意到我們使用二維陣列表示矩陣,但是二維陣列不能作為函式的返回值。具體實現如下

1 #include 2 #include 3 #include 4

5#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 3

4#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 2

using

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 將每乙個元素都初始...