算法分析 矩阵连乘问题
矩阵连乘问题可以采用动态规划思想进行分解。要采用动态规划思想求解的问题需要满足两个条件:
1、问题需要满足最优子结构 2、子问题具有重叠性
首先,我们定义n个可以连乘的矩阵A1、A2、A3、……An,定义An的维度为p(n-1)p(n)。对于n个可以连乘的矩阵,我们可以将矩阵划分为A1-Ak的连乘S1以及Ak+1-An的连乘S2以及矩阵S1和S2的乘积。当矩阵序列只有一个矩阵时,显然连乘为0。
矩阵连乘动态规划实现:
/**
* @param p 矩阵连乘中各个矩阵维度数组
* @param n 连乘矩阵个数
* @param s 最优矩阵连乘计算次数数组
* @param m 最优矩阵连乘划分位置数组
*/
public void multiplyChain(int[] p,int n,int[][] s,int[][] m){
for(int i=1;i<=n;i++)s[i][i]=0;
//确定矩阵连乘问题的规模 j个矩阵连乘
for(int j=2;j<=n;j++){
//遍历矩阵连乘的开始矩阵
for(int r=1;r<=n-j+1;r++){
//确定矩阵连乘的结束矩阵
int l=r+j-1;
s[r][l]=s[r+1][l]+p[r-1]*p[r]*p[l];
for(int k=r+1;k<l;k++){
//从第k个矩阵开始划分
int value = +p[r-1]*p[k]*p[l];
if(value<s[r][l]) s[r][l]=value;
}
}
}
}
矩阵连乘的备忘录方法(自顶向下):
/**
* 返回n个连乘矩阵最优计算次数
* @param n 连乘矩阵个数
* @param m 连乘矩阵最优计算次数数组
* @param p 矩阵维度数组
* @return
*/
public int memorizedMatrixChain(int n,int[][] m,int[] p){
//将矩阵最优次数全部设置为0 做备忘录
for(int i=1;i<=n;i++)
for(int j=1;j<=n;j++)
m[i][j]=0;
return lookUpChain(1,n,m,p);
}
/**
* 递归调用 返回矩阵a到矩阵b的最优计算次数
* @param a 连乘开始范围
* @param b 连乘结束范围
* @param m 最优计算次数数组
* @param p 矩阵维度数组
* @return
*/
public int lookUpChain(int a,int b,int[][] m,int[] p){
//已经计算出了最优次数就不再进行计算
if(m[a][b]>0)return m[a][b];
if(a==b)return 0;
//递归计算其它划分情况下的最优次数
m[a][b]= lookUpChain(a+1,b,m,p)+p[a-1]*p[a]*p[b];
for(int i=a+1;i<b;i++){
int value = lookUpChain(a,i,m,p)+lookUpChain(i+1,b,m,p)+p[a-1]*p[i]*p[b];
if(value<m[a][b]) m[a][b]=value;
}
return m[a][b];
}