算法 矩阵连乘 递归+动态规划+备忘录
2016-12-29 19:11
197 查看
题目
给定n个矩阵,其中两个相邻的矩阵是可乘的,试求出最佳计算次序,使得总计算量最少。例如:
A1[30X35]
A2[35X15]
A3[15X5]
A4[5X10]
A5[10X20]
A6[20X25]
分析
m[1]=m[1][k] + m[k+1]
+p0pkpn
代码
1、递归算法#include <stdio.h> #define N 6 int m[N+1][N+1];//最小乘法次数 int p[N+1]={30,35,15,5,10,20,25};//第1、2、3、4、5、6个矩阵行数,第6个矩阵列数. int digui(int i, int j) { int minvalue =10000000, temp; if(i==j) return 0; for(int k=i; k<j; k++){ temp=digui(i,k) + digui(k+1,j) + p[i-1]*p[k]*p[j]; if(temp<minvalue) { minvalue=temp; m[i][j]=k; } } return minvalue; } void traceback(int i,int j) { if (i==j)return; traceback(i,m[i][j]); traceback(m[i][j]+1,j); printf("A[%d-%d] and A[%d-%d]\n", i,m[i][j],m[i][j]+1,j); return; } int main(){ printf("%d\n",digui(1,N)); traceback(1,N); return 0; }
2、动态规划
#include <stdio.h> #define N 6 int m[N+1][N+1];//m是最优值 int s[N+1][N+1];//s是最优值的断开点的索引 int p[N+1]={30,35,15,5,10,20,25}; void traceback(int i,int j){ if(i==j) return; traceback(i,s[i][j]); traceback(s[i][j]+1,j); printf("A[%d][%d] and A[%d][%d]\n", i,s[i][j],s[i][j]+1,j); } void dongtai() { int i,j,k,r; for(i=1;i<=N;i++)//单一矩阵的最小乘次都置为0 m[i][i]=0; for(r=2;r<=N;r++){//r为连乘矩阵的个数 for(i=1;i<=N+1-r;i++){ //i表示连乘矩阵中的第一个 j=i+r-1; //j表示连乘矩阵中的最后一个 //所以,这两层循环是起始为Ai,结尾为Aj,长度为r的矩阵段Ai~Aj m[i][j]=m[i+1][j]+p[i-1]*p[i]*p[j]; s[i][j]=i;//记录断开点的索引 for(k=i+1;k<j;k++){ //循环求出Ai~Aj中的最小数乘次数 //在第一个与最后一个之间寻找最合适的断开点, //注意,应该从i开始,但是上面已经记录了i。 int temp=m[i][k]+m[k+1][j]+p[i-1]*p[k]*p[j]; if(temp<m[i][j]){ m[i][j]=temp; s[i][j]=k; } } } } } int main(){ dongtai(); printf("%d\n",m[1] ); traceback(1,N); return 0; }
3、备忘录
#include <stdio.h> #define N 6 int m[N+1][N+1];//最优解 int s[N+1][N+1]; int p[N+1]= {30,35,15,5,10,20,25}; void traceback(int i,int j){ if(i==j) return; traceback(i,s[i][j]); traceback(s[i][j]+1,j); printf("A[%d][%d] and A[%d][%d]\n", i,s[i][j],s[i][j]+1,j); } int beiwanglu(int i, int j) { if(m[i][j]>0) return m[i][j]; if(i==j) return 0; int u=beiwanglu(i,i)+beiwanglu(i+1,j)+p[i-1]*p[i]*p[j]; s[i][j]=i; for(int k=i+1; k<j; k++) { int temp=beiwanglu(i,k)+beiwanglu(k+1,j)+p[i-1]*p[k]*p[j]; if(temp<u){ u=temp; s[i][j]=k; } } m[i][j]=u; return u; } int f(int n){ int i,j; for(i=1; i<=n; i++) for(j=i; j<=n; j++) m[i][j]=0; return beiwanglu(1,n); } int main() { printf("%d\n",f(N)); traceback(1,N); return 0; }
相关文章推荐
- 算法分析与设计——矩阵连乘问题
- (基于Java)算法之动态规划——矩阵连乘问题
- (基于Java)算法之动态规划——矩阵连乘问题
- 算法笔记 //13_矩阵连乘问题
- 算法[动态规划]-矩阵连乘问题
- 算法重拾之路——矩阵连乘问题
- 算法动态规划问题之矩阵连乘
- 动态规划经典算法之矩阵连乘问题源代码
- 算法之矩阵连乘
- 【编程素质】算法-矩阵连乘问题(枚举法、备忘录法、动态规划)
- 0010算法笔记——【动态规划】矩阵连乘问题
- 【计算机算法分析】动态规划法——矩阵连乘问题
- 动态规划——矩阵连乘(算法设计课题)
- 算法设计与分析--矩阵连乘顺序问题…
- 算法分析与设计矩阵连乘问题
- 算法复习___二分_矩阵连乘
- 矩阵连乘算法思想
- 矩阵连乘-动态规划-(只是感觉描述的清晰易懂,并不是什么新算法)
- 《数据结构与算法分析:C语言描述》复习——第十章“算法设计技巧”——矩阵连乘问题
- 递推式优化算法之矩阵连乘