Recursive algorithm inefficient because it recomputes the same F(i) repeatedly in different branches of the recursion tree.
CE100 Algorithms and Programming II
Problem 1: Fibonacci Numbers Bottom-up Computation
Reminder:
F(0)=0 and F(1)=1F(n)=F(n−1)+F(n−2)
RuntimeΘ(n)
ITER-FIBO(n)
F[0] = 0F[1] = 1for i = 2 to n do
F[i] = F[i-1] + F[i-2]
returnF[n]
CE100 Algorithms and Programming II
Optimization Problems
DP typically applied to optimization problems
In an optimization problem
There are many possible solutions (feasible solutions)
Each solution has a value
Want to find an optimal solution to the problem
A solution with the optimal value (min or max value)
Wrong to say the optimal solution to the problem
There may be several solutions with the same optimal value
CE100 Algorithms and Programming II
Development of a DP Algorithm
Step-1. Characterize the structure of an optimal solution Step-2. Recursively define the value of an optimal solution Step-3. Compute the value of an optimal solution in a bottom-up fashion Step-4. Construct an optimal solution from the information computed in Step 3
CE100 Algorithms and Programming II
Problem 2: Matric Chain Multiplication
Input: a sequence (chain) ⟨A1,A2,…,An⟩ of n matrices
Aim: compute the product A1⋅A2⋅…An
A product of matrices is fully parenthesized if
It is either a single matrix
Or, the product of two fully parenthesized matrix products surrounded by a pair of parentheses. (Ai(Ai+1Ai+2…Aj)) ((AiAi+1Ai+2…Aj−1)Aj) ((AiAi+1Ai+2…Ak)(Ak+1Ak+2…Aj)) for i≤k<j
All parenthesizations yield the same product; matrix product is associative
CE100 Algorithms and Programming II
Matrix-chain Multiplication: An Example Parenthesization
Input:⟨A1,A2,A3,A4⟩ (5 distinct ways of full parenthesization)
The way we parenthesize a chain of matrices can have a dramatic effect on the cost of computing the product
CE100 Algorithms and Programming II
Matrix-chain Multiplication: Reminder
MATRIX-MULTIPLY(A, B)
if cols[A]!=rows[B] then
error(“incompatible dimensions”)
for i=1 to rows[A] do
for j=1 to cols[B] do
C[i,j]=0for k=1 to cols[A] do
C[i,j]=C[i,j]+A[i,k]·B[k,j]
return C
CE100 Algorithms and Programming II
Matrix Chain Multiplication: Example
A1:10x100, A2:100x5, A3:5x50
Which paranthesization is better? (A1A2)A3 or A1(A2A3)?
CE100 Algorithms and Programming II
Matrix Chain Multiplication: Example
A1:10×100, A2:100×5, A3:5×50
Which paranthesization is better? (A1A2)A3 or A1(A2A3)?
CE100 Algorithms and Programming II
Matrix Chain Multiplication: Example
A1:10×100, A2:100×5, A3:5×50
Which paranthesization is better? (A1A2)A3 or A1(A2A3)?
In summary:
(A1A2)A3 = # of multiply-add ops: 7500
A1(A2A3) = # of multiple-add ops: 75000
First parenthesization yields 10x faster computation
CE100 Algorithms and Programming II
Matrix-chain Multiplication Problem
Input: A chain ⟨A1,A2,…,An⟩ of n matrices,
where Ai is a pi−1×pi matrix
Objective: Fully parenthesize the product
A1⋅A2…An
such that the number of scalar mult-adds is minimized.
CE100 Algorithms and Programming II
Counting the Number of Parenthesizations
Brute force approach: exhaustively check all parenthesizations
P(n): # of parenthesizations of a sequence of n matrices
We can split sequence between kth and (k+1)st matrices for any k=1,2,…,n−1 , then parenthesize the two resulting sequences independently, i.e.,
(A1A2A3…Ak)(break−pointAk+1Ak+2…An)
We obtain the recurrence
P(1)=1 and P(n)=k=1∑n−1P(k)P(n−k)
CE100 Algorithms and Programming II
Number of Parenthesizations:
P(1)=1 and P(n)=k=1∑n−1P(k)P(n−k)
The recurrence generates the sequence of Catalan Numbers Solution is P(n)=C(n−1) where
C(n)=n+11(n2n)=Ω(4n/n3/2)
The number of solutions is exponential in n
Therefore, brute force approach is a poor strategy
CE100 Algorithms and Programming II
The Structure of Optimal Parenthesization
Notation:Ai..j: The matrix that results from evaluation of the product: AiAi+1Ai+2…Aj
Observation: Consider the last multiplication operation in any parenthesization: (A1A2…Ak)⋅(Ak+1Ak+2…An)
There is a k value (1≤k<n) such that:
First, the product A1…k is computed
Then, the product Ak+1…n is computed
Finally, the matrices A1…k and Ak+1…n are multiplied
CE100 Algorithms and Programming II
Step 1: Characterize the Structure of an Optimal Solution
An optimal parenthesization of product A1A2…An will be: (A1A2…Ak)⋅(Ak+1Ak+2…An) for some k value
The cost of this optimal parenthesization will be: = Cost of computing A1…k + Cost of computing Ak+1…n + Cost of multiplying A1…k⋅Ak+1…n
CE100 Algorithms and Programming II
Step 1: Characterize the Structure of an Optimal Solution
Key observation: Given optimal parenthesization
(A1A2A3…Ak)⋅(Ak+1Ak+2…An)
Parenthesization of the subchain A1A2A3…Ak
Parenthesization of the subchain Ak+1Ak+2…An
should both be optimal
Thus, optimal solution to an instance of the problem contains optimal solutions to subproblem instances
i.e., optimal substructure within an optimal solution exists.
CE100 Algorithms and Programming II
Step 2: A Recursive Solution
Step 2: Define the value of an optimal solution recursively in terms of optimal solutions to the subproblems
Assume we are trying to determine the min cost of computing Ai…j
mi,j: min # of scalar multiply-add opns needed to compute Ai…j
Note:The optimal cost of the original problem: m1,n
How to compute mi,j recursively?
CE100 Algorithms and Programming II
Step 2: A Recursive Solution
Base case: mi,i=0 (single matrix, no multiplication)
Let the size of matrix Ai be (pi−1×pi)
Consider an optimal parenthesization of chain
Ai…Aj:(Ai…Ak)⋅(Ak+1…Aj)
The optimal cost: mi,j=mi,k+mk+1,j+pi−1×pk×pj
where:
mi,k: Optimal cost of computing Ai…k
mk+1,j: Optimal cost of computing Ak+1…j
pi−1×pk×pj : Cost of multiplying Ai…k and Ak+1…j
CE100 Algorithms and Programming II
Step 2: A Recursive Solution
In an optimal parenthesization: k must be chosen to minimize mij
The mij values give the costs of optimal solutions to subproblems
In order to keep track of how to construct an optimal solution
Define sij to be the value of k which yields the optimal split of the subchain Ai…j
That is, sij=k such that
mij=mik+mk+1,j+pi−1pkpj holds
CE100 Algorithms and Programming II
Direct Recursion: Inefficient!
Recursive Matrix-Chain (RMC) Order
RMC(p,i,j)
if (i == j) then
return0
m[i, j] = INF
for k=i to j-1 do
q = RMC(p, i, k) + RMC(p, k+1, j) + p_{i-1} p_k p_j
if q < m[i, j] then
m[i, j] = q
endfor
return m[i, j]
CE100 Algorithms and Programming II
Direct Recursion: Inefficient!
Recursion tree for RMC(p,1,4)
Nodes are labeled with i and j values
CE100 Algorithms and Programming II
Computing the Optimal Cost (Matrix-Chain Multiplication)
An important observation:
We have relatively few subproblems
one problem for each choice of i and j satisfying 1≤i≤j≤n
total n+(n−1)+⋯+2+1=21n(n+1)=Θ(n2) subproblems
We can write a recursive algorithm based on recurrence.
However, a recursive algorithm may encounter each subproblem many times in different branches of the recursion tree
This property, overlapping subproblems, is the second important feature for applicability of dynamic programming
CE100 Algorithms and Programming II
Computing the Optimal Cost (Matrix-Chain Multiplication)
Compute the value of an optimal solution in a bottom-up fashion
matrix Ai has dimensions pi−1×pi for i=1,2,…,n
the input is a sequence ⟨p0,p1,…,pn⟩ where length[p]=n+1
Procedure uses the following auxiliary tables:
m[1…n,1…n]: for storing the m[i,j] costs
s[1…n,1…n]: records which index of k achieved the optimal cost in computing m[i,j]
CE100 Algorithms and Programming II
Bottom-Up Computation
How to choose the order in which we process mij values?
Before computing mij, we have to make sure that the values for mik and mk+1,j have been computed for all k.
mij=i≤k<jMIN{mik+mk+1,j+pi−1pkpj}
CE100 Algorithms and Programming II
Bottom-Up Computation
mij=i≤k<jMIN{mik+mk+1,j+pi−1pkpj}
mij must be processed after mik and mj,k+1
Reminder:mij computed only for j>i
CE100 Algorithms and Programming II
Bottom-Up Computation
mij=i≤k<jMIN{mik+mk+1,j+pi−1pkpj}
mij must be processed after mik and mj,k+1
How to set up the iterations over i and j to compute mij?
CE100 Algorithms and Programming II
Bottom-Up Computation
mij=i≤k<jMIN{mik+mk+1,j+pi−1pkpj}
If the entries mij are computed in the shown order, then mik and mk+1,j values are guaranteed to be computed before mij.
CE100 Algorithms and Programming II
Bottom-Up Computation
mij=i≤k<jMIN{mik+mk+1,j+pi−1pkpj}
CE100 Algorithms and Programming II
Bottom-Up Computation
mij=i≤k<jMIN{mik+mk+1,j+pi−1pkpj}
CE100 Algorithms and Programming II
Algorithm for Computing the Optimal Costs
Note: l =ℓ and p_{i-1} p_k p_j =pi−1pkpj
MATRIX-CHAIN-ORDER(p)
n = length[p]-1for i=1 to n do
m[i, i]=0
endfor
for l=2 to n do
for i=1 to n n-l+1 do
j=i+l-1
m[i, j]=INF
for k=i to j-1 do
q=m[i,k]+m[k+1, j]+p_{i-1} p_k p_j
if q < m[i,j] then
m[i,j]=q
s[i,j]=k
endfor
endfor
endfor
return m and s
CE100 Algorithms and Programming II
Algorithm for Computing the Optimal Costs
The algorithm first computes
m[i,i]←0 for i=1,2,…,n min costs for all chains of length 1
Then, for ℓ=2,3,…,n computes
m[i,i+ℓ−1] for i=1,…,n−ℓ+1 min costs for all chains of length ℓ
For each value of ℓ=2,3,…,n,
m[i,i+ℓ−1] depends only on table entries m[i,k]&m[k+1,i+ℓ−1] for i≤k<i+ℓ−1, which are already computed
CE100 Algorithms and Programming II
Algorithm for Computing the Optimal Costs
compute m[i,i+1](n−1) values{m[1,2],m[2,3],…,m[n−1,n]}compute m[i,i+2](n−2) values{m[1,3],m[2,4],…,m[n−2,n]}compute m[i,i+3](n−3) values{m[1,4],m[2,5],…,m[n−3,n]}⎩⎨⎧ℓ=2for i=1 to n−1 do m[i,i+1]=∞for k=i to i do ⋮⎩⎨⎧ℓ=3for i=1 to n−2 do m[i,i+2]=∞for k=i to i+1 do ⋮⎩⎨⎧ℓ=4for i=1 to n−3 do m[i,i+3]=∞for k=i to i+2 do ⋮
CE100 Algorithms and Programming II
Table access pattern in computing m[i,j]s for ℓ=j−i+1
fork←itoj−1doq←m[i,k]+m[k+1,j]+pi−1pkpj
CE100 Algorithms and Programming II
Table access pattern in computing m[i,j]s for ℓ=j−i+1
((Ai)⋮mult.(Ai+1Ai+2…Aj))
CE100 Algorithms and Programming II
Table access pattern in computing m[i,j]s for ℓ=j−i+1
((AiAi+1)⋮mult.(Ai+2…Aj))
CE100 Algorithms and Programming II
Table access pattern in computing m[i,j]s for ℓ=j−i+1
((AiAi+1Ai+2)⋮mult.(Ai+3…Aj))
CE100 Algorithms and Programming II
Table access pattern in computing m[i,j]s for ℓ=j−i+1