您的位置:首页 > 其它

矩阵连乘问题 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]即可得到最优解的表达。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: