动态规划算法与分治法类似,其基本思想也是将待求解问题分解成若干个子问题。
动态规划基本步骤
矩阵相乘只有在第一个矩阵的列数和第二个矩阵的行数相同时才有定义,设有矩阵M1,M2,M3,M4,
其维数分别是30×35, 35×15, 15×5 和5×10,现要求出这4个矩阵相乘的结果。若矩阵A的维数是m×n,矩阵B的维数是n×r,则A与B相乘后所得矩阵AB的维数是m×r。按照矩阵相乘的定义,求出矩阵AB中的一个元素需要做n次乘法(及q-1次加法)。这样,要计算出AB就需要做n×m×r次乘法。为简单起见,且由于加法比同样数量的乘法所用时间要少得多,故这里我们暂不考虑加法的计算量。因矩阵连乘满足结合律,故计算矩阵连乘的方式可以有多种。
例如
M3M4:5*15*10=750;共750次乘法
M2(M3M4):35*15*10=5250;共5250次乘法
M1(M2(M3M4)):30*35*10=10500;共10500次乘法
(M1(M2M3)):30*35*5=5250;共5250次乘法
(M1(M2M3))M4:30*5*10=1500;共1500次乘法
求矩阵连乘最小乘法次数
将矩阵连乘积Ai,Ai+1,...,Aj 简记为A[i:j] ,这里i≤j ,考察计算A[i:j]的最优计算次序。设这个计算次序在矩阵
Ak和Ak+1之间将矩阵链断开,i≤k<j,则其相应完全加括号方式为(AiAi+1...Ak)(Ak+1...Aj)
计算量:A[i:k]的计算量加上A[k+1:j]的计算量,再加上A[i:k]和A[k+1:j]相乘的计算量
![](https://i-blog.csdnimg.cn/blog_migrate/55be934b9e7fb841bced5b86a48a0332.png)
可以递归地定义m[i,j]为:
例如我们来计算此四个矩阵的最小连乘次数 30×35, 35×15, 15×5 ,5×10和10*25
m[2,4]=min{m[2,k]}+m[k+1,4]+P1PkP4}其中分K的不同取值来找最小的,此时k只能取2,3。k的位置只有j-i种可能
4-2=2,所以k只有2种可能
矩阵 | M1 | M2 | M3 | M4 | M5 |
行数*列数 | 30*35 | 35*15 | 15*5 | 5*10 | 10*25 |
P下标 | 0 | 1 | 2 | 3 | 4 |
P值 | 30 | 35 | 15 | 5 | 10 |
m[2,4]=m[2,2]+m[3,4]+P1P2P4=0+m[3,3]+m[4,4]+P2P3P4+P1P2P4=0+0+0+15*5*10+35*15*10=750+5250=6000
或者=m[2,3]+m[4,4]+P1P3P4=m[2,2]+m[3,3]+P1P2P3+0+P1P3P4=0+0+35*15*5+0+35*5*10=2625+1750=4375
在程序编写中通过比较大小得出最小次数,主要代码实现如下:
for(int i =1; i <= n; i++) m[i][i] = 0;
for(int r =2; r <= n; r++)
for(int i =1; i <= n - r+1; i++) {
int j=i+r-1;
m[i][j] = m[i+1][j]+p[i-1]*p[i]*p[j];
s[i][j] = i;
for(int k =i+1; k < j; k++) {
int t =m[i][k] + m[k+1][j] + p[i-1]*p[k]*p[j];
if(t < m[i][j]) {
m[i][j] = t;
s[i][j] = k;}