实验目的:
- 理解动态规划算法的基本思想
- 运用动态规划算法解决实际问题
实验内容:
- 编程矩阵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