动态规划之矩阵连乘
2015-04-05 13:51
260 查看
问题介绍:
给定n个矩阵{A1,A2,A3......An},其中Ai与Ai+1是可乘的,i=1,2......n-1.考察n个矩阵连乘积的最小次数,即以最少的计算量来求得最终结果。
矩阵连乘性质分析:
1.假设ra,ca和rb,cb表示矩阵A和B的行数与列数,则AxB=ra*ca*cb,因为相邻连乘的矩阵必有ca=rb
2.同一连乘矩阵由不同连乘顺序,所以计算量不一样,但最终结果是一样
例如:矩阵连乘积A1A2A3A4A5可以有一下五种不同的计算次序
(A1(A2(A3A4))),(A1((A2A3)A4)),((A1A2)(A3A4)),((A1(A2A3))A4),(((A1A2)A3)A4)
现在我们的目的是要找到其中计算量最小的连乘方式,
建立模型分析:
1.将矩阵连乘积AiAi+1......Aj简记为A[i,j]
2.假设计算次序在Ak和Ak+1之间断开,i<=k<j,则先计算A[i,k]和A[k+1,j]然后将计算结果相乘得到A[i,j],故总计算量为A[i,k]的计算量加上A[k+1,j]的计算量,再加上
A[i,k]和A[k+1,j]相乘的计算量。
最优子结构:
假设用m[i][j]表示A[i,j]
1.要得到A[i,j]的最小值,由于i<=k<j,所以我们要找到k的取值令A[i,j]最小时的情况,即
m[i][j]=min{m[i][k]+m[k+1][j]+pi-1*pk*pj} i<=k<j
m[i][j]=0 i=j
同理m[i][k]和m[k+1][j]也取其最优断开处得到的最小值,这样一步步到最后,当i=1,j=n时,由于我们每一步取得都是最小值,那么总体上来说,我们得到的当然也是 最小值。
因此,矩阵连乘的计算次序问题的最优解包含着子问题的最优解,这种性质成为最优子结构性质。
算法分析:
1.对于动态规划算法可以看出,由于前一步的值得到了保存,避免了重复计算。时间复杂度最多为O(n3)
2.对于直接递归算法,由于计算过的值又被重复计算,造成时间复杂度猛增。
T(n)=1+
(T(k)+T(n-k)+1) n>1
可以计算出T(n)>2的n-1次方,立方级的复杂度可想而知了,
3.备忘录法同动态规划法一样,由于保存了其中间值,复杂度从2n降为n3
算法分析:
给定n个矩阵{A1,A2,A3......An},其中Ai与Ai+1是可乘的,i=1,2......n-1.考察n个矩阵连乘积的最小次数,即以最少的计算量来求得最终结果。
矩阵连乘性质分析:
1.假设ra,ca和rb,cb表示矩阵A和B的行数与列数,则AxB=ra*ca*cb,因为相邻连乘的矩阵必有ca=rb
2.同一连乘矩阵由不同连乘顺序,所以计算量不一样,但最终结果是一样
例如:矩阵连乘积A1A2A3A4A5可以有一下五种不同的计算次序
(A1(A2(A3A4))),(A1((A2A3)A4)),((A1A2)(A3A4)),((A1(A2A3))A4),(((A1A2)A3)A4)
现在我们的目的是要找到其中计算量最小的连乘方式,
建立模型分析:
1.将矩阵连乘积AiAi+1......Aj简记为A[i,j]
2.假设计算次序在Ak和Ak+1之间断开,i<=k<j,则先计算A[i,k]和A[k+1,j]然后将计算结果相乘得到A[i,j],故总计算量为A[i,k]的计算量加上A[k+1,j]的计算量,再加上
A[i,k]和A[k+1,j]相乘的计算量。
最优子结构:
假设用m[i][j]表示A[i,j]
1.要得到A[i,j]的最小值,由于i<=k<j,所以我们要找到k的取值令A[i,j]最小时的情况,即
m[i][j]=min{m[i][k]+m[k+1][j]+pi-1*pk*pj} i<=k<j
m[i][j]=0 i=j
同理m[i][k]和m[k+1][j]也取其最优断开处得到的最小值,这样一步步到最后,当i=1,j=n时,由于我们每一步取得都是最小值,那么总体上来说,我们得到的当然也是 最小值。
因此,矩阵连乘的计算次序问题的最优解包含着子问题的最优解,这种性质成为最优子结构性质。
算法分析:
1.对于动态规划算法可以看出,由于前一步的值得到了保存,避免了重复计算。时间复杂度最多为O(n3)
2.对于直接递归算法,由于计算过的值又被重复计算,造成时间复杂度猛增。
T(n)=1+
(T(k)+T(n-k)+1) n>1
可以计算出T(n)>2的n-1次方,立方级的复杂度可想而知了,
3.备忘录法同动态规划法一样,由于保存了其中间值,复杂度从2n降为n3
#include<iostream> using namespace std; #define MAXNUM 20 int p[MAXNUM]; int s[MAXNUM][MAXNUM]; int m[MAXNUM][MAXNUM]; //动态规划法 void MatrixChain(int *p,int n,int m[][MAXNUM],int s[][MAXNUM]) { for(int i=1;i<=n;i++) m[i][i]=0; for(int r=2;r<=n;r++) //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; } } //cout<<"m["<<i<<"]["<<j<<"]"<<m[i][j]<<endl; } } //递归算法直接求解 int RecurMatrix(int i,int j) { if(i==j) return 0; int u=RecurMatrix(i,i)+RecurMatrix(i+1,j)+p[i-1]*p[i]*p[j]; s[i][j]=i; for(int k=i+1;k<j;k++) { int t=RecurMatrix(i,k)+RecurMatrix(k+1,j)+p[i-1]*p[k]*p[j]; if(t<u) { u=t; s[i][j]=k; } } return u; } //备忘录法 int RecurMatrixSave(int i,int j) { if(m[i][j]>0) return m[i][j]; if(i==j) return 0; int u=RecurMatrix(i,i)+RecurMatrix(i+1,j)+p[i-1]*p[i]*p[j]; s[i][j]=i; for(int k=i+1;k<j;k++) { int t=RecurMatrix(i,k)+RecurMatrix(k+1,j)+p[i-1]*p[k]*p[j]; if(t<u) { u=t; s[i][j]=k; } } m[i][j]=u; return u; } void TraceBack(int i,int j,int s[][MAXNUM]) { if(i==j) {cout<<i;return;} cout<<"("; TraceBack(i,s[i][j],s); TraceBack(s[i][j]+1,j,s); cout<<")"; } int main() { int n; while(scanf("%d",&n)!=EOF) { for(int i=0;i<n;i++) { cout<<"请输入第"<<i<<"个维度"<<endl; scanf("%d",&p[i]); } MatrixChain(p,n-1,m,s); TraceBack(1,n-1,s); cout<<endl; RecurMatrixSave(1,n-1); TraceBack(1,n-1,s); cout<<endl; RecurMatrix(1,n-1); TraceBack(1,n-1,s); } return 0; }
算法分析:
相关文章推荐
- 动态规划实例(十):矩阵连乘
- 动态规划—矩阵连乘问题
- 动态规划——矩阵连乘问题
- 动态规划-矩阵连乘问题
- 动态规划问题3-矩阵连乘问题
- 动态规划-3.1.2矩阵连乘问题之迭代法(自底向上)
- 动态规划之矩阵连乘
- 动态规划_矩阵连乘问题
- 动态规划-矩阵连乘问题
- 动态规划经典算法之矩阵连乘问题源代码
- 动态规划_矩阵连乘的空间复杂度优化
- 动态规划5-矩阵连乘问题
- 动态规划--矩阵连乘的最优乘法顺序
- 动态规划之矩阵连乘
- poj 1179 Polygon(动态规划:矩阵连乘加强)
- 动态规划——矩阵连乘的问题
- Go语言动态规划矩阵连乘
- java实现矩阵连乘的动态规划
- 动态规划之矩阵连乘问题
- 动态规划:矩阵连乘问题