c语言动态求解矩阵连乘积问题

 计算矩阵连乘积

在科学计算中经常要计算矩阵的乘积。矩阵A和B可乘的条件是矩阵A的列数等于矩阵B的行数。若A是一个p×q的矩阵,B是一个q×r的矩阵,则其乘积C=AB是一个p×r的矩阵。由该公式知计算C=AB总共需要pqr次的数乘。其标准计算公式为:

现在的问题是,给定n个矩阵{A1,A2,…,An}。其中Ai与Ai+1是可乘的,i=1,2,…,n-1。要求计算出这n个矩阵的连乘积A1A2…An,最少的乘法次数。

递归公式:

算法参考如下:

 

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];

              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)

{

   if(i==j)

cout<<"A"<<i;

else if (i==j-1)

cout<<"(A"<<i<<"A"<<j<<")";

else

{

cout<<"(";

traceback(i,s[i][j],s);

traceback(s[i][j]+1,j,s);

cout<<")";

}

 }

 

 

 

 

具体代码:

#include<stdio.h>

#define MAX 100

void MatrixChain(int *p,int n,int **m,int **s)

{

int i,j,r;

for(i=0;i<=n;i++)

for(j=0;j<n;j++)

{

if(i==0||j==0)m[i][j]=-1,s[i][j]=-1;

if(j<i)m[i][j]=-1,s[i][j]=-1;

}

for(i=1;i<=n;i++)

m[i][i]=0,s[i][i]=0;

for(r=2;r<=n;r++)

for(i=1;i<=n-r+1;i++)

{

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;

}

}

}

printf("最优值m[][]数组为:\n");

for(i=1;i<=n;i++)

{

for(j=1;j<=n;j++)

if(m[i][j]==-1)printf(" \t");

else printf("%d\t",m[i][j]);

printf("\n");

}

printf("最优解s[][]数组为:\n");

for(i=1;i<=n;i++)

{

for(j=1;j<=n;j++)

{

if(m[i][j]==-1)printf(" \t");

else printf("%d\t",s[i][j]);

}

printf("\n");

}

}

void traceback(int i,int j,int **s)

{

if(i==j)

printf("A%d",i);

else if(i==j-1)

printf("(A%dA%d)",i,j);

else

{

printf("(");

traceback(i,s[i][j],s);

traceback(s[i][j]+1,j,s);

printf(")");

}

 

}

void main()

{

int n,i;

int *p=new int[MAX];

printf("一共有n个矩阵,请输入n的值:");

scanf("%d",&n);

printf("请输入依次n个矩阵的行值和列值(列如2个矩阵30x35,35x15,则输入30 35 15):\n");

for(i=0;i<=n;i++)

scanf("%d",&p[i]);

int **m = new int*[n+1];

for(i= 0; i <=n; i++)

m[i] = new int[n+1];

int **s = new int*[n+1];

for(i= 0; i <=n; i++)

s[i] = new int[n+1];

MatrixChain(p,n,m,s);

traceback(1,n,s);

printf("\n");

}

  • 0
    点赞
  • 9
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
矩阵连乘问题是一个经典的动态规划问题。给定一系列矩阵,我们需要找到一种最优的计算次序,使得计算这些矩阵的乘所需的标量乘法次数最少。 根据引用\[2\]中的分析,最优解具有最优子结构性质,即最优解包含着其子问题的最优解。我们可以通过建立递归关系来解决这个问题。引用\[1\]中的代码展示了如何使用动态规划来解决矩阵连乘问题。 首先,我们定义一个二维数组m\[i\]\[j\]来表示计算矩阵Ai到Aj的最少标量乘法次数。数组s\[i\]\[j\]用来记录最优解的断开位置。 然后,我们使用自底向上的方式计算最优值。从长度为2的矩阵链开始,逐步计算长度为3、4、...、n的矩阵链的最优解。具体的计算过程可以参考引用\[1\]中的代码。 最后,我们可以通过回溯的方式来构造最优解。引用\[1\]中的TrackBack函数展示了如何根据数组s\[i\]\[j\]来构造最优解的断开位置。 综上所述,C语言动态规划矩阵连乘问题可以通过建立递归关系、计算最优值和回溯构造最优解来解决。引用\[1\]中的代码提供了一个实现的示例。 #### 引用[.reference_title] - *1* *2* [动态规划算法---矩阵连乘C语言)](https://blog.csdn.net/weixin_44903715/article/details/101318531)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v91^control,239^v3^insert_chatgpt"}} ] [.reference_item] - *3* [矩阵连乘问题 动态规划 C](https://blog.csdn.net/while_BLUE_/article/details/112431353)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v91^control,239^v3^insert_chatgpt"}} ] [.reference_item] [ .reference_list ]

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值