Algorithms - Lecture 5 (Dynamic Programming 1)
Algorithms - Lecture 5 (Dynamic Programming 1)
Ahmed Kosba
3
Examples covered in this lecture
• Fibonacci numbers
• Rod cutting problem
• Matrix-chain multiplication
4
Computing Fibonacci Numbers
• Fibonacci numbers: 0, 1, 1, 2, 3, 5, 8, …
F0 = 0, F1 = 1
Fi = Fi-1 + Fi-2 for i > 1
• Compute the nth Fibonacci number recursively (n ≥ 0):
Fib(n)
if (n == 0 or n == 1)
return n
return Fib(n-1) + Fib(n-2)
Running time? T(n) = T(n-1) + T(n-2) + θ(1)
Note: This is simplified. θ(1) is not accurate here, as the numbers grow 1 with n,
i.e., the addition won’t be constant-time.
1 5
The nth Fibonacci number is θ(n)-bit long.
Computing Fibonacci Numbers
• Based on the recurrence, the running time of the
naïve recursive algorithm is O(2n) and Ω(2n/2).
• Exercise: Verify the upper and lower bounds.
• What can you observe about the recursion tree of the
previous algorithm?
Subproblems appear multiple times.
Fib(n)
Fib(n-2) Fib(n-1)
Fib(n-3) Fib(n-4)
6
Computing Fibonacci Numbers
• How to avoid the unnecessary cost of the previous
implementation?
• Two methods:
• Top-down approach: Use the recursive approach, but
with memoization.
• Store the solutions of subproblems.
• Bottom-up approach: Compute the solutions of the
smaller subproblems first.
• A dependency graph of the subproblems can be built and used
to infer which problems to do first.
7
Computing Fibonacci Numbers
• Top-down approach with memoization:
• Use an array F of size n to store the results of the
subproblems.
• Assume all F[i] are initialized to 0 at the beginning.
Fib(n)
if (n == 0 or n == 1)
return n
if (F[n] == 0)
F[n] = Fib(n-1) + Fib(n-2)
return F[n]
8
Computing Fibonacci Numbers
• Bottom-up approach:
• Compute the solutions to the small subproblems first,
and use them to compute the solutions of larger
subproblems.
Fib(n)
F[0] = 0
F[1] = 1
for(i = 2 to n)
F[i] = F[i-1] + F[i-2]
return F[n]
Note: The above solution can be done using constant space without
having to store all the previous solutions.
9
Computing Fibonacci Numbers
• There are other ways to compute Fibonacci
numbers but they are out of the context of this
lecture.
𝜑𝑛
• Method 1: 𝐹𝑛 = rounded to the nearest integer,
√5
where 𝜑 is the golden ratio. (Section 3.2 in CLRS)
• A problem with this approach is the floating-point errors.
• Method 2:
𝐹𝑛 𝑛 𝐹0
0 1
= .
𝐹𝑛+1 1 1 𝐹1
11
Rod Cutting Problem
• Example from CLRS notes:
n=8
i 1 2 3 4 5 6 7 8
pi 1 5 8 9 10 17 17 20
Solution?
Max possible revenue = 22
This is obtained by cutting the rod into pieces of lengths 2 and 6.
12
Rod Cutting Problem
• Attempt 1:
• Choose based on the maximum price per inch.
i 1 2 3 4 5 6 7 8
pi 1 5 8 9 10 17 17 20
pi / i 1 2.5 2.67 2.25 2 2.83 2.42 2.5
i 1 2 3 4 5 6 7 8
pi 1 5 8 9 10 17 17 20
pi / i 1 2.5 2.67 2.25 2 2.83 2.42 2.5
So, the chosen cut is (6, 2)
What is the problem with this approach? 13
Rod Cutting Problem
• Counter example for attempt 1:
• Assume the rod was 4 inches only.
i 1 2 3 4
pi 1 5 8 9
pi / i 1 2.5 2.67 2.25
• If the piece with the maximum price per inch is selected first,
then (3,1) will be the proposed cut, but this won't be optimal.
• (2, 2) is the optimal solution here.
• The price of (3, 1) is 9, while the price for (2, 2) is 10.
Cut at position i
17
Rod Cutting Problem
A simpler way to view the problem: Find max revenue for a
p1 +
rod of length n - 1
Every decomposition of the rod starts
with a first piece of length i followed
Find max revenue for a
by a decomposition of the remainder p2 +
rod of length n - 2
(n – i) inches.
18
Rod Cutting Problem
Naïve Algorithm
Cut-Rod(p, n)
Pseudocode from CLRS
if n == 0
return 0
q = -∞
for(i = 1 to n) How efficient is this algorithm?
q= max(q, p[i] + Cut-Rod(p, n- i))
return q
4
2 1 0 1 0 0
As in the first example, the
subproblems overlap. 1 0 0 0
19
0
Rod Cutting Problem
Naïve Algorithm
• Runtime of the naïve recursive algorithm:
• Let 𝑇 𝑛 be the number of calls to Cut-Rod
𝑇 0 =1
𝑛−1
𝑇 𝑛 = 1 + Σ𝑗=0 𝑇(𝑗)
• It can be shown that 𝑇 𝑛 = 2n
20
Rod Cutting Problem
Bottom-up Approach
Pseudocode from CLRS
21
Rod Cutting Problem
Top-down approach with Memoization
Pseudocode from CLRS
Initialize memo.
Running time
of MEMOIZED-
Check if the problem was solved before. CUT-ROD:
Θ(n2)
23
0
Rod Cutting Problem
Reconstructing a solution:
Original goal: return the actual piece sizes (not just
the price).
Pseudocode from CLRS
Store the size of the first piece that would lead to the
maximum revenue for a rod of size j.
24
Rod Cutting Problem
• Trace the previous algorithm for n = 8, and p
defined as follows:
i 1 2 3 4 5 6 7 8
pi 1 5 8 9 10 17 17 20
i 0 1 2 3 4 5 6 7 8
r[i] 0 1 5 8 10 13 17 18 22
s[i] 0 1 2 3 2 2 6 1 2
To construct the solution, note that s[n] will have the length of the first piece
that would lead to the optimal solution for a rod of length n.
As s[8] = 2, the length of the first piece should be 2.
The next piece length can be found by s[8 - 2] = s[6] = 6.
In the general case, this continues till we reach s[0].
(Pseudocode of reconstruction is in CLRS – Simple while loop)
25
Dynamic Programming Paradigm
- Study the structure of the optimal solution.
- Find a recursive definition.
- Compute the value of the optimal solution using
either
- a bottom-up approach, or
- a top-down approach with memoization.
- Construct an optimal solution.
26
Examples covered in this lecture
• Fibonacci numbers
• Rod cutting problem
• Matrix-chain multiplication
27
Matrix-chain Multiplication [CLRS 15.2]
Given a sequence of n matrices A1, A2, .. , An, the goal is to
compute their product
A1A2 … An
Determine a way for multiplying the matrices with the lowest
possible cost (min. number of scalar multiplications).
30
Matrix-chain Multiplication
• Let m[i, j] be the minimum number of scalar
multiplications need to compute 𝐴𝑖 𝐴𝑖+1 … 𝐴𝑗
• Each 𝐴𝑖 is a 𝑝𝑖−1 × 𝑝𝑖 matrix.
• Suppose 𝐴𝑖 𝐴𝑖+1 … 𝐴𝑗 is parenthesized as
(𝐴𝑖 𝐴𝑖+1 … 𝐴𝑘 )(𝐴𝑘+1 𝐴𝑘+2 … 𝐴𝑗 )
The optimal cost for this will be
m[i, k] + m[k+1, j] + 𝑝𝑖−1 𝑝𝑘 𝑝𝑗
• There are possible j – i ways to do the
parenthesizations.
• Need to select k that would lead to the minimum
cost. 31
Matrix-chain Multiplication
Recursive definition for m[i, j]
m[i, j] = 0 if i = j
m[i, j] = min {m[i, k] + m[k+1, j] + 𝑝𝑖−1 𝑝𝑘 𝑝𝑗 } if i < j
i≤k<j
32
Matrix-chain Multiplication
Subproblem dependencies
[1, 4]
[1, 3] [2, 4]
34
Matrix-chain Multiplication
Bottom-up approach
• Example: Find the optimal way to multiply A1A2A3A4
matrix A1 A2 A3 A4
dimension 30 x 35 35 x 15 15 x 5 5 x 10
j
1 2 3 4
1 0
2 0
i
3 0
4 0
35
Matrix-chain Multiplication
Bottom-up approach
• Example: Find the optimal way to multiply A1A2A3A4
matrix A1 A2 A3 A4
dimension 30 x 35 35 x 15 15 x 5 5 x 10
j
1 2 3 4
1 0 m[1,2] = m[1,1] + m[2,2] + p0p1p2
36
Matrix-chain Multiplication
Bottom-up approach
• Example: Find the optimal way to multiply A1A2A3A4
matrix A1 A2 A3 A4
dimension 30 x 35 35 x 15 15 x 5 5 x 10
j
1 2 3 4
1 0 15750
2 0 2625
i
3 0 750
4 0
37
Matrix-chain Multiplication
Bottom-up approach
• Example: Find the optimal way to multiply A1A2A3A4
matrix A1 A2 A3 A4
dimension 30 x 35 35 x 15 15 x 5 5 x 10
j
1 2 3 4
1 0 15750 m[1,3] = min( m[1,1] + m[2,3] + p0p1p3 ,
m[1,2] + m[3,3] + p0p2p3 )
2 0 2625
i
3 0 750
m[2,4] = min( m[2,2] + m[3,4] + p1p2p4 ,
4 0 m[2,3] + m[4,4] + p1p3p4 )
m
The colored expressions will lead to the minimum value for m[I, j] at the specified i, j.
38
As we will see later, it will help to keep track of which k led to the minimum.
Matrix-chain Multiplication
Bottom-up approach
• Example: Find the optimal way to multiply A1A2A3A4
matrix A1 A2 A3 A4
dimension 30 x 35 35 x 15 15 x 5 5 x 10
j
1 2 3 4
1 0 15750 7875
2 0 2625 4375
i
3 0 750
4 0
39
Matrix-chain Multiplication
Bottom-up approach
• Example: Find the optimal way to multiply A1A2A3A4
matrix A1 A2 A3 A4
dimension 30 x 35 35 x 15 15 x 5 5 x 10
j
1 2 3 4
1 0 15750 7875 m[1,4] = min( m[1, 1] + m[2, 4] + 𝑝0 𝑝1 𝑝4
m[1, 2] + m[3, 4] + 𝑝0 𝑝2 𝑝4
2 0 2625 4375
i m[1, 3] + m[4, 4] + 𝑝0 𝑝3 𝑝4 )
3 0 750
4 0
40
Matrix-chain Multiplication
Bottom-up approach
• Example: Find the optimal way to multiply A1A2A3A4
matrix A1 A2 A3 A4
dimension 30 x 35 35 x 15 15 x 5 5 x 10
j
1 2 3 4
1 0 15750 7875 9375
2 0 2625 4375
i How to construct the optimal solution?
3 0 750
4 0
41
Matrix-chain Multiplication
Bottom-up approach
• Example: Find the optimal way to multiply A1A2A3A4
matrix A1 A2 A3 A4
dimension 30 x 35 35 x 15 15 x 5 5 x 10
j
1 2 3 4
1 0 15750 7875 9375
2 0 2625 4375
i How to construct the optimal solution?
3 0 750
As before, we can maintain an auxiliary data
4 0 structure along the way.
42
Matrix-chain Multiplication
Bottom-up approach
• Example: Find the optimal way to multiply A1A2A3A4
matrix A1 A2 A3 A4
dimension 30 x 35 35 x 15 15 x 5 5 x 10
j j
1 2 3 4 1 2 3 4
1 0 15750 7875 9375 1 1 1 3
2 0 2625 4375 2 2 3
i i
3 0 750 3 3
4 0 4
m s
s[i,j] = the value of k that led to the optimal
value for m[i,j]
Matrix-chain Multiplication
Bottom-up approach
• Example: Find the optimal way to multiply A1A2A3A4
matrix A1 A2 A3 A4
dimension 30 x 35 35 x 15 15 x 5 5 x 10
j
Given the matrix s, how to construct an optimal
1 2 3 4
solution for A1A2A3A4?
1 1 1 3 • Check s[1, 4] first. Since s[1,4] = 3, this means
2 2 3 that the best way to multiply would be
i (A1A2A3 )A4
3 3 • However, this does not answer how A1A2A3
4 should be multiplied. To find this, check s[1, 3].
Since s[1,3] = 1, the best way would be A1(A2A3)
s • Therefore, the best way would be (A1(A2A3))A4
Matrix-chain Multiplication
Bottom-up approach
• Note: The example in the CLRS book draws the
matrices in a different way, but it is the same
method.
47