算法设计与分析——动规矩阵联乘问题学习笔记

动态规划——矩阵联乘

目的

由于n个矩阵联乘时,计算次序影响着计算量(数乘的次数),所以要找到一种加括号的方式使得依次计算次序计算矩阵联乘需要的数乘次数最少。

实现过程

加括号的过程可以看作对这组矩阵加断点将矩阵链断开,所以假设在   A k \ A_k  Ak   A k + 1 \ A_{k+1}  Ak+1之间断开,此时,将原矩阵链分为了   A [ 1 : k ] \ A[1:k]  A[1:k]   A [ k + 1 : n ] \ A[k+1:n]  A[k+1:n]两部分,想要最后整体达到最优,那么分开的两段也要达到最优。且分段后   A [ i : n ] \ A[i:n]  A[i:n] 的最小数乘数为   A [ 1 : k ] \ A[1:k]  A[1:k]的计算量加上   A [ k + 1 : n ] \ A[k+1:n]  A[k+1:n]的计算量再加上   A [ 1 : k ] \ A[1:k]  A[1:k]   A [ k + 1 : n ] \ A[k+1:n]  A[k+1:n]相乘的计算量。
由此递归的定义出最少   A [ i : j ] \ A[i:j]  A[i:j]段的最小数乘数为
在这里插入图片描述

在代码实现的过程中利用了递归的重叠子问题性质,对于反复计算的子问题,自底向上计算,将答案保存,后面再需要直接查找即可。

代码

r表示矩阵联乘规模,i表示最大可起始点,m最优值数组,s最优断开位置的数组。

void matrixchain(int *p,int n,int **m,int **s)
{
	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];//Ai的维数时是pi-1,pi 
			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[i]*p[j];
				if(t<m[i][j])
				{
					m[i][j]=t;
					s[i][j]=k;
				}
			}
		}
	}
 } 
void traceback(int i,int j,int **s)
 {
 	if(i==j)
 	 return;
 	traceback(i,s[i][j],s);
 	traceback(s[i][j]+1,j,s);
 	cout<<"A ["<<i<<","<<s[i][j]<<"]";
 	cout<<"and A ["<<s[i][j]+1<<","<<j<<"]"<<endl;
 }
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

雪痕迹

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值