This
is the concluding part of the series of tutorials on Dynamic Programming. In
this part we will see and assimilate one example where the problem of Matrix
Chain Multiplication will be solved with Dynamic Programming Principle
What is this Matrix Chain Multiplication Problem?
Suppose
we have a sequence or chain A1, A2, …, An of n matrices to be multiplied. That is, we want to compute the
product A1A2…An. Now there are many possible ways
(parenthesizations) to compute the product.
Let us
consider the chain A1, A2,
A3, A4 of 4 matrices. Now to compute the product A1A2A3A4,
there are 5 possible ways as described below:
(A1(A2(A3A4))),
(A1((A2A3)A4)), ((A1A2)(A3A4)),
((A1(A2A3))A4), (((A1A2)A3)A4)
Each of these options may lead to the
different number of scalar multiplications, and we have to select the best one
(option resulting fewer number of Scalar Multiplications)
Hence the problem statement looks something
like: “Parenthesize the product A1A2…An
such that the total number of scalar multiplications is minimized”
Please remember that the objective of Matrix
Chain Multiplication is not to do the multiplication physically, rather the
objective is to fix the way of that multiplication ordering so that the number
of scalar multiplication gets minimized.
Give
me one real example
Ok. But before I show you one real example,
let us revisit the algorithm which multiplies two matrices. It goes like
following:
Input:
Matrices Ap×q and Bq×r (with dimensions p×q and q×r)
Result:
Matrix Cp×r resulting from the product A·B
MATRIX-MULTIPLY(Ap×q
, Bq×r)
1. for i ← 1 to p
2. for
j ← 1 to r
3. C[i,
j] ← 0
4. for
k ← 1 to q
5. C[i,
j] ← C[i, j] + A[i, k] · B[k, j]
6. return C
In the above algorithm, scalar
multiplication in line 5 dominates time to compute C Number of scalar
multiplications = pqr
Now on the basis of above algorithm what if
we try to multiply three matrices A10´100, B100´5, and C5´50?
There are 2 ways to parenthesize
–
((AB)C)
= D10´5 · C5´50
•
AB Þ 10·100·5=5,000 scalar multiplications
•
DC Þ 10·5·50 =2,500 scalar multiplications
•
Total
number of scalar multiplications 7,500
–
(A(BC))
= A10´100 · E100´50
•
BC Þ 100·5·50=25,000 scalar multiplications
•
AE Þ 10·100·50 =50,000 scalar multiplications
•
Total
number of scalar multiplications 75,000
It is evident that the first option will
result the fewer number of scalar multiplication and it is the best one for
computational easiness.
Hope now you understand what I mean.
How
do you know that this problem could be solved through Dynamic Programming?
See, there are some clear evidences that
this problem is perfect fit to be solved through Dynamic Programming.
In connection to the Matrix Chain Multiplication, the optimal solution
to the problem contains within it the optimal solution to subproblems. That is
why we can say that this problem will better be solved by Dynamic Programming.
Now the question is how we came to a conclusion that the principle of
optimality holds true in this case?
Looking back to the problem, we are given with a chain A1, A2,
…, An of n matrices, where for i=1, 2, …, n, matrix Ai
has dimension pi-1´pi. We need to search for optimal solution of parenthesization in order to minimize the scalar computation.
Hence to find the structure of the optimal solution –
§
Let us
use the notation Ai..j for the matrix that
results from the product Ai Ai+1
… Aj
§
Let us
admit that an optimal parenthesization of the product A1A2…An
splits the product between Ak and Ak+1
for some integer k where1 ≤ k < n
§
So we
have to compute matrices A1..k and Ak+1..n
first; then multiply them to get the
final matrix A1..n
The Key observation here is the parenthesizations of the subchains A1A2…Ak
and Ak+1Ak+2…An
must also be optimal if the parenthesization of the chain A1A2…An
is optimal.
Hence Dynamic Programming Principle could effectively be used for
Matrix Chain Multiplication problem.
What is the Dynamic
Programming approach particularly for this problem?
Let m[i, j] be the minimum number of scalar multiplications necessary
to compute Ai..j . So minimum cost to compute A1..n is m[1,
n]
Suppose the optimal parenthesization of Ai..j splits the
product between Ak and Ak+1 for some integer k where i ≤ k
< j. Hence Ai..j = (Ai Ai+1…Ak)·(Ak+1Ak+2…Aj)=
Ai..k · Ak+1..j
We get Cost of computing Ai..j = cost of computing Ai..k
+ cost of computing Ak+1..j + cost of multiplying Ai..k
and Ak+1..j
Now Cost of multiplying Ai..k and Ak+1..j is pi-1pk
pj
So evidently m[i, j ] = m[i, k] + m[k+1, j ] + pi-1pk pj for i ≤ k < j and m[i, i ] = 0 for i=1,2,…,n
But optimal parenthesization occurs at one value of k among all
possible i ≤ k < j, so check all these and select the best one.
So the optimal substructure relation is like following:
m[i, j ] = 0 if i=j
min {m[i, k] + m[k+1,
j ] + pi-1pk pj } if i<j
i ≤ k< j
To keep track of how to construct an optimal solution, we use a table s.
s[i, j ] = value of k at which Ai Ai+1 … Aj is
split for optimal parenthesization.
Wait a minute, I got almost
everything except that p array what is it? Where did it come from?
The P array stores the dimensions of the matrices. Suppose we are to
multiply 3 matrices of dimension 5* 10, 10* 3 and 3*8, in this case the length
of p array will be (3+1) 4 and it will be like P[0] = 5, p[1] = 10, p[2] = 3 and p[3]=8.
So generalizing, if you have n matrices to be multiplied, take the
length of p as n+1, then fill p[0] with row number of 1st matrix, fill
p[n] with column no of nth matrix, and for the intermediate indices go like
following
P[1] = col no of 1st matrix or row no of 2nd
matrix
P[2] = col no of 2nd matrix or row no of 3rd
matrix
P[3] = col no of 3rd matrix or row no of 4th
matrix
…….
P[n-1] = col no of (n-1)th matrix or row no of nth matrix.
Now I got it. Anyways, how is
the algorithm?
Input: Array p[0…n]
containing matrix dimensions and n
Result: Minimum-cost
table m and split table s
MATRIX-CHAIN-ORDER(p[ ], n)
for i ←
1 to n
m[i, i] ← 0
for l ←
2 to n
for
i ← 1 to n-l+1
j
← i+l-1
m[i,
j] ← ¥
for
k ← i to j-1
q
← m[i, k] + m[k+1, j] + p[i-1]
p[k] p[j]
if q < m[i, j]
m[i, j] ← q
s[i,
j] ← k
return m and s
Can you please give me a C
code for Matrix Chain Multiplication
Here is the code. This code fills
up the split table but never utilizes it to show the proper ordering of
parenthesis. That part is left for you guys to explore.
This program takes the length
of the chain of matrices, and the p array where the dimension of arrays are
stored and computes the minimum number of scalar multiplications.
There is no comment. Try to comment it by your own..this will give you the insights of the program
#include<stdio.h>
#include<stdlib.h>
#include<conio.h>
#include<limits.h>
int compute(int*dimArray,
int**splitTab, int start, int end)
{
int iter, sTableEntry;
int minimumCountOfScalarMultiplications =
INT_MAX;
int countOfScalarMultiplications;
if(start == end)
return 0;
else
{
for(iter = start; iter < end;
iter++)
{
countOfScalarMultiplications = compute(dimArray, splitTab, start,iter)+
compute(dimArray, splitTab, iter+1, end)+(dimArray[start -
1]*dimArray[iter]*dimArray[end]);
if(countOfScalarMultiplications <
minimumCountOfScalarMultiplications)
{
minimumCountOfScalarMultiplications = countOfScalarMultiplications;
sTableEntry
= iter;
}
}
splitTab[start][end] =
sTableEntry;
}
return minimumCountOfScalarMultiplications;
}
int main(void)
{
int* processedInput;
int lengthOfChain;
int iter;
int** splitTable;
printf("\n Enter the length of the
chain::");
scanf("%d", &lengthOfChain);
processedInput =
(int*)malloc(lengthOfChain+1*sizeof(int));
splitTable = (int**)calloc(lengthOfChain +
1, sizeof(int*));
for(iter = 0; iter<lengthOfChain;
iter++)
splitTable[iter] =
(int*)calloc(lengthOfChain + 1 , sizeof(int));
printf("\n Enter the dimension of the
matrix = ");
for(iter = 0; iter<=lengthOfChain;
iter++)
scanf("%d",
&processedInput[iter]);
printf("\n Your Input Is Registered
Successfully.... Press any key to continue");
getch();
printf("\n The number of minimum
scalar multiplication = %d", compute(processedInput,splitTable,1,
lengthOfChain));
getch();
return 0;
}
Sample Input
Enter the length of the
chain::6
Enter the dimension of the
matrix =30 35 15 5 10 20 25
Sample Output
The number of minimum scalar
multiplication = 15125
very helpful!!...
ReplyDeletethanx fr writing such a blog sir :)