您的位置:首页 > 其它

动态规划-3.1.2矩阵连乘问题之迭代法(自底向上)

2018-01-09 23:22 375 查看
问题描述:给定n个矩阵{A1,A2,…,An},其中Ai与Ai+1是可乘的,i=1,2…,n-1。如何确定计算矩阵连乘积的计算次序,使得依此次序计算矩阵连乘积需要的数乘次数最少

问题分析:由于矩阵乘法满足结合律,所以计算矩阵的连乘可以有许多不同的计算次序。这种计算次序可以用加括号的方式来确定。

若一个矩阵连乘积的计算次序完全确定,也就是说该连乘积已完全加括号,则可以依此次序反复调用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)。

动态规划法:当解某一问题的直接递归算法所产生的递归树中,相同的子问题反复出现,并且不同子问题的个数又相对较少时,用动态规划算法是有效的。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: