动态规划 -- 矩阵链乘法

矩阵链乘法

n个矩阵相乘,A1A2...An,试着找到一种相乘顺序,使得整个相乘的过程中所做的标量乘法次数最少,即相乘的代价最小。

 

问题分析:

  记矩阵Ai的行列分别为Pi-1和Pi,那么A1*A2所做的乘法的次数为P0*P1*P2

A1A2...An的最小相乘代价为f(1,n),Ai...Aj的最小相乘代价为f(i,j)

则 f(1,n) = min{f(1,k)+f(k+1,n)+P0*Pk*Pn} k=1...n-1

f(i,i)=0  f(i,i+1)=Pi-1*Pi*Pi+1

 

So 可以由此产生递归式

 1 Recursive_Matrix_Multiply(p, i, j)
2 {
3 if(i==j)
4 return 0;
5 f[i][j] = max_int;
6 for(k=i;k<j;k++)
7 {
8 q=Recursive_Matrix_Multiply(p,i,k)+Recursive_Matrix_Multiply(p,k+1,j)+p[i-1]*p[k]*p[j];
9 if(q<f[i][j])
10 {
11 f[i][j]=q;
12 s[i][j]=k;
13 }
14 }
15 return f[i][j];
16 }

其中s[i][j]记录的是Ai...Aj相乘的最小代价的分割点,即先计算Ai...Ak,再计算Ak+1...Aj,然后再将结果相乘,Ai...Aj的相乘代价最小

递归的解法看起来思路清晰,但时间复杂度太高

若记n个矩阵的时间复杂度为T(n),则T(n)=∑k=1..n-1{T(k) + T(n-k) + c}, 可以推断T(n)>=2n

分析递归的过程可以发现,有很多子问题被重复计算过了,比如计算A1...A3的过程中需要A2A3,在A1...Aj,j>3的过程中,也都需要A2A3,如果我们能够自底向上开始计算Ai..Aj,并把结果记录下来,后面用到的时候直接查询就可获得,就可以降低时间复杂度了

于是,有了以下自底向上的解法

 1 Matrix_Chain_Order(p, 1, n)
2 {
3 for(t=1;t<n+1;i++)
4 f[t][t]=0;
5 for(m=2;m<n;m++)
6 {
7 for(i=1;i<=n-m+1;i++)
8 {
9 j=i+m-1;
10 f[i][j]=max_int;
11 for(k=i;k<j;k++)
12 {
13 q = f[i][k]+f[k+1][j]+p[i-1]*p[k]*p[j];
14 if(q<f[i][j])
15 {
16 f[i][j]=q;
17 s[i][j]=k;
18 }
19 }
20 }
21 }
22 return f and s;
23 }

三层循环,每一层中的循环变量值至多为n-1,故时间复杂度为O(n3),时间复杂度有指数级 降低到了多项式时间,而付出的代价是增加了O(n2)的辅助空间

 

动态规划的思想就是以空间为代价,降低算法的时间复杂度


转载于:https://www.cnblogs.com/un4sure/archive/2012/03/16/2400867.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值