矩阵连乘问题(动态规划)
来源:互联网 发布:水利工程用什么软件 编辑:程序博客网 时间:2024/05/17 09:02
计算三个矩阵连乘{A1,A2,A3},维数分别为10*100 , 100*5 , 5*50
按此顺序计算需要的次数((A1*A2)*A3):10X100X5+10X5X50=7500次
按此顺序计算需要的次数(A1*(A2*A3)):10X5X50+10X100X50=75000次
所以问题是:如何确定运算顺序,可以使计算量达到最小化。枚举显然不可,如果枚举的话,相当于一个“完全加括号问题”,次数为卡特兰数,卡特兰数指数增长,必然不行。
子问题状态的建模(很关键):
将AiAi+1...Aj简记为A[i:j],(0<=i<=j<=n-1),所需的最少数乘次数为m[i][j],则原问题的最优值为m[0][n-1]
显然如果i=j,则m[i][j]这段中就一个矩阵,需要计算的次数为0;
如果i>j,则m[i][j]=min{m[i][k]+m[k+1][j]+p[i-1]Xp[k]Xp[j]},其中k,在i与j之间游荡,所以i<=k<j ;
辅助数组s来记录计算m[i][j]时取得最优代价处的k的值。
m和s数组的计算顺序如图所示(只用到上三角矩阵):
#include<iostream>#include<iomanip>#define SIZE 6 //控制参与连乘矩阵的个数using namespace std;/** 数组m记录最少数乘次数,s记录断开的位置k * AiAi+1...Aj简记为A[i:j],(0<=i<=j<=n-1),所需的最少数乘次数为m[i][j],则原问题的最优值为m[0][n-1] */int m[SIZE][SIZE],s[SIZE][SIZE];void MatrixChain(int p[],int n){for(int i=0;i<n;i++)//i=j时为单一矩阵,即矩阵链长度为1,无需计算m[i][i]=0; for(int l=2;l<=n;l++)//l为矩阵链长度,从2开始循环 {for(int i=0;i<n-l+1;i++)//l长度的矩阵链的第一个矩阵, 即A[i:j]中的i {int j=i+l-1;//根据当前的长度算出矩阵链的最后一个矩阵m[i][j]=m[i+1][j]+p[i]*p[i+1]*p[j+1];s[i][j]=i+1;for(int k=i+1;k<j;k++)//遍历所有断开位置k{int min=m[i][k]+m[k+1][j]+p[i]*p[k+1]*p[j+1];//寻找最小值 if(min<m[i][j]) {m[i][j]=min;s[i][j]=k+1;}}} }}void Traceback(int i,int j) //找出s数组中记录的最优断开点{if(i==j)cout<<"A"<<i+1;else{cout<<"(";Traceback(i,s[i][j]-1);Traceback(s[i][j],j);cout<<")";}}int main(){system("title 矩阵连乘问题");int p[SIZE+1]={30,35,15,5,10,20,25}; //p记录矩阵的行列数MatrixChain(p,SIZE);cout<<"输出m矩阵为:"<<endl;for(int i=0;i<SIZE;i++){for(int j=0;j<SIZE;j++){cout<<setw(5)<<m[i][j]<<" ";}cout<<endl;}cout<<endl<<endl;cout<<"输出s矩阵为:"<<endl;for(int i=0;i<SIZE;i++){for(int j=0;j<SIZE;j++){cout<<setw(5)<<s[i][j]<<" ";}cout<<endl;}cout<<"\n矩阵连乘加括号方式为:";Traceback(0,SIZE-1);return 0;}
参考 http://www.cnblogs.com/liushang0419/archive/2011/04/27/2030970.html
参考《算法导论》 P197-201
- 动态规划 - 矩阵连乘问题
- 矩阵连乘问题(动态规划)
- 动态规划--矩阵连乘问题
- 动态规划之矩阵连乘问题
- 动态规划之矩阵连乘问题
- 【动态规划】矩阵连乘问题
- 动态规划:矩阵连乘问题
- 动态规划5-矩阵连乘问题
- 动态规划5-矩阵连乘问题
- 动态规划:矩阵连乘问题
- 动态规划之矩阵连乘问题
- 矩阵连乘问题(动态规划)
- 动态规划之矩阵连乘问题
- 动态规划 之 矩阵连乘问题
- 动态规划 矩阵连乘问题
- 动态规划---矩阵连乘问题
- 动态规划—矩阵连乘问题
- 动态规划 矩阵连乘问题
- 大流量网站的底层系统架构
- Caused by: java.lang.AbstractMethodError: oracle.jdbc.driver.OracleDatabaseMetaData.locatorsUpdateCo
- DataFlash 驱动代码小议
- 帝都一年
- 零值比较(bool,int,float,指针变量与零值比较的if语句
- 矩阵连乘问题(动态规划)
- Linux下sqlplus不能使用光标箭头解决方法
- STM32之CAN---配置波特率
- Windows RT开放桌面API或能快速获得开发者的支持
- 自己在CODING过程中遇到的问题以及解决(C/VC)
- 提高SQL查询效率
- 程序员之路——一个老程序员对刚上大学的学弟学妹的忠告
- An AES (Rijndael) Implementation in C/C++ (as specified in FIPS-197)
- Round-robin tournament