动态规划解矩阵连乘
动态规划的基本要素
1:最有子结构
2:重叠子问题
动态规划适用于解最优化问题,通常有四个步骤
(1) 找出最优解的性质,并刻画其结构性质。
(2) 递归的定义最优质
(3) 以自底向上的方式计算出最优质
(4) 根据计算最优质时得到的信息,构造最优解
我们以矩阵连乘为例。
{A1,A2,...An}Ai与Ai+1是可乘的。
矩阵乘法满足结合律,所以可以有很多不同的计算次序,可以用加括号的方式确定每一种计算次序,我们的目的是找出最有计算次序。
很明显所有的计算次序是一个Catalan数呈指数增长,穷举算法不是一个有效算法
下面用动态规划解矩阵连乘的最有计算次序问题
我们用A[i:j]表示Ai到Aj的计算次许,则我们的目的是求A[1:n]
设矩阵在Ak和Ak+1处断开,则先计算Ak和Ak+1然后将计算结果相乘得到A[1:n]用反证法可是证明当A[1:n]的计算次序是最优的其所包含的矩阵子链的计算次序也是最优的。
(2)建立递归关系
A[i:j],1<=i<=j<=n,所需要的最少数乘次数为m[i][j]我们可以得出一下递归关系
m[i][j] = 0 when i= j;
m[i][j] = m[i][k] + m[k+1][j] + pi-1*pk*pj; when i<j;
(3)计算最优值
根据m[i][j]的递归式我们很容易写一个递归算法m[1][n]这里不再赘述。
(4)下面是书上的计算次序图
上传不了图片
下面是我实现这个算法的代码
package martixchain; import java.io.Reader; import java.util.Scanner; import javax.security.auth.kerberos.KerberosKey; import org.omg.CORBA.PUBLIC_MEMBER; /*-------------------------------------------------------------- * Author: DingWenchao * Writtern: Dec 3,2014 * * martixchain *to produce the optimal array->the optimal computing orders *example:matrix[30,35,15,5,10,20,25]-> matrix 30 35 5 10 20 25 *to produce: 15125 ((A1(A2A3))((A4A5)A6)) * *Tests: matrix[30,35,15,5,10,20,25] *expected is : 15125 ((A1(A2A3))((A4A5)A6)) * -------------------------------------------------------------*/ public class Martix_chain{ public static void main(String args[]){ System.out.println("Enter the number of martix"); Scanner reader = new Scanner(System.in); int n = reader.nextInt(); int []p = new int[n+1]; System.out.println("Enter ther a array of number " + "for eample 30 35 15 5 10 20 25 stand for six martixs 30*35,35*15,15*5,5*10,10*20,20*25 "); for(int i = 0;i <= n;i++){ p[i] = reader.nextInt(); } reader.close(); martix mx = new martix(n, p); int[][]s = mx.martixChain(); for(int i = 1;i<=n;i++){ for(int j = 1;j<=n;j++){ System.out.println(s[i][j]); } } mx.traceback(1, n); } } class martix{ int n; //the number of martix. int[]p; //the array of martix. int[][]m; //to save each of int[][]s;//to save k martix(int n,int[]p){//construct function this.n = n; this.p = p; this.m = new int[n+1][n+1]; this.s = new int[n+1][n+1]; } int[][] martixChain(){ for(int i = 1;i <= n;i++)m[i][i] = 0; for(int r = 2;r <= n;r++)//diagonal cycle for(int i = 1;i <= n-r+1;i++){// int j = i + r - 1; m[i][j] = m[i][i] + m[i+1][j] + p[i-1]*p[i]*p[j]; s[i][j] = i; 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; } } } return s; } void traceback(int i,int j){ if(i == j) return; traceback(i,s[i][j]); traceback(s[i][j]+1,j ); System.out.println("Multiplay A" + i + "," + s[i][j] + "and A" + (s[i][j]+1)+"," + j); } }