動態規劃——矩陣連乘積
實驗目的:
- 理解動態規劃演算法的基本思想
- 運用動態規劃演算法解決實際問題
實驗內容:
- 程式設計矩陣A1A2A3A4A5的連乘積,並給出最優的計算次序,其中各矩陣維數分別為:
A1(20*30),A2(30*20),A3(20*15),A4(15*20),A5(20*10)
實驗步驟:
package com.shiyan.org;
public class Matrix {
void MatrixChain(int[] p, int n, int[][] m, int[][] s) {
for (int i = 1; i <= n; i++) {
m[i][i] = 0;
}
for (int r = 2; r <= n; r++) {//r為當前計算的鏈長(子問題規模)
for (int i = 1; i <= n - r + 1; i++) {//n-r+1為最後一個r鏈的前邊界
int j = i + r - 1;//計算前邊界為r,鏈長為r的鏈的後邊界
m[i][j] = m[i + 1][j] + p[i - 1] * p[i] * p[j];//將鏈ij劃分為A(i) * ( A[i+1:j] )
s[i][j] = i;
for (int k = i + 1; k < j; k++) {
//將鏈ij劃分為( A[i:k] )* (A[k+1:j])
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;
}
}
}
}
}
//構造最優解
void Traceback(int i, int j, int[][] s) {
if (i == j) {
return;
}
Traceback(i, s[i][j], s);
Traceback(s[i][j] + 1, j, s);
System.out.println("Multiply A " + i + "," + s[i][j]);
System.out.println("and A " + (s[i][j] + 1) + "," + j);
}
public static void main(String[] args) {
Matrix mc = new Matrix();
int n = 7;
int p[] = { 30, 35, 15, 5, 10, 20, 25 };
int m[][] = new int[n][n];
int s[][] = new int[n][n];
int l = p.length - 1;
mc.MatrixChain(p, l, m, s);
for (int i = 1; i < n; i++) {
for (int j = 1; j < n; j++) {
System.out.print(m[i][j] + "\t");
}
System.out.println();
}
System.out.println();
for (int i = 1; i < n; i++) {
for (int j = 1; j < n; j++) {
System.out.print(s[i][j] + " ");
}
System.out.println();
}
mc.Traceback(1, 6, s);
}
}
實驗結果:
0 15750 7875 9375 11875 15125
0 0 2625 4375 7125 10500
0 0 0 750 2500 5375
0 0 0 0 1000 3500
0 0 0 0 0 5000
0 0 0 0 0 0
0 1 1 3 3 3
0 0 2 3 3 3
0 0 0 3 3 3
0 0 0 0 4 5
0 0 0 0 0 5
0 0 0 0 0 0
Multiply A 2,2
and A 3,3
Multiply A 1,1
and A 2,3
Multiply A 4,4
and A 5,5
Multiply A 4,5
and A 6,6
Multiply A 1,3
and A 4,6