现在的位置: 首页 > 综合 > 正文

动态规划--矩阵连乘问题

2013年08月23日 ⁄ 综合 ⁄ 共 1816字 ⁄ 字号 评论关闭
package dynamicDesign;

class Matr {
	int a;
	int b;

	public Matr(int a, int b) {
		this.a = a;
		this.b = b;
	}
}
public class Matrix {
	public static void main(String args[]) {
		Matr[] matr = { new Matr(3, 2), new Matr(2, 5), new Matr(5, 10),
				new Matr(10, 2), new Matr(2, 3) };
		int[] a = { 3, 2, 5, 10, 2, 3 };
		int s [][] =getBest(a);
		traceBack(1,a.length-1,s);
	}

	public static int[][] getBest(int a[]) {
		int n = a.length - 1;// 取得 矩阵的个数
		int m[][] = new int[a.length][a.length];
		int s[][] = new int[a.length][a.length];
		// 初始化
		for (int i = 0; i < a.length; i++) {
			m[i][i] = 0;
			s[i][i] = 0;
		}
		// 根据矩阵的规模从2个 矩阵到所有矩阵
		for (int r = 2; r <= n; r++) {
			for (int i = 1; i <= n - r + 1; i++) // i 表示规模为 r 的矩阵的开始位置
			{
				int j = i + r - 1;// j 表示 规模为 r 矩阵的结束位置
				m[i][j] = m[i + 1][j] + a[i - 1] * a[i] * a[j];// 求出矩阵a[i][j]// 的最优值
				s[i][j]=i;// 默认为 i 作为最优点								
				// 因为 m[i][j] i到j 的取值不光有 m[i][i]+m[i+1][j],从i
				// 到J的所有位置都有可能,我们要找出来最小的那个
				for (int k = i + 1; k < j; k++)// k<j not =, as for m[i+1]
				{
					int t = m[i][k] + m[k + 1][j] + a[i - 1] * a[k] * a[j];// 从i到j,拆分点在K位置的值
					if (t < m[i][j])// 找使m[i][j]最小的K的位置,这个位置就是i~j 矩阵相乘的最小次数
					{
						m[i][j] = t;
						s[i][j] = k;
					}
				}
			}
		}
		// 打印
		/*for (int i = 1; i < m.length; i++) {
			for (int j = 1; j < m[i].length; j++)
				System.out.print(m[i][j]+ " ");
			System.out.println();
		}*/
		return s;
	}
	public static void traceBack(int i,int j,int s[][])
	{
		if(i==j)return ;// i == j 表示 第I个矩阵和第J个矩阵,也就是指同一个矩阵
		traceBack(i,s[i][j],s);// i~j 的最优解是s[i][j],再利用相同的方法找出 i ~ s[i][j]
		traceBack(s[i][j]+1,j,s);// 同样,找出 s[i][j]+1 
		System.out.println("A["+i+":"+s[i][j]+"]乘以A["+(s[i][j]+1)+":"+j+"]");
	}
	
	
	
}


/*
 * 		矩阵连乘问题
 * 			  |- 0												i == j
 * 	 m[i][j ]= 
 * 			  |- min(n[i][k]+ m[k+1][j]+a[i-1]*a[k]*a[j])		i <  j
 * 
 * 	思路:
 * 	1. 确定合适的数据结构,用 m[i][j] 表示子问题最优值,s[i][j] 子问题最优决策
 * 					m[i][j]= k 表示矩阵 i ~ j 最少乘法次数为K,s[i][j] 表示 取得最少乘法的最优点位置 
 *  2. 初始化,m[i][i] = 0; s[i][i] = 0;
 *  3. 因为我们在求多个数组的最优解的时候会用到小个数组的最优解,这也是动态规划 的特点,所以我们先求出
 *  		小规模的数组的最优解,保存起来,然后再求大规模的数组的最优解
 *  		如,我们要求m[1][3] 的最优解,我们可以把它拆成m[1][1]~ m[2][3],还可以拆成m[1][2] ~ m[2][3]
 *  			可见,只要我们先把所有小规模的问题解决了,大规模的也就随着解决了
 *  4. 有了上面的分析,我们就成规模为2开始,一直到规模是整个所愿有的矩阵	
 *  	for(r=2;r<a.length;r++) 表示了所有的规模 
 *  		for(i=0;i<= n - r + 1;i++) 表示了所有的规模为 R 的范围
 *  		{
 *  			然后根据当前的  i~j 又有多种拆分方式,所以有下面的循环,求最优的点
 *  				for (int k = i + 1; k < j; k++)
 *  		}
 */

 

抱歉!评论已关闭.