矩阵连乘问题

问题描述:

 给定 n 个矩阵 {A1,A2,...,An}, 其中 Ai Ai+1 是可乘的(i=1,2,...,n-1)。考察这 n 个矩阵的连乘积 A1A2···A,记录最优值和最优断点位置。

备注:

 

  •   编程语言:c++
  •   编译器:Code::Blocks 16.01
  •   操作系统:windows 10

 

源代码:

  1 //矩阵连乘问题
  2 /*测试数据
  3 6
  4 30 35 15 5 10 20 25
  5 */
  6 
  7 #include<iostream>
  8 #include <limits.h>  //极限值头文件,INT_MAX无穷大,INT_MIN无穷小
  9 
 10 using namespace std;
 11 
 12 int MatrixChain(int *p,int n,int **m,int **s)
 13 {
 14     int i,l,j,k,t;
 15     for(int i=1;i<=n;i++)
 16     {
 17         m[i][i]=0;             //单一矩阵的情况  一个矩阵数乘次数为0
 18         s[i][i]=0;
 19     }
 20     for(l=2;l<=n;l++)    //相乘矩阵的区间(l:相乘矩阵个数)   l为段长
 21     {
 22         for(i=1;i<=n-l+1;i++)
 23         {
 24             j=i+l-1;
 25 
 26             if(m[i][j] != -1)  //算法优化--备忘录法,避免子问题重叠导致的重复运算
 27                 return m[i][j];
 28             else
 29             {
 30                 m[i][j]=INT_MAX;  //INT_MAX(无穷大)
 31                 for(k=i;k<=j-1;k++)     //改变断点,试探出最小的情况
 32                 {
 33                     t=m[i][k]+m[k+1][j]+p[i-1]*p[k]*p[j];
 34                     if(t<m[i][j])
 35                     {
 36                         m[i][j] = t;
 37                         s[i][j] = k;     //记录断点位置  分点归左
 38                     }
 39                 }
 40             }
 41         }
 42     }
 43     return 0;
 44 }
 45 
 46 int PrintSolution(int i,int j,int **sss)  //输出最优计算次序
 47 {
 48     if(i == j)
 49         cout<<"A"<<i;
 50     else
 51     {
 52         cout<<"(";
 53         PrintSolution(i,sss[i][j],sss);  //分点归左
 54         PrintSolution(sss[i][j]+1,j,sss);
 55         cout<<")";
 56     }
 57     return 0;
 58 }
 59 
 60 int main ()
 61 {
 62     int num;
 63     int *dimension;
 64     int **mm;
 65     int **ss;
 66     cin>>num;    //相乘矩阵个数
 67 
 68     dimension=new int[num+1];     //矩阵维数
 69 
 70     //创建动态二维数组
 71     mm=new int*[num+1];
 72     ss=new int*[num+1];
 73     for(int i=0;i<num+1;i++)
 74     {
 75         mm[i]=new int[num+1];
 76         ss[i]=new int[num+1];
 77     }
 78 
 79     //赋初值
 80     for(int j=0;j<num+1;j++)
 81     {
 82         for(int k=0;k<num+1;k++)
 83         {
 84             mm[j][k]=-1;
 85             ss[j][k]=-1;
 86         }
 87     }
 88 
 89     //输入数据
 90     for(int r=0;r<=num;r++)
 91         cin>>dimension[r];
 92 
 93     MatrixChain(dimension,num,mm,ss);
 94 
 95     for(int j=1;j<=num;j++)  //记录最优值
 96     {
 97         for(int k=1;k<=num;k++)
 98             cout<<mm[j][k]<<"\t";
 99         cout<<endl;
100     }
101     cout<<endl;
102 
103     for(int j=1;j<=num;j++)  //记录最优断点位置
104     {
105         for(int k=1;k<=num;k++)
106             cout<<ss[j][k]<<"\t";
107         cout<<endl;
108     }
109 
110     cout<<endl;
111     PrintSolution(1,num,ss);  //输出最优计算次序
112     cout<<endl;
113 
114     //释放空间
115     delete[] dimension;
116 
117     for(int i=0;i<num+1;i++)
118     {
119         delete[] mm[i];
120         delete[] ss[i];
121     }
122     delete[] mm;
123     delete[] ss;
124     return 0;
125 }

 

运行界面:
 

转载于:https://www.cnblogs.com/BATcaesar-mmm/p/BATcaesar.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值