JAVA實現矩陣連乘

3、實驗二矩陣連乘

實驗內容

n個矩陣連乘,不滿足交換律,但是滿足結合律,通過不同的加括號方式,會使得需要的乘法次數不同。用動態規劃方法計算,找出最優加括號方式,使總的乘法次數最少。

解題思路

將矩陣連乘積Ai Ai +1 … Aj簡記爲A[i:j],這裏i≤j。
考察計算A[i:j]的最優計算次序。設這個計算次序在矩陣Ak和Ak+1之間將矩陣鏈斷開,i≤k<j,則其相應完全加括號方式爲(Ai Ai +1…Ak)(Ak+1 Ak+2… Aj)。
計算量:A[i:k]的計算量加上A[k+1:j]的計算量,再加上A[i:k]和A[k+1:j]相乘的計算量。

源代碼

package b矩陣連乘;

public class MatrixText {
	public static void main(String agrs[]) {
		int[] p = { 30, 35, 15, 5, 10, 20, 25 };
//		int[] p = { 30,15,5,20,3 };
		int n = p.length;
		System.out.print("您輸入的矩陣爲:");
		for (int i = 0; i < n - 1; i++) {
			System.out.print("A" + (i + 1) + "[" + p[i] + "]" + "[" + p[i + 1] + "]" + "  ");
		}
		System.out.println("\n");
		int[][] m = new int[n][n];
		int[][] s = new int[n][n];
		Utils.matrixChain(p, m, s);
		// 打印m矩陣
		System.out.println("The m["+(n-1)+"]["+(n-1)+"] 矩陣:");
		for (int i = 1; i < m.length; i++) {
			for (int j = 1; j < m.length; j++) {
				if (i > j) {
					System.out.print("0" + "\t");
				} else {
					System.out.print(m[i][j] + "\t");
				}
			}
			System.out.println();
		}
		System.out.println();
		// 打印s矩陣
		System.out.println("The s["+(n-1)+"]["+(n-1)+"] 矩陣:");
		for (int i = 1; i < s.length; i++) {
			for (int j = 1; j < s.length; j++) {
				if (i > j) {
					System.out.print("0" + "\t");
				} else {
					System.out.print(s[i][j] + "\t");
				}
			}
			System.out.println();
		}
		System.out.println();
		System.out.println("矩陣連乘加括號方式爲:");
		Utils.OptimalParens(s, 1, n - 1);

	}

}

package b矩陣連乘;

public class Utils {

	/**
	 * @see 計算最優值
	 * @param p:各個矩陣的下標
	 * @param m:最優解矩陣
	 * @param s:最優解矩陣所取得k值的矩陣
	 */
	public static void matrixChain(int[] p, int[][] m, int[][] s) {
		int n = p.length - 1;// 求出矩陣的個數
		// 給m矩陣主對角線賦值爲0
		for (int i = 1; i <= n; i++) {
			m[i][i] = 0;
		}
		for (int r = 2; r <= n; r++)
			for (int i = 1; i <= n - r + 1; i++) {
				int j = i + r - 1;
				// 給矩陣設置一個超大值,爲後面的比較做準備
				m[i][j] = 999999999;
				for (int k = i; 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和s矩陣賦值
						m[i][j] = t;
						s[i][j] = k;
					}
				}
			}
	}

	/**
	 * @see 打印加括號的最優解方案
	 * @param s:最優解矩陣所取得k值的矩陣
	 * @param i:矩陣的第一個A1
	 * @param j:矩陣的最後一個A(n-1)
	 */
	public static void OptimalParens(int[][] s, int i, int j) {
		if (i == j) {
			System.out.print("A" + i);
		} else if (i + 1 == j) {
			System.out.print(" (A" + i + " A" + j + ") ");
		} else {
			System.out.print(" (");
			// 遞歸調用
			OptimalParens(s, i, s[i][j]);
			OptimalParens(s, s[i][j] + 1, j);
			System.out.print(") ");
		}
	}

}

運行截圖

在這裏插入圖片描述

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章