矩阵连乘问题(递归与动态规划实现)

问题描述

给定n个矩阵{A1A2…An},其中Ai和Ai+1是可乘的,考察这n个矩阵的连乘积A1A2…An。由于矩阵的乘法满足结合律,故计算矩阵的连乘积有许多不同的计算次序,而不同的计算次序,所需要计算的连乘次数也是不同的,求解连乘次数最少的矩阵连乘最优次序。
**

递归实现:

#include "stdafx.h"
 int p[100],s[100][100],n;
 //计算最优值
 int LookupChain(int i, int j,)
{
      if (i == j) return 0;
       int u= LookupChain(i,i) + LookupChain(i+1,j) + p[i-1]*p[i]*p[j];
       s[i][j] = i;
       for (int k = i+1; k < j; k++) {
         int t = LookupChain(i,k) + LookupChain(k+1,j) + p[i-1]*p[k]*p[j];
         if (t < u) { u = t; s[i][j] = k;}
         }
       return u;
}
 //构造最优解
void Traceback(int i, int j, int s[100][100]){
		if(i==j) return;
		Traceback(i, s[i][j], s);
		Traceback(s[i][j]+1, j, s);
		printf("Multiply A%d,%d",i,s[i][j]);
		printf("and A%d,%d\n",s[i][j]+1,j);
}
int main(){
    printf("请输入矩阵个数:\n");
    scanf("%d",&n);
    printf("请输入矩阵各维数值:\n");
    for(int i=0;i<n+1;i++){
        scanf("%d",&p[i]);
    }
    printf("最优值为:%d\n",LookupChain(1,n));
	printf("最优解为:\n");
    Traceback(1,n,s);
    printf("\n");
	return 0;
}

动态规划实现:

#include "stdafx.h"
//计算最优值
void matrixChain(int* p, int n,int m[100][100],int s[100][100]) {
	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;
				}
			}
		}
	}
}
//构造最优解
void Traceback(int i, int j, int s[100][100]){
		if(i==j) return;
		Traceback(i, s[i][j], s);
		Traceback(s[i][j]+1, j, s);
		printf("Multiply A%d,%d",i,s[i][j]);
		printf("and A%d,%d\n",s[i][j]+1,j);
}

int main(int argc, char* argv[])
{
	int p[100],m[100][100],s[100][100];
	int	n;
	printf("请输入矩阵个数:\n");
    scanf("%d",&n);
    printf("请输入矩阵各维数值:\n");
    for(int i=0;i<n+1;i++){
        scanf("%d",&p[i]);
    }
    matrixChain(p,n+1,m,s);
    printf("最优值为:%d\n",m[1][n]);
    printf("最优解为:\n");
    Traceback(1,n,s);
	return 0;
}

测试

测试递归程序:
测试过程:输入矩阵个数3,然后输入矩阵的行和列之后回车,系统输出最优值和最优解。

在这里插入图片描述
测试动态规划程序:
测试过程:输入矩阵个数5,然后输入矩阵的行和列之后回车,系统输出最优值和最优解。
在这里插入图片描述

讨论

根据计算m[ i ][ j ]的递归式,容易写一个递归算法计算m[1][n]。但是简单地递归将耗费指数计算时间。在递归计算时,许多子问题被重复计算多次。这也是该问题可以用动态规划算法求解的又一显著特征。
用动态规划算法解决此问题,可依据其递归是以自底向上的方式进行计算。在计算的过程中,保存已解决的子问题答案。每个子问题只计算一次,而在后面需要时只要简单查一下,从而避免大量的重复计算。

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

LongTermism

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

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

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

打赏作者

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

抵扣说明:

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

余额充值