Dynamic Programming - Algorithm

Download as ppt, pdf, or txt
Download as ppt, pdf, or txt
You are on page 1of 63

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 Programming2


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 Programming3


…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 Programming4


…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 Programming5


…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 Programming6


…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 Programming7
…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 Programming8
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 Programming9


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 Programming10


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 Programming11


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 Programming12


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 Programming13


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 Programming14


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 Programming15


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 Programming16


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 Programming17
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 Programming18


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 Programming19
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 Programming20


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 Programming21
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 Programming22


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 Programming23


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 Programming24


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 Programming25


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 Programming26


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 Programming27


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 Programming28


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 Programming29


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 Programming30


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 kj
M(i,k) M(k  1,j) di1 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 Programming31
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 Programming32


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 Programming33


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 Programming34
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 Programming35
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 Programming36


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 Programming37
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 Programming38


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 Programming39


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 Programming40
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 Programming41


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 Programming42
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 Programming43


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 Programming44
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 Programming45


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 Programming46
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 Programming47
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 Programming48


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 Programming49


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 Programming50


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 Programming51
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 Programming52
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 Programming53
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 Programming54


LCS: Computing Length
LCS-Length(X,
LCS-Length(X, Y, Y, m,m, n)
n)
11 for
for i1 i1 to to mm do do
22 c[i,0] 0
c[i,0] 0
33 for
for j0 j0 to to nn do do
44 c[0,j] 0
c[0,j] 0
55 for
for i1 i1 to to mm do do
66 for
for j1 j1 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 Programming55
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 Programming56


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 Programming57


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 Programming58


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 Programming59


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 Programming60


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 Programming61


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 Programming62


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 Programming63

You might also like