矩阵连乘问题 DP
2016-06-13 15:25
531 查看
问题描述:
给定n个矩阵{A1,A2,...,An},其中Ai与Ai+1是可乘的,i=1,2,....,n-1.考查这n个矩阵的连乘积A1A2A3....An。由于矩阵乘法满足结合律,故计算矩阵的连乘积可以有许多不同的计算次序。这种计算次序可以用加括号的方式来确定。若一个矩阵连乘积的计算次序完全确定,也就是说该连乘积已完全加括号,则可以依次次序反复调用2个矩阵相乘的标准法计算出矩阵连乘积。
问题分析:
1.分析最优解的结构
矩阵连乘积的计算次序问题的最优解包含着子问题的最优解。最优子性质是动态规划算法求解的显著特征。
2.建立递归关系(动态规划算法的主要内容)
设计动态规划算法的第二步是递归地定义最优值。设计算A[ i , j ],1<=i<=j<=n,所需要的最少数乘次数为m[ i ] [ j ],则原问题的最优值为m[ 1 ][ n ]。
当 i=j 时,A[i][j]=Ai,为单一矩阵,无需计算,因此,m[i][i]=0,i=1,2,3,4,...,n.
当i<j时,利用最优子结构性质计算m[i][j]。
m[i][j]的递归定义如下:
|- 0 i=j
m[i][j]= |-
|- min{ m[i][k]+m[k+1][j]+pi-1xpkxpj} i<j k是最优次序中的断开位置,对应m[ i ] [ j ]的断开位置 记为s[ i ] [j]。m[i][j]给出了最优值,即最少计算次数。
i<=k<j
3.计算最优值
由m[i][j]的递归式,很容易写出一个递归算法计算m[1]
。在递归计算事,很多子问题被重复计算多次,这也是该问题可用动态规划算法求解的又一显著特征。用动态规划算法解此问题时,可以根据其递归式以自底向上的方式进行计算。在计算过程中,保存已解决的子问题答案。每个子问题只计算一次,而在后面需要时只要简单的查一下,从而避免了大量的重复计算,最终得到多项式时间的算法。
动态规划问题的关键是:先构造最小子问题的最优解,然后利用最小子问题的最优解解决次小子问题的最优解,然后用次小子问题的最优解解决次次小子问题的最优解。。。。一直到解决原问题的解。
是一种自底向上的方法。
public static void matrixChain(int[] p,int [][] m,int [][]s)//p为输入参数,矩阵Ai的维数为pi-1xpi,i=1,2,3,...,n
//m记录最优解,s记录断开位置。
{
int n=p.length-1;
for(int i=1;i<=n;i++)m[i][i]=0; //当i=j时的结果
for(int r=2;r<=n;r++) //依次计算出m[i][i+1],i=1,2,3,...,n-1
for(int i=1;i<=n-r+1;i++){ // m[i][i+2],i=1,2,3,...,n-2
// 然后利用最小子问题的解去解决更大子问题的解,例如:求m[i][i+2]时用到么m[i][i+1]
int j=i+r-1;
m[i][j]=m[i+1][j]+p[i-1]*p[i]*p[j];
s[i][j]=i; //先将断开位置初始化为i,然后利用下面for循环去寻找更优的断开位置。
for(int k=i+1;k<j;k++){
int t=m[i][k]+m[k+1][j]+p[i-1]*p[k]*p[i];
if(t<m[i][j]{
m[i][j]=t;
s[i][j]=k;
}
}
}
}
4.构造最优解。
public static void tarceback(int[][]s,int i,int j)
{
if(i==j)return; //递归的结束即递归的返回点
traceback(s,i,s[i][j]);
traceback(s,s[i][j],j);
System.out.println("MultiplyA"+i+","+s[i][j]+"AndA"+(s[i][j]+1)+","+j);
}
要输出A[1:n]的最优计算次序只要调用上面的traceback(1,n,s)即可。
总结:
1.注意动态规划算法的使用条件,解决问题时要分析该问题是否适合用动态规划算法求解。
最优子结构,即原问题的最优解也是其任意子问题的最优解。
2.动态规划算法的核心。
找到解决该问题的递归关系式,然后由下到上,依次解决子问题的解。
3.要注意设变量记录。
本例中,m[i][j]记录Ai....Aj的最优解,s[i][j]记录Ai....Aj的断开位置,然后通过递归遍历s[i][j]即可得到最优解的表达。
给定n个矩阵{A1,A2,...,An},其中Ai与Ai+1是可乘的,i=1,2,....,n-1.考查这n个矩阵的连乘积A1A2A3....An。由于矩阵乘法满足结合律,故计算矩阵的连乘积可以有许多不同的计算次序。这种计算次序可以用加括号的方式来确定。若一个矩阵连乘积的计算次序完全确定,也就是说该连乘积已完全加括号,则可以依次次序反复调用2个矩阵相乘的标准法计算出矩阵连乘积。
问题分析:
1.分析最优解的结构
矩阵连乘积的计算次序问题的最优解包含着子问题的最优解。最优子性质是动态规划算法求解的显著特征。
2.建立递归关系(动态规划算法的主要内容)
设计动态规划算法的第二步是递归地定义最优值。设计算A[ i , j ],1<=i<=j<=n,所需要的最少数乘次数为m[ i ] [ j ],则原问题的最优值为m[ 1 ][ n ]。
当 i=j 时,A[i][j]=Ai,为单一矩阵,无需计算,因此,m[i][i]=0,i=1,2,3,4,...,n.
当i<j时,利用最优子结构性质计算m[i][j]。
m[i][j]的递归定义如下:
|- 0 i=j
m[i][j]= |-
|- min{ m[i][k]+m[k+1][j]+pi-1xpkxpj} i<j k是最优次序中的断开位置,对应m[ i ] [ j ]的断开位置 记为s[ i ] [j]。m[i][j]给出了最优值,即最少计算次数。
i<=k<j
3.计算最优值
由m[i][j]的递归式,很容易写出一个递归算法计算m[1]
。在递归计算事,很多子问题被重复计算多次,这也是该问题可用动态规划算法求解的又一显著特征。用动态规划算法解此问题时,可以根据其递归式以自底向上的方式进行计算。在计算过程中,保存已解决的子问题答案。每个子问题只计算一次,而在后面需要时只要简单的查一下,从而避免了大量的重复计算,最终得到多项式时间的算法。
动态规划问题的关键是:先构造最小子问题的最优解,然后利用最小子问题的最优解解决次小子问题的最优解,然后用次小子问题的最优解解决次次小子问题的最优解。。。。一直到解决原问题的解。
是一种自底向上的方法。
public static void matrixChain(int[] p,int [][] m,int [][]s)//p为输入参数,矩阵Ai的维数为pi-1xpi,i=1,2,3,...,n
//m记录最优解,s记录断开位置。
{
int n=p.length-1;
for(int i=1;i<=n;i++)m[i][i]=0; //当i=j时的结果
for(int r=2;r<=n;r++) //依次计算出m[i][i+1],i=1,2,3,...,n-1
for(int i=1;i<=n-r+1;i++){ // m[i][i+2],i=1,2,3,...,n-2
// 然后利用最小子问题的解去解决更大子问题的解,例如:求m[i][i+2]时用到么m[i][i+1]
int j=i+r-1;
m[i][j]=m[i+1][j]+p[i-1]*p[i]*p[j];
s[i][j]=i; //先将断开位置初始化为i,然后利用下面for循环去寻找更优的断开位置。
for(int k=i+1;k<j;k++){
int t=m[i][k]+m[k+1][j]+p[i-1]*p[k]*p[i];
if(t<m[i][j]{
m[i][j]=t;
s[i][j]=k;
}
}
}
}
4.构造最优解。
public static void tarceback(int[][]s,int i,int j)
{
if(i==j)return; //递归的结束即递归的返回点
traceback(s,i,s[i][j]);
traceback(s,s[i][j],j);
System.out.println("MultiplyA"+i+","+s[i][j]+"AndA"+(s[i][j]+1)+","+j);
}
要输出A[1:n]的最优计算次序只要调用上面的traceback(1,n,s)即可。
总结:
1.注意动态规划算法的使用条件,解决问题时要分析该问题是否适合用动态规划算法求解。
最优子结构,即原问题的最优解也是其任意子问题的最优解。
2.动态规划算法的核心。
找到解决该问题的递归关系式,然后由下到上,依次解决子问题的解。
3.要注意设变量记录。
本例中,m[i][j]记录Ai....Aj的最优解,s[i][j]记录Ai....Aj的断开位置,然后通过递归遍历s[i][j]即可得到最优解的表达。
相关文章推荐
- IT忍者神龟之长连接与长轮询分别如何实现的?各有哪些优势和劣势?
- PAT乙级—1018. 锤子剪刀布 (20)-native
- 使用adb命令对手机进行截屏保存到电脑,SDCard
- Android开发短信发送
- 让XShell保存日志教程
- 面试题10 二进制中1的个数
- 知道这20个正则表达式,能让你少写1,000行代码
- 关于用strtok_s处理过的CString会导致之前的CString之间的赋值被同化的问题的解决方案
- 利用OpenCV的imread将RGB图像转化为灰度图像!
- UIScrollView之Zoom
- C和指针小结(推荐)
- 讯飞语音开发之语音听写--不带ui界面
- java设计模式之一工厂模式(Factory Method)
- java设计模式之一工厂模式(Factory Method)
- java设计模式之一工厂模式(Factory Method)
- java设计模式之一工厂模式(Factory Method)
- java设计模式之一工厂模式(Factory Method)
- java设计模式之一工厂模式(Factory Method)
- java设计模式之一工厂模式(Factory Method)
- java设计模式之一工厂模式(Factory Method)