Given a chain
<A1, A2,...,An>
ofn
matrices, wherefor i = 1, 2,...,n
, matrixAi
has dimensionpi-1 * pi
, fully parenthesize the productA1A2...An
in way that minimize the number of scalar multiplications.
The goal of the problem is that to find a way to parenthesize the sequence of matrices that yields the lowest cost.
p[]
is an array that store dimension of the matrix chainm[][]
is an array that saves minimum cost of the scalar multiplication of sequence<Ai,Ai+1,...,Aj>
- if
i == j
, thenm[i,j] = 0
m[i,j] = min(m[i,k] + m[k+1,j] + p[i-1] * p[k] * p[j])
& i <= k < j
public class TopDown {
public int topDownMatrixProduct(int[] p, int i, int j, int[][] m) {
if (i >= j) {
return 0;
}
if (m[i][j] > 0) {
return m[i][j];
}
int min = Integer.MAX_VALUE;
for (int k = i; k < j; k++) {
int q = topDownMatrixProduct(p, i, k, m) + topDownMatrixProduct(p, k + 1, j, m) + (p[i - 1] * p[k] * p[j]);
if (q < min) {
min = q;
}
}
m[i][j] = min;
return min;
}
}
You need a find maximum method to above code works well. For complete code, details and other forms click.
public class BottomUp {
public static int[][] matrixChainOrder(int[] p) {
int n = p.length - 1; // because p have indices of 0,1,...,n-1,n => length of p is n+1
int[][] m = new int[n + 1][n + 1];
int[][] s = new int[n + 1][n + 1];
for (int i = 0; i < n; i++) { // the minimum cost for sequences with size of one
m[i][i] = 0;
}
for (int l = 2; l <= n; l++) { // is the chain length
for (int i = 1; i <= n - l + 1; i++) { // [1]*
int j = l + i - 1;
int min = Integer.MAX_VALUE;
for (int k = i; k < j; k++) { // find best k for range between i, j (k: is the last position that multiply occurs between two matrices
int q = m[i][k] + m[k + 1][j] + p[i - 1] * p[k] * p[j];
if (q < min) {
min = q;
s[i][j] = k;
}
}
m[i][j] = min;
}
}
return m;
}
}
You need a find maximum method to above code works well. For complete code, details and other forms click.
- O(n^3)
Matrix | A1 | A2 | A3 | A4 | A5 | A6 |
---|---|---|---|---|---|---|
dimension | 30 * 35 | 35 * 15 | 15 * 5 | 5 * 10 | 10 * 20 | 20 * 25 |
- We store Dimension of matrices in a
p[]
array. - Denote dimension of matrix
Ai
withp[i-1]
andp[i]
.p[i-1]
andp[i]
store inorder row and column of matrixAi
.
pi | 0 | 1 | 2 | 3 | 4 | 5 | 6 |
---|---|---|---|---|---|---|---|
values | 30 | 35 | 15 | 5 | 10 | 20 | 25 |
-
If we have a chain of matrices <A1, A2, A3, A4, A5, A6> with dimensions that are shown in the Matrix Table, we want to fully parenthesize the product A1A2...A6 in a way that minimizes the number of scalar multiplications, we can obtain the cost with recursive formula:
-
chain <A1, A2, A3, A4, A5, A6> with length of 6:
-
m[1,6] = min(m[1,k] + m[k+1,6] + p[0] * p[k] * p[6])
&1 <= k < 6
-
k = 1
==> m[1,1] + m[2,6] + p[0] * p[1] * p[6] = 0 + 10500 + 30 * 35 * 25 = 36750 -
k = 2
==> m[1,2] + m[3,6] + p[0] * p[2] * p[6] = 15750 + 5375 + 30 * 15 * 25 = 32375 -
k = 3
==> m[1,3] + m[4,6] + p[0] * p[3] * p[6] = 7875 + 3500 + 30 * 5 * 25 = 15125 -
k = 4
==> m[1,4] + m[5,6] + p[0] * p[4] * p[6] = 9375 + 5000 + 30 * 10 * 25 = 21875 -
k = 5
==> m[1,5] + m[6,6] + p[0] * p[5] * p[6] = 11875 + 0 + 30 * 20 * 25 = 26875
-
-
m[2,6] = min(m[2,k] + m[k+1,6] + p[1] * p[k] * p[6])
&2 <= k < 6
-
k = 2
==> m[2,2] + m[3,6] + p[1] * p[2] * p[6] = 0 + 5375 + 35 * 15 * 25 = 18500 -
k = 3
==> m[2,3] + m[4,6] + p[1] * p[3] * p[6] = 2625 + 3500 + 35 * 5 * 25 = 10500 -
k = 4
==> m[2,4] + m[5,6] + p[1] * p[4] * p[6] = 4375 + 5000 + 35 * 10 * 25 = 18125 -
k = 5
==> m[2,5] + m[6,6] + p[1] * p[5] * p[6] = 7125 + 0 + 35 * 20 * 25 = 24625
-
-
m[3,6] = min(m[3,k] + m[k+1,6] + p[2] * p[k] * p[6])
&3 <= k < 6
-
k = 3
==> m[3,3] + m[4,6] + p[2] * p[3] * p[6] = 0 + 3500 + 15 * 5 * 25 = 5375 -
k = 4
==> m[3,4] + m[5,6] + p[2] * p[4] * p[6] = 750 + 5000 + 15 * 10 * 25 = 9500 -
k = 5
==> m[3,5] + m[6,6] + p[2] * p[5] * p[6] = 2500 + 0 + 15 * 20 * 25 = 10000
-
-
m[4,6] = min(m[4,k] + m[k+1,6] + p[3] * p[k] * p[6])
&4 <= k < 6
-
k = 4
==> m[4,4] + m[5,6] + p[3] * p[4] * p[6] = 0 + 5000 + 5 * 10 * 25 = 6250 -
k = 5
==> m[4,5] + m[6,6] + p[3] * p[5] * p[6] = 1000 + 0 + 5 * 20 * 25 = 3500
-
-
m[5,6] = min(m[5,k] + m[k+1,6] + p[1] * p[k] * p[6])
&5 <= k < 6
-
k = 5
==> m[5,5] + m[6,6] + p[4] * p[5] * p[6] = 0 + 0 + 10 * 20 * 25 = 5000
-
-
m[4,5] = min(m[4,k] + m[k+1,5] + p[3] * p[k] * p[5])
&4 <= k < 5
-
k = 4
==> m[4,4] + m[5,5] + p[3] * p[4] * p[5] = 0 + 0 + 5 * 10 * 20 = 1000
-
-
m[3,4] = min(m[3,k] + m[k+1,4] + p[2] * p[k] * p[4])
&3 <= k < 4
-
k = 3
==> m[3,3] + m[4,4] + p[2] * p[3] * p[4] = 0 + 0 + 15 * 5 * 10 = 750
-
-
m[3,5] = min(m[3,k] + m[k+1,5] + p[2] * p[k] * p[5])
&3 <= k < 5
-
k = 3
==> m[3,3] + m[4,5] + p[2] * p[3] * p[5] = 0 + 1000 + 15 * 5 * 20 = 2500 -
k = 4
==> m[3,4] + m[5,5] + p[2] * p[4] * p[5] = 750 + 0 + 15 * 10 * 20 = 3750
-
-
m[2,3] = min(m[2,k] + m[k+1,3] + p[1] * p[k] * p[3])
&2 <= k < 3
-
k = 2
==> m[2,2] + m[3,3] + p[1] * p[2] * p[3] = 0 + 0 + 35 * 15 * 5 = 2625
-
-
m[2,4] = min(m[2,k] + m[k+1,4] + p[1] * p[k] * p[4])
&2 <= k < 4
-
k = 2
==> m[2,2] + m[3,4] + p[1] * p[2] * p[4] = 0 + 750 + 35 * 15 * 10 = 6000 -
k = 3
==> m[2,3] + m[4,4] + p[1] * p[3] * p[4] = 2625 + 0 + 35 * 5 * 10 = 4375
-
-
m[2,5] = min(m[2,k] + m[k+1,5] + p[1] * p[k] * p[5])
&2 <= k < 5
-
k = 2
==> m[2,2] + m[3,5] + p[1] * p[2] * p[5] = 0 + 2500 + 35 * 15 * 20 = 13000 -
k = 3
==> m[2,3] + m[4,5] + p[1] * p[3] * p[5] = 2625 + 1000 + 35 * 5 * 20 = 7125 -
k = 4
==> m[2,4] + m[5,5] + p[1] * p[4] * p[5] = 4375 + 0 + 35 * 10 * 20 = 11375
-
-
m[1,2] = min(m[1,k] + m[k+1,2] + p[0] * p[k] * p[2])
&1 <= k < 2
-
k = 1
==> m[1,1] + m[2,2] + p[0] * p[1] * p[2] = 0 + 0 + 30 * 35 * 15 = 15750
-
-
m[1,3] = min(m[1,k] + m[k+1,3] + p[0] * p[k] * p[3])
&1 <= k < 3
-
k = 1
==> m[1,1] + m[2,3] + p[0] * p[1] * p[3] = 0 + 2625 + 30 * 35 * 5 = 7875 -
k = 2
==> m[1,2] + m[3,3] + p[0] * p[2] * p[3] = 15750 + 0 + 30 * 15 * 5 = 18000
-
-
m[1,4] = min(m[1,k] + m[k+1,4] + p[0] * p[k] * p[4])
&1 <= k < 4
-
k = 1
==> m[1,1] + m[2,4] + p[0] * p[1] * p[4] = 0 + 4375 + 30 * 35 * 10 = 14875 -
k = 2
==> m[1,2] + m[3,4] + p[0] * p[2] * p[4] = 15750 + 750 + 30 * 15 * 10 = 21000 -
k = 3
==> m[1,3] + m[4,4] + p[0] * p[3] * p[4] = 7875 + 0 + 30 * 5 * 10 = 9375
-
-
m[1,5] = min(m[1,k] + m[k+1,5] + p[0] * p[k] * p[5])
&1 <= k < 5
-
k = 1
==> m[1,1] + m[2,5] + p[0] * p[1] * p[5] = 0 + 7125 + 30 * 35 * 20 = 28125 -
k = 2
==> m[1,2] + m[3,5] + p[0] * p[2] * p[5] = 15750 + 2500 + 30 * 15 * 20 = 27250 -
k = 3
==> m[1,3] + m[4,5] + p[0] * p[3] * p[5] = 7875 + 1000 + 30 * 5 * 20 = 11875 -
k = 4
==> m[1,4] + m[5,5] + p[0] * p[4] * p[5] = 9375 + 0 + 30 * 10 * 20 = 15375
-
Result of fully parenthesize:
((A1) * ( (A2) * (A3) ) ) * (( (A4) * (A5)) * A6)
- Table of minimum number of scalar multiplications:
- The minimum number of scalar multiplications to multiply the 6 matrices is
m[1,6] = 15125
- The minimum number of scalar multiplications to multiply the 6 matrices is
i\j |
j | 1 | 2 | 3 | 4 | 5 | 6 |
---|---|---|---|---|---|---|---|
i | Ai\Aj |
A1 | A2 | A3 | A4 | A5 | A6 |
1 | A1 | 0 | 15750 | 7875 | 9375 | 11875 | 15125 |
2 | A2 | - | 0 | 2625 | 4375 | 7125 | 10500 |
3 | A3 | - | - | 0 | 750 | 2500 | 5375 |
4 | A4 | - | - | - | 0 | 1000 | 3500 |
5 | A5 | - | - | - | - | 0 | 5000 |
6 | A6 | - | - | - | - | - | 0 |
- Table of last multiply position between two subproblems:
i\j |
j | 1 | 2 | 3 | 4 | 5 | 6 |
---|---|---|---|---|---|---|---|
i | Ai\Aj |
A1 | A2 | A3 | A4 | A5 | A6 |
1 | A1 | 0 | 1 | 1 | 3 | 3 | 3 |
2 | A2 | - | 0 | 2 | 3 | 3 | 3 |
3 | A3 | - | - | 0 | 3 | 3 | 3 |
4 | A4 | - | - | - | 0 | 4 | 5 |
5 | A5 | - | - | - | - | 0 | 5 |
6 | A6 | - | - | - | - | - | 0 |