CSC2105: Algorithms
Dynamic Programming
Mashiour Rahman
Assistant Professor
[email protected]
American International University Bangladesh
Algorithm design techniques
Iterative (brute-force) algorithms
Example: insertion sort
Algorithms that use efficient data structures
Example: heap sort
Divide-and-conquer algorithms
Example: Binary search, merge sort, quick sort
Dynamic programming
Example: Fibonacci numbers, Matrix multiplication optimization, Longest
Common Subsequence
Greedy algorithms
Example: Huffman coding, Minimum Spanning Tree, Dijkstara
Graph Algorithms
Example: BFS (Robot moving, Path Finding), DFS( Topological Sorting,
Strongly Connected Component)
Mashiour Rahman AIUB::CSC2105::Algorithms Dynamic Programming2
Fibonacci Numbers
Leonardo Fibonacci (1202):
A rabbit starts producing offspring during the second
year after its birth and produces one child each
generation
How many rabbits will there be after n generations?
F(1)=1 F(2)=1 F(3)=1
F(3)=2+1 F(4)=2+1
F(4)=3 F(5)=3+2
F(5)=5 F(6)=5+3
F(6)=8
Mashiour Rahman AIUB::CSC2105::Algorithms Dynamic Programming3
…Fibonacci Numbers
F(n)= F(n-1)+ F(n-2)
F(0) =0, F(1) =1
0, 1, 1, 2, 3, 5, 8, 13, 21, 34 …
FibonacciR(n)
FibonacciR(n)
01 if nn 11 then
01 if then return
return nn
02
02 else
else return
return FibonacciR(n-1)
FibonacciR(n-1) ++ FibonacciR(n-2)
FibonacciR(n-2)
Straightforward recursive procedure is slow!
Mashiour Rahman AIUB::CSC2105::Algorithms Dynamic Programming4
…Fibonacci Numbers
F(6) = 8
F(5) F(4)
F(4) F(3) F(3) F(2)
F(3) F(2) F(2) F(1) F(2) F(1) F(1) F(0)
F(2) F(1) F(1) F(0) F(1) F(0) F(1) F(0)
F(1) F(0)
We keep calculating the same value over and over!
Subproblems are overlapping – they share sub-subproblems
Mashiour Rahman AIUB::CSC2105::Algorithms Dynamic Programming5
…Fibonacci Numbers
How many summations are there in F(n)?
F(n) = F(n – 1) + F(n – 2) + 1
F(n) 2F(n – 2) +1 and F(1) = F(0) = 0
Solving the recurrence we get
F(n) 2n/2 – 1 1.4n
Running time is exponential!
Mashiour Rahman AIUB::CSC2105::Algorithms Dynamic Programming6
…Fibonacci Numbers
We can calculate F(n) in linear time by
remembering solutions to the solved
subproblems (= dynamic programming).
Compute solution in a bottom-up fashion
Trade space for time!
Fibonacci(n)
Fibonacci(n)
01
01 F[0]0
F[0]0
02
02 F[1]1
F[1]1
03 for ii
03 for 22 to
to nn do
do
04
04 F[i]
F[i] F[i-1]
F[i-1] ++ F[i-2]
F[i-2]
05
05 return
return F[n]
F[n]
Mashiour Rahman AIUB::CSC2105::Algorithms Dynamic Programming7
…Fibonacci Numbers
In fact, only two values need to be remembered
at any time!
FibonacciImproved(n)
FibonacciImproved(n)
01 if nn 11 then
01 if then return
return nn
02 Fim2 0
02 Fim2 0
03 Fim1 1
03 Fim1 1
04 for ii
04 for 22 to
to nn do
do
05
05 Fi
Fi Fim1
Fim1 ++ Fim2
Fim2
06
06 Fim2
Fim2 Fim1
Fim1
07
07 Fim1
Fim1 Fi
Fi
05
05 return
return Fi Fi
Mashiour Rahman AIUB::CSC2105::Algorithms Dynamic Programming8
History
Dynamic programming
Invented in the 1957 by Richard Bellman as a
general method for optimizing multistage decision
processes
The term “programming” refers to a tabular method.
method
Often used for optimization problems.
Mashiour Rahman AIUB::CSC2105::Algorithms Dynamic Programming9
Dynamic Programming
Solves problems by combining the solutions to
subproblems that contain common sub-sub-problems.
Difference between DP and Divide-and-Conquer
Using Divide and Conquer to solve these problems is
inefficient as the same common sub-sub-problems
have to be solved many times.
times
DP will solve each of them once and their answers
are stored in a table for future reference.
Mashiour Rahman AIUB::CSC2105::Algorithms Dynamic Programming10
Intuitive Explanation
Given a problem P, obtain
a sequence of problems
Q0, Q1, …., Qm, where:
You have a solution to Q0
The solution to a problem
Qj, j > 0,
0 can be obtained
from solutions to problems
Q0...Qk, k < j,
j that appear
earlier in the “sequence”.
Mashiour Rahman AIUB::CSC2105::Algorithms Dynamic Programming11
Elements of Dynamic Programming
DP is used to solve problems with the following
characteristics:
Optimal sub-structure (Principle of Optimality)
an optimal solution to the problem contains within it
optimal solutions to sub-problems.
Overlapping subproblems
there exist some places where we solve the same
subproblem more than once
Mashiour Rahman AIUB::CSC2105::Algorithms Dynamic Programming12
Example: Fibonacci Numbers
F(6) = 8
F(5) F(4)
F(4) F(3) F(3) F(2)
F(3) F(2) F(2) F(1) F(2) F(1) F(1) F(0)
F(2) F(1) F(1) F(0) F(1) F(0) F(1) F(0)
F(1) F(0)
We keep calculating the same value over and over!
Subproblems are overlapping – they share sub-subproblems
Mashiour Rahman AIUB::CSC2105::Algorithms Dynamic Programming13
Steps to Designing a
Dynamic Programming Algorithm
1. Characterize optimal sub-structure
2. Recursively define the value of an
optimal solution
3. Compute the value bottom up
4. (if needed) Construct an optimal solution
Mashiour Rahman AIUB::CSC2105::Algorithms Dynamic Programming14
1.Optimal Sub-Structure
An optimal solution to the problem contains optimal
solutions to sub-problems
Solution to a problem:
Making a choice out of a number of possibilities (look what
possible choices there can be)
Solving one or more sub-problems that are the result of a
choice (characterize the space of sub-problems)
Show that solutions to sub-problems must themselves be
optimal for the whole solution to be optimal.
Mashiour Rahman AIUB::CSC2105::Algorithms Dynamic Programming15
2. Recursive Solution
Write a recursive solution for the value of an
optimal solution.
Combination of M opt for all subproblems resulting from choice k
M opt Optimal
over all k choices The cost associated with making the choice k
Show that the number of different instances
of sub-problems is bounded by a polynomial.
Mashiour Rahman AIUB::CSC2105::Algorithms Dynamic Programming16
3. Bottom Up
Compute the value of an optimal solution in
a bottom-up fashion, so that you always have
the necessary sub-results pre-computed
(or use memoization)
Check if it is possible to reduce the space
requirements, by “forgetting” solutions to
sub-problems that will not be used any more
Mashiour Rahman AIUB::CSC2105::Algorithms Dynamic Programming17
4. Construct Optimal Solution
Construct an optimal solution from
computed information (which
records a sequence of choices made
that lead to an optimal solution)
Mashiour Rahman AIUB::CSC2105::Algorithms Dynamic Programming18
Review: Matrix Multiplication
Matrix-Multiply(A,B):
1 if columns[A] != rows[B] then
2 error "incompatible dimensions"
3 else{
5 for i = 1 to rows[A] do
6 for j = 1 to columns[B] do{
7 C[i,j] = 0
8 for k = 1 to columns[A] do
9 C[i,j] = C[i,j]+A[i,k]*B[k,j]
10 }
11 }
12 return C
Time complexity = O(pqr),
where |A|=p×q and |B|=q×r
Mashiour Rahman AIUB::CSC2105::Algorithms Dynamic Programming19
Multiplying Matrices
Two matrices, A – n×m matrix and B – m×k
matrix, can be multiplied to get C with
dimensions n×k, using n×m×k scalar
multiplications
a11 a12 ... ... ... m
a a
b11 b12 b13
21 22 b b b 22 ... c ...
ci , j ai ,l bl , j
a a 21 22 23 ... ... ...
31 32 l 1
Problem: Compute a product of many
matrices efficiently
Mashiour Rahman AIUB::CSC2105::Algorithms Dynamic Programming20
Matrix Chain Multiplication [MCM]:
The Problem
Input: Matrices T1,T2,…, Tn, each Ti of size di-1 x di
Output: Fully parenthesized product T1T2…Tn that
minimizes the number of scalar multiplications.
A product of matrices is fully parenthesized if it is either
a) a single matrix, or
b) the product of 2 fully parenthesized matrix products surrounded
by parentheses.
Example: T1 T2 T3 T4 can be fully parenthesized as:
1. (T1 (T2 (T3 T4 ))) 4. ((T1 (T2 T3 ))T4 )
2. (T1 ((T2 T3 )T4 )) 5. (((T1 T2 )T3 )T4 )
3. ((T1 T2 )(T3 T4 ))
Mashiour Rahman AIUB::CSC2105::Algorithms Dynamic Programming21
Matrix Chain Multiplication [MCM]:
The Problem
Suppose size of Ai is pi-1 by pi.
(A1 ( A2 ( A3 A4 ) )) : p2 p3 p4 + p1p2p4 + p0p1p4
(((A1 A2) A3) A4 ) : p0 p1 p2 + p0p2p3 + p0p3p4
p1 p2 p3 p4
A4
A2
A3
p0 A1
Mashiour Rahman AIUB::CSC2105::Algorithms Dynamic Programming22
Matrix Chain Multiplication [MCM]:
(A1(A2(A3 A4)))
p1 p2 p3 p4 p1 p2 p4
A2 A4 A2
A3 A 3 A4
A1 A1
p0 p0
(A3 A4) (A2(A3 A4))
p2p3p4 multiplications p1p2p4 multiplications
Total: p2p3p4 + p1p2p4 + p0p1p4
p4 p1 p4
A2(A3A4)
p0 A1
A1( A2(A3A4)) p0
(A1(A2(A3 A4)))
p0p1p4 multiplications
Mashiour Rahman AIUB::CSC2105::Algorithms Dynamic Programming23
Matrix Chain Multiplication [MCM]:
(((A1 A2)A3)A4)
p1 p2 p3 p4 p2 p3 p4
A2 A4 A4
A3 A3
A1
p0 p0 (A1A2)
((A1 A2)A3)
(A1 A2)
p0p2p3 multiplications
p0p1p2 multiplications
Total: p0p1p2 + p0p2p3 + p0p3p4
p4
p3 p4
A4
((A1A2)A3)A4
p0 (A1A2)A3
p0
(((A1 A2)A3)A4)
p0p3p4 multiplications
Mashiour Rahman AIUB::CSC2105::Algorithms Dynamic Programming24
MCM: Parenthesization
Some Preliminaries A=30 x 1 B=1 x 40
Matrix multiplication is associative
30x1x40
(AB)
AB C = A(BC)
BC
The parenthesization matters
(AB)=30x40 C=40x10
Consider A×B×C×D, where
A is 30×1,B is 1×40,
40 30x40x10
C is 40×10,
10 D is 10×25
Costs:
((AB)C)=30x10 D=10x25
(((AB)
AB C)D)
=1200 + 12000 + 7500 = 20700 30x10x25
(((AB)C)D)=30x25
Mashiour Rahman AIUB::CSC2105::Algorithms Dynamic Programming25
MCM: Parenthesization
Some Preliminaries
Matrix multiplication is associative
(AB)
AB C = A(BC)
BC A=30 x 1 B=1 x 40 C=40x10 D=10x25
The parenthesization matters 30x1x40 40x10x25
Consider A×B×C×D, where
A is 30×1,B is 1×40,
40
(AB)=30x40 (CD)=40x25
C is 40×10,
10 D is 10×25
Costs:
(((AB)
AB C)D)
30x40x25
1200 + 12000 + 7500 = 20700
((AB)(
AB CD)
CD
=1200 + 10000 + 30000 = 41200
((AB)(CD))=30x25
Mashiour Rahman AIUB::CSC2105::Algorithms Dynamic Programming26
MCM: Parenthesization
Some Preliminaries B=1 x40 C=40x10
Matrix multiplication is associative
1x40x10
(AB)
AB C = A(BC)
BC
The parenthesization matters
(BC)=1 x10 D=10x25
Consider A×B×C×D, where
A is 30×1,B is 1×40,
40 1x10x25
C is 40×10,
10 D is 10×25
Costs:
A=30 x 1 ((BC)D)=1x25
(((AB)
AB C)D)
1200 + 12000 + 7500 = 20700
30x1x25
((AB)(
AB CD)
CD
1200 + 10000 + 30000 = 41200
(A((BC)
BC D)) (A((BC)D))=30x25
=400 + 250 + 750 = 1400
Mashiour Rahman AIUB::CSC2105::Algorithms Dynamic Programming27
MCM: Parenthesization
Some Preliminaries
Matrix multiplication is associative
(AB)
AB C = A(BC)
BC We need to optimally parenthesize
The parenthesization matters T1 x T2 x…Tn, where Ti is a di-1 x di matrix.
According to the given example
Consider A×B×C×D, where
A is 30×1,B is 1×40,
40
d = {30, 1, 40, 10, 25 }
C is 40×10,
10 D is 10×25
T1 x T2 x T3 x T4 where
Costs:
T1 = d1-1 x d1 = d0 x d1 = 30 x 1
(((AB)
AB C)D)
T2 = d2-1 x d2 = d1 x d2 = 1 x 40
1200 + 12000 + 7500 = 20700 T3 = d3-1 x d3 = d2 x d3 = 40 x 10
((AB)(
AB CD)
CD T4 = d4-1 x d4 = d3 x d4 = 10 x 25
1200 + 10000 + 30000 = 41200 Costs:
(A((BC)
BC D)) ((T1 T2) T3) T4 = 20700
400 + 250 + 750 = 1400 (T1 T2) (T3 T4) = 41200
T1 ((T2 T3) T4) = 1400
Mashiour Rahman AIUB::CSC2105::Algorithms Dynamic Programming28
MCM: Parenthesization
Let the number of different parenthesizations, P(n).
1 if n 1
n-1
P(n) P(k)P(n - k) if n 2
Then,
k 1
Using Generating Function we have,
P(n) = C(n-1), the (n-1)th Catalan Number where
2n
C(n) 1/(n 1)Cn Ω 4 / n n 3/2
Exhaustively checking all possible parenthesizations
take exponential time!
Mashiour Rahman AIUB::CSC2105::Algorithms Dynamic Programming29
MCM :: Step 1: Characterize Optimal Sub-structure
Let M(i, j) be the minimum number of multiplications
necessary to compute Ti..j = Ti x … x Tj
Key observations
The outermost parenthesis partitions the chain of matrices (i, j) at
some k, (i ≤ k < j):
j (Ti…Tk)(Tk+1…Tj)
The optimal parenthesization of matrices (i, j) is also optimal on either
side of k; i.e., for matrices (i, k)
k and (k+1, j)
j
Within the optimal parenthesization of Ti..j,
(a) the parenthesization of Ti..k must be optimal
(b) the parenthesization of Tk+1..j must be optimal
Why?
Mashiour Rahman AIUB::CSC2105::Algorithms Dynamic Programming30
MCM :: Step 2: Recursive (Recurrence) Formulation
Need to find T1..n
Let M(i, j) = minimum # of scalar multiplications needed to compute Ti..j
Since Ti..j can be obtained by breaking it into Ti..k & Tk+1..j , we have
0 if i j
M(i,j)
min
i kj
M(i,k) M(k 1,j) di1 dk dj if i j
Note: The sizes of Ti..k is di-1 x dk and Tk+1..j is dk x dj ,
and Ti..k Tk+1..j is di-1 x dj after di-1 dk dj scalar multiplications.
Let s(i, j) be the value k where the optimal split occurs
A direct recursive implementation is exponential – a lot of duplicated work.
But there are only few different subproblems (i, j): one solution for each
choice of i and j (i < j).
j
Mashiour Rahman AIUB::CSC2105::Algorithms Dynamic Programming31
MCM::Step 2: Recursive (Recurrence) Formulation
Recursive-Matrix-Chain(d, i, j)
1 if i = j then
2 return 0;
3 M[i, j] = ∞;
4 for k = i to j-1 do
5 q = Recursive-Matrix-Chain(d, i, k) +
Recursive-Matrix-Chain(d, k+1, j) +
di-1dkdj
6 if q < M[i, j] then
7 M[i, j] = q ;
S[i, j] = k ;
8 return M[i, j] ;
Mashiour Rahman AIUB::CSC2105::Algorithms Dynamic Programming32
MCM :: Step 2: Recursive (Recurrence) Formulation
Overlapping Subproblems
Let T(n) be the time complexity of
Recursive-Matrix-Chain(d, 1, n)
For n > 1, we have
n 1
T(n)= 1 + (T(k) T(n - k) 1)
k 1
a) 1 is used to cover the cost of lines 1-3, and 8
b) 1 is used to cover the cost of lines 6-7
Using substitution, we can show that T(n) ≥ 2n-1
Hence T(n) = Ω(2n)
Mashiour Rahman AIUB::CSC2105::Algorithms Dynamic Programming33
MCM :: Step 3: Computing Optimal Costs
To compute Ti..j we need only values for subproblems of
length<i-j.
Solve subproblems in the increasing length of subproblems:
first subproblems of length 2, then of length 3 and so on.
Length = 4 T1..4
An Example:
(T2(T3T4))
T2T3T4 =
Length = 3 T1..3 T2..4 ((T2T3)T4)
T2..2 T3..4
Length = 2 T1..2 T2..3 T3..4 T2..4 =
T2..3 T4..4
Length = 1 T1..1 T2..2 T3..3 T4..4
Mashiour Rahman AIUB::CSC2105::Algorithms Dynamic Programming34
MCM :: Step 3: Computing the Optimal Costs
Idea: store the optimal cost M(i, j) for each
subproblem in a 2d array M[1..n,1..n]
Trivially M(i, i) = 0,
0 1≤ i ≤ n
To compute M(i, j), where i – j = L, we need only
values of M for subproblems of length < L.
Thus we have to solve subproblems in the increasing
length of subproblems: first subproblems of length 2, then
of length 3 and so on.
To reconstruct an optimal parenthesization for each
pair (i, j) we record in s[i, j] = k the optimal
split into two subproblems (i, k) and (k+1, j)
Mashiour Rahman AIUB::CSC2105::Algorithms Dynamic Programming35
MCM :: Step 3: Computing the Optimal Costs
Matrix-Chain-Order( d )
01 n = length[d]-1 //d is the array of matrix sizes
02 for i = 1 to n do
03 M[i,i] = 0 // no multiplication for 1 matrix
04 for len = 2 to n do // len is length of sub-chain
05 for i = 1 to n-len+1 do // i: start of sub-chain
06 j =i+len-1 // j: end of sub-chain
07 M[i,j] = ∞
08 for k = i to j-1 do
09 q = M[i,k]+M[k+1,j]+di-1dkdj
10 if q < M[i,j] then
11 M[i,j] = q
12 s[i,j] = k
13 return M and s
Time complexity = O(n3 )
Mashiour Rahman AIUB::CSC2105::Algorithms Dynamic Programming36
MCM :: Step 3: Computing the Optimal Costs
After the execution: M [1,n] contains the value of an
optimal solution and s contains optimal subdivisions (choices
of k) of any subproblem into two sub-subproblems
Let us run the algorithm on the six matrices:
Matrix Dimension
T1 30 X 35
T2 35 X 15
T3 15 X 5
T4 5 X 10
T5 10 X 20
T6 20 X 25
d={ 30, 35, 15, 5, 10, 20, 25 }
See CLRS Figure 15.3
Mashiour Rahman AIUB::CSC2105::Algorithms Dynamic Programming37
Simulation-MCM 0 1 2 3 4 5 6
d 30 35 15 5 10 20 25
Matrix-Chain-Order( d ) M 1 2 3 4 5 6
01 n = length[d]-1 1
02 for i = 1 to n do
03 M[i,i] = 0 2
04 for len = 2 to n do
3
05 for i = 1 to n-len+1 do
06 j =i+len-1 4
07 M[i,j] = ∞
5
08 for k = i to j-1 do
09 q = M[i,k]+M[k+1,j]+di-1dkdj 6
10 if q < M[i,j] then
11 M[i,j] = q S 1 2 3 4 5 6
12 s[i,j] = k 1
13 return M and s
2
3
4
5
6
Mashiour Rahman AIUB::CSC2105::Algorithms Dynamic Programming38
Simulation-MCM 0 1 2 3 4 5 6
d 30 35 15 5 10 20 25
Matrix-Chain-Order( d ) M 1 2 3 4 5 6
01 n = length[d]-1 1 0
02 for i = 1 to n do
03 M[i,i] = 0 2 0
04 for len = 2 to n do
3 0
05 for i = 1 to n-len+1 do
06 j =i+len-1 4 0
07 M[i,j] = ∞
5 0
08 for k = i to j-1 do
09 q = M[i,k]+M[k+1,j]+di-1dkdj 6 0
10 if q < M[i,j] then
11 M[i,j] = q S 1 2 3 4 5 6
12 s[i,j] = k 1
13 return M and s
2
3
4
5
6
Mashiour Rahman AIUB::CSC2105::Algorithms Dynamic Programming39
Simulation-MCM 0 1 2 3 4 5 6
d 30 35 15 5 10 20 25
Matrix-Chain-Order( d ) M 1 2 3 4 5 6
01 n = length[d]-1 1 0 15750
02 for i = 1 to n do
03 M[i,i] = 0 2 0 2625
04 for len = 2 to n do
3 0 750
05 for i = 1 to n-len+1 do
06 j =i+len-1 4 0 1000
07 M[i,j] = ∞
5 0 5000
08 for k = i to j-1 do
09 q = M[i,k]+M[k+1,j]+di-1dkdj 6 0
10 if q < M[i,j] then S 1 2 3 4 5 6
11 M[i,j] = q
12 s[i,j] = k 1 1
13 return M and s
2 2
3 3
4 4
5 5
len=2, [i,j]=[1,2] to [5,6], k = 1 to 5 6
M[1,2] = M[1,1]+M[2,2]+d0*d1*d2 = 0+0+30*35*15 = 15750;
M[2,3] = M[2,2]+M[3,3]+d1*d2*d3 = 0+0+35*15* 5 = 2625;
M[3,4] = M[3,3]+M[4,4]+d2*d3*d4 = 0+0+15* 5*10 = 750;
M[4,5] = M[4,4]+M[5,5]+d3*d4*d5 = 0+0+ 5*10*20 = 1000;
M[5,6] = M[5,5]+M[6,6]+d4*d5*d6 = 0+0+10*20*25 = 5000;
Mashiour Rahman AIUB::CSC2105::Algorithms Dynamic Programming40
Simulation-MCM 0 1 2 3 4 5 6
d 30 35 15 5 10 20 25
Matrix-Chain-Order( d ) M 1 2 3 4 5 6
01 n = length[d]-1 1 0 15750
02 for i = 1 to n do
03 M[i,i] = 0 2 0 2625
04 for len = 2 to n do
3 0 750
05 for i = 1 to n-len+1 do
06 j =i+len-1 4 0 1000
07 M[i,j] = ∞
5 0 5000
08 for k = i to j-1 do
09 q = M[i,k]+M[k+1,j]+di-1dkdj 6 0
10 if q < M[i,j] then S 1 2 3 4 5 6
11 M[i,j] = q
12 s[i,j] = k 1 1
13 return M and s
2 2
Len= 3 3
[i, j]=[ , ] to [ , ] 4 4
5 5
k= 6
M[ , ]=M[ , ]+M[ , ]+d *d *d
= + + * * =
Mashiour Rahman AIUB::CSC2105::Algorithms Dynamic Programming41
MCM :: Step 4: Constructing Optimal Solution
To get the optimal solution T1..6, s[]
is used as follows:
T1..6
= (T1..3 T4..6) ;since s[1,6] = 3
= ((T1..1 T2..3 )(T4..5 T6..6 ))
;since s[1,3] =1 and s[4,6]=5
=((T1 (T2 T3 ))((T4 T5 )T6 ))
MCM can be solved in O(n3) time
Mashiour Rahman AIUB::CSC2105::Algorithms Dynamic Programming42
Matrix Chain Multiplication Problem
Running time
It is easy to see that it is O(n3)
(three nested loops)
It turns out it is also (n3)
Thus, a reduction from exponential time to
polynomial time.
Mashiour Rahman AIUB::CSC2105::Algorithms Dynamic Programming43
Memoization
Memoization is one way to deal with overlapping subproblems
After computing the solution to a subproblem, store it in a table
Subsequent calls just do a table lookup
Can modify recursive algorithm to use memoziation
If we prefer recursion we can structure our algorithm as a
recursive algorithm:
MemoMCM(i,j)
MemoMCM(i,j)
1.
1. if
if ii == jj then
then return
return 00
2.
2. else
else if M[i,j] << then
if M[i,j] then return
return M[i,j]
M[i,j]
3.
3. else
else for
for kk :=:= ii to
to j-1
j-1 do
do
4.
4. qq :=
:= MemoMCM(i,k)+
MemoMCM(i,k)+
MemoMCM(k+1,j)
MemoMCM(k+1,j) ++ ddi-1 dkdj
i-1dkdj
5.
5. if
if qq << M[i,j]
M[i,j] then
then
6.
6. M[i,j]
M[i,j] :=:= qq
7.
7. return
return M[i,j]
M[i,j]
Initialize all elements to and call MemoMCM(i,j)
Mashiour Rahman AIUB::CSC2105::Algorithms Dynamic Programming44
Memoization
Memoization:
Solve the problem in a top-down fashion, but
record the solutions to subproblems in a table.
Pros and cons:
Recursion is usually slower than loops and uses
stack space
Easier to understand
If not all subproblems need to be solved, you are
sure that only the necessary ones are solved
Mashiour Rahman AIUB::CSC2105::Algorithms Dynamic Programming45
Longest Common Subsequence
The Problem
Given two sequences
X = < x1, x2, … , xm >
Z = < z1, z2, … , zk >
Z is a subsequence of X if
zj = xi( j ) for all j = 1, … , k
where <i(1),i(2),…,i(k)> is strictly increasing (but not required
to be consecutive)
Examples:
Let X = < A, B, C, B, D, A, B >
< A >, < B >, < C >, and < D > are subsequences.
< C, A >, < C, B >, < C, B, A, B > are subsequences.
How many possible subsequences for a n-element sequence?
Mashiour Rahman AIUB::CSC2105::Algorithms Dynamic Programming46
Longest Common Subsequence Problem
Z is a common subsequence of sequences X and Y if Z is a
subsequence of both X and Y.
Example:
Let X = < A, B, C, B, D, A, B > and Y = < B, D, C, A, B, A >
< A >, <B>, <C>, and <D> are common subsequences.
< C, A > is, but < A, C > is not.
< B, C, A> is a common subsequence
< B, C, B, A > is the longest common subsequence.
Example:
x = “sariempiolcewe”
y = “westigmupsalrte”
Mashiour Rahman AIUB::CSC2105::Algorithms Dynamic Programming47
Longest Common Subsequence Problem
LCS:
Input: two sequences x[1..m] and y[1..n]
Output: longest common subsequence of x and y (denoted
LCS(x,y))
Brute-force algorithm:
For every subsequence of x, check if it is a subsequence of y
2m subsequences of x to check against n elements of y : O(n 2m)
Mashiour Rahman AIUB::CSC2105::Algorithms Dynamic Programming48
LCS: Optimal Sub-structure
The ith prefix of X = < x1,x2,…,xm > is denoted
Xi = < x1,x2,…,xi >
X0 is the empty sequence
Xm is the whole sequence X
Theorem 15.1 (Optimal Sub-structure of LCS)
Let X=<x1,x2,…,xm>, Y=<y1,y2,…,yn>, and
Z=<z1,z2,…,zk> be LCS(X,Y).
(1) If xm= yn, then zk = xm = yn and Zk-1 is LCS(Xm-1,Yn-1)
(2) if xm ≠ yn, then zk ≠ xm implies Z is LCS(Xm-1,Y)
(3) if xm ≠ yn, then zk ≠ yn implies Z is LCS(X,Yn-1)
Mashiour Rahman AIUB::CSC2105::Algorithms Dynamic Programming49
LCS: Optimal Substructure
We make Z to be empty and proceed from the
ends of Xm=“x1 x2 …xm” and Yn=“y1 y2 …yn”
If xm=yn, append this symbol to the beginning of Z,
and find optimally LCS(Xm-1, Yn-1)
If xm≠yn,
Skip either a letter from X
or a letter from Y
Decide which decision to do by comparing
LCS(Xm, Yn-1) and LCS(Xm-1, Yn)
Starting from beginning is equivalent.
Mashiour Rahman AIUB::CSC2105::Algorithms Dynamic Programming50
LCS: Optimal Substructure
LCS has an optimal sub-structure defined by prefixes
of X and Y
The sub-problems of finding LCS(Xm-1,Yn) and
LCS(Xm,Yn-1) share a common sub-sub-problem of
finding LCS(Xm-1,Yn-1). They are overlapping.
Simplify: just worry about LCS length for now
Define c[i, j] = length of LCS(Xi, Yj)
So c[m, n] = length of LCS(X, Y)
Mashiour Rahman AIUB::CSC2105::Algorithms Dynamic Programming51
LCS: Recurrence
Define c[i, j] = length of LCS of x[1..i],
y[1..j]
0 if i 0 or j 0
c[i, j ] c[i 1, j 1] 1 if i, j 0 and xi y j
max{c[i, j 1], c[i 1, j ]} if i, j 0 and x y
i j
Note that the conditions in the problem restrict sub-
problems (if xi = yi we consider xi-1 and yi-1, etc)
Use b[i, j] to remember where to extract an
element of an LCS.
Mashiour Rahman AIUB::CSC2105::Algorithms Dynamic Programming52
LCS: Recurrence
int
int lcsRec(
lcsRec(int
int i,
i, int
int j)
j) {{
if
if (i==0
(i==0 ||
|| j==0)
j==0) return
return 0;
0;
else
else if
if (x[i]
(x[i] ==
== y[j])
y[j])
return
return lcsRec(i-1,j-1)
lcsRec(i-1,j-1) ++ 1;
1;
else
else
return
return max(lcsRec(i-1,j),lcsRec(i,j-1));
max(lcsRec(i-1,j),lcsRec(i,j-1));
}}
Recurrence for time complexity: T(2n)=2T(2n-1)
T(2n)=T(2n-2)+1 if x[n]=y[n] =2(2T(2n-2))
T(2n)=2T(2n-1) if x[n]!=y[n] =4T(2n-2)
T(2n)=1 if n=0 =4(2T(2n-3))
=8T(2n-3)
=2iT(2n-i)
= 22n = 4n
Mashiour Rahman AIUB::CSC2105::Algorithms Dynamic Programming53
LCS: Recurrence
int
int lcsMemo(
lcsMemo(int
int i,
i, int
int j)
j) {{
if
if (c[i][j]
(c[i][j] !=
!= -1)
-1) return
return c[i][j]
c[i][j]
else
else if
if (x[i]
(x[i] ==
== y[j])
y[j]) {{
c[i][j]
c[i][j] == lcsMemo(i-1,j-1)
lcsMemo(i-1,j-1) ++ 11
return
return c[i][j]
c[i][j]
}}
else
else {{
c[i][j]=max(lcsMemo(i-1,j),lcsMemo(i,j-1))
c[i][j]=max(lcsMemo(i-1,j),lcsMemo(i,j-1))
return
return c[i][j]
c[i][j]
}}
}}
c String x
T(n) = O(n2)
String y
Mashiour Rahman AIUB::CSC2105::Algorithms Dynamic Programming54
LCS: Computing Length
LCS-Length(X,
LCS-Length(X, Y, Y, m,m, n)
n)
11 for
for i1 i1 to to mm do do
22 c[i,0] 0
c[i,0] 0
33 for
for j0 j0 to to nn do do
44 c[0,j] 0
c[0,j] 0
55 for
for i1 i1 to to mm do do
66 for
for j1 j1 to to nn dodo
77 if
if xxii == yyjj then
then
88 c[i,j] c[i-1,j-1]+1
c[i,j] c[i-1,j-1]+1
99 b[i,j] ”copy”
b[i,j] ”copy”
10 else
10 else if c[i-1,j]
if c[i-1,j] c[i,j-1]
c[i,j-1] then
then
11
11 c[i,j] c[i-1,j]
c[i,j] c[i-1,j]
12
12 b[i,j] ”skipX”
b[i,j] ”skipX”
13
13 else
else
14
14 c[i,j] c[i,j-1]
c[i,j] c[i,j-1]
15
15 b[i,j] ”skipY”
b[i,j] ”skipY”
16
16 return
return c, c, bb
Mashiour Rahman AIUB::CSC2105::Algorithms Dynamic Programming55
LCS: Example
0, if i=0, j=0
c[i,j] = c[i-1,j-1]+1 if i,j>0 and xi = yj
max ( c[i,j-1], c[i-1,j] ) if i,j>0 and xi ≠ yi
X a b b c a a c
Y 0 0 0 0 0 0 0 0
a 0
c 0
c 0
b 0
c 0
c 0
a 0
Mashiour Rahman AIUB::CSC2105::Algorithms Dynamic Programming56
LCS: Example
0, if i=0, j=0
c[i,j] = c[i-1,j-1]+1 if i,j>0 and xi = yj
max ( c[i,j-1], c[i-1,j] ) if i,j>0 and xi ≠ yi
a b b c a a c
0 0 0 0 0 0 0 0
a 0
c 0
c 0
b 0
c 0
c 0
a 0
Mashiour Rahman AIUB::CSC2105::Algorithms Dynamic Programming57
LCS: Example
0, if i=0, j=0
c[i,j] = c[i-1,j-1]+1 if i,j>0 and xi = yj
max ( c[i,j-1], c[i-1,j] ) if i,j>0 and xi ≠ yi
a b b c a a c
0 0 0 0 0 0 0 0
a 0
c 0
c 0
b 0
c 0
c 0
a 0
Mashiour Rahman AIUB::CSC2105::Algorithms Dynamic Programming58
LCS: Example
0, if i=0, j=0
c[i,j] = c[i-1,j-1]+1 if i,j>0 and xi = yj
max(c[i,j-1],c[i-1,j]) if i,j>0 and xi ≠ yi
a b b c a a c
0 0 0 0 0 0 0 0
a 0 1 1 1 1 1 1 1
c 0 1 1 1 2 2 2 2
c 0 1 1 1 2 2 2 3
b 0 1 2 2 2 2 2 3
c 0 1 2 2 3 3 3 3
c 0 1 2 2 3 3 3 4
a 0 1 2 2 3 4 4 4
Mashiour Rahman AIUB::CSC2105::Algorithms Dynamic Programming59
Constructing an LCS
Print-LCS(b, X, i, j)
1 if i = 0 or j = 0 then
2 return
3 if b[i,j] = “copy" then
4 Print-LCS(b,X,i-1,j-1)
5 print x[i]
6 elseif b[i,j]=“skipX" then
7 Print-LCS(b,X,i-1,j)
8 else
Print-LCS(b,X,i,j-1)
length[X] = m, length[Y] = n,
Call Print-LCS(b, X, n, m) to construct LCS
Time complexity: O(m+n).
Mashiour Rahman AIUB::CSC2105::Algorithms Dynamic Programming60
LCS: Example
0, if i=0, j=0
c[i,j] = c[i-1,j-1]+1 if i,j>0 and xi = yj
max(c[i,j-1],c[i-1,j]) if i,j>0 and xi ≠ yi
a b b c a a c
0 0 0 0 0 0 0 0
a 0 1 1 1 1 1 1 1
c 0 1 1 1 2 2 2 2
c 0 1 1 1 2 2 2 3
b 0 1 2 2 2 2 2 3
c 0 1 2 2 3 3 3 3
c 0 1 2 2 3 3 3 4
a 0 1 2 2 3 4 4 4
Mashiour Rahman AIUB::CSC2105::Algorithms Dynamic Programming61
Longest Common Subsequence
There is a need to quantify how similar they
are:
Comparing DNA sequences in studies of evolution
of different species
Spell checkers
Editing
Mashiour Rahman AIUB::CSC2105::Algorithms Dynamic Programming62
References & Readings
CLRS:
15.2, 15.3, 15.4
Exercises: 15.2-1, 15.2-2, 15.2-3, 15.3-2, 15.4-1,
15.4-3, 15.4-5, 15.4-6.
Problems: 15-3.
HSR:
5.6
Mashiour Rahman AIUB::CSC2105::Algorithms Dynamic Programming63