动态规划-3.1.2矩阵连乘问题之迭代法(自底向上)
2018-01-09 23:22
375 查看
问题描述:给定n个矩阵{A1,A2,…,An},其中Ai与Ai+1是可乘的,i=1,2…,n-1。如何确定计算矩阵连乘积的计算次序,使得依此次序计算矩阵连乘积需要的数乘次数最少
问题分析:由于矩阵乘法满足结合律,所以计算矩阵的连乘可以有许多不同的计算次序。这种计算次序可以用加括号的方式来确定。
若一个矩阵连乘积的计算次序完全确定,也就是说该连乘积已完全加括号,则可以依此次序反复调用2个矩阵相乘的标准算法计算出矩阵连乘积
(2)建立递归关系
设计算A[i:j],1≤i≤j≤n,所需要的最少数乘次数m[i,j],则原问题的最优值为m[1,n] 。
这里,A[i]的维数为p[i-1]*p[i]。
①当i=j时,A[i,j]=Ai, m[i,j]=0;(表示只有一个矩阵,如A1,没有和其他矩阵相乘,故乘的次数为0)
②当i< j时,m[i,j]=min{m[i,k]+m[k+1,j] +pi-1*pk*pj} ,其中 i <= k< j
(3)计算最优值
(4)构造最优解
2. 依次从链长为[2:n]递增分别计算不同链长的矩阵连乘最优值
3.1 先令m[i][j]最优值为矩阵链首元素划分下的值,后再进行对比
3.2 计算k∈[i+1:j-1]递增划分下最优值,并和之前已保存的最优值对比,取小者
如题所示:
分析结果如下:
举例说明:
程序代码如下:
运行结果:
总结:算法matrixChain的主要计算量取决于算法中对r,i和k的3重循环。循环体内的计算量为O(1),而3重循环的总次数为O(n^3)。因此算法的计算时间上界为O(n^3)。算法所占用的空间显然为O(n2)。
动态规划法:当解某一问题的直接递归算法所产生的递归树中,相同的子问题反复出现,并且不同子问题的个数又相对较少时,用动态规划算法是有效的。
问题分析:由于矩阵乘法满足结合律,所以计算矩阵的连乘可以有许多不同的计算次序。这种计算次序可以用加括号的方式来确定。
若一个矩阵连乘积的计算次序完全确定,也就是说该连乘积已完全加括号,则可以依此次序反复调用2个矩阵相乘的标准算法计算出矩阵连乘积
基于矩阵连乘的动态规划思想步骤
(1)找出最优解的性质,刻画其特征结构(2)建立递归关系
设计算A[i:j],1≤i≤j≤n,所需要的最少数乘次数m[i,j],则原问题的最优值为m[1,n] 。
这里,A[i]的维数为p[i-1]*p[i]。
①当i=j时,A[i,j]=Ai, m[i,j]=0;(表示只有一个矩阵,如A1,没有和其他矩阵相乘,故乘的次数为0)
②当i< j时,m[i,j]=min{m[i,k]+m[k+1,j] +pi-1*pk*pj} ,其中 i <= k< j
(3)计算最优值
(4)构造最优解
基于矩阵连乘的算法实现步骤
1. 先初始化m[i][i]2. 依次从链长为[2:n]递增分别计算不同链长的矩阵连乘最优值
3.1 先令m[i][j]最优值为矩阵链首元素划分下的值,后再进行对比
3.2 计算k∈[i+1:j-1]递增划分下最优值,并和之前已保存的最优值对比,取小者
如题所示:
分析结果如下:
举例说明:
程序代码如下:
public class test3_1_2 { public static void matrixChain(int[] p,int[][] m,int[][] s){ int n = p.length-1; //1.先初始化m[i][i] for(int i=1;i<=n;i++) m[i][i] = 0; //2.依次从链长为[2:n]递增分别计算不同链长的矩阵连乘最优值 for(int r=2;r<=n;r++) for(int i=1;i<=n-(r-1);i++){ //当计算链长为r时,i的取值范围 int j = i+r-1; //每条矩阵链m[i][j] i表示矩阵链首元素下标;j表示矩阵链的尾元素下标 //3.1先令m[i][j]最优值为矩阵链首元素划分下的值,后再进行对比 m[i][j] = m[i+1][j]+p[i-1]*p[i]*p[j]; //完整表达式为m[i][j]=m[i][i]+m[i+1][j]+p[i-1]*p[i]*p[j];因m[i][i]=0故省去,此时的"k"=i s[i][j] = i; //3.2计算k∈[i+1:j-1]递增划分下最优值,并和之前已保存的最优值对比,取小者 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; } } } } public static void traceback(int[][] s,int i,int j){ if(i==j) return; traceback(s,i,s[i][j]); traceback(s,s[i][j]+1,j); System.out.println("(A"+i+"。。。"+"A"+s[i][j]+")(A"+(s[i][j]+1)+"。。。"+"A"+j+")"); } public static void main(String[] args) { int[] p = {30,35,15,5,10,20,25}; int n = p.length; int[][] m = new int ; int[][] s = new int ; matrixChain(p,m,s); System.out.println("矩阵连乘最优值为:"+m[1][n-1]); traceback(s,1,n-1); } }
运行结果:
矩阵连乘最优值为:15125 (A2。。。A2)(A3。。。A3) (A1。。。A1)(A2。。。A3) (A4。。。A4)(A5。。。A5) (A4。。。A5)(A6。。。A6) (A1。。。A3)(A4。。。A6)
总结:算法matrixChain的主要计算量取决于算法中对r,i和k的3重循环。循环体内的计算量为O(1),而3重循环的总次数为O(n^3)。因此算法的计算时间上界为O(n^3)。算法所占用的空间显然为O(n2)。
动态规划法:当解某一问题的直接递归算法所产生的递归树中,相同的子问题反复出现,并且不同子问题的个数又相对较少时,用动态规划算法是有效的。
相关文章推荐