Post on 05-Mar-2021
TU/e Algorithms (2IL15) – Lecture 3
1
Algorithms (2IL15) – Lecture 3
DYNAMIC PROGRAMMING
0
0 0
0 0
0 0
0 0
0
TU/e Algorithms (2IL15) – Lecture 3
2
Optimization problems
for each instance there are (possibly) multiple valid solutions
goal is to find an optimal solution
• minimization problem:
associate cost to every solution, find min-cost solution
• maximization problem:
associate profit to every solution, find max-profit solution
TU/e Algorithms (2IL15) – Lecture 3
3
Techniques for optimization
optimization problems typically involve making choices
backtracking: just try all solutions
can be applied to almost all problems, but gives very slow algorithms
try all options for first choice,
for each option, recursively make other choices
greedy algorithms: construct solution iteratively, always make choice that seems best
can be applied to few problems, but gives fast algorithms
only try option that seems best for first choice (greedy choice),
recursively make other choices
dynamic programming
in between: not as fast as greedy, but works for more problems
TU/e Algorithms (2IL15) – Lecture 3
4
Algorithms for optimization: how to improve on backtracking
for greedy algorithms
1. try to discover structure of optimal solutions: what properties do optimal solutions have ? what are the choices that need to be made ? do we have optimal substructure ?
optimal solution = first choice + optimal solution for subproblem do we have greedy-choice property for the first choice ?
what if we do not have a good greedy choice? then we can often use dynamic programming
TU/e Algorithms (2IL15) – Lecture 3
Dynamic programming: examples
maximum weight independent set (non-adjacent vertices) in path graph
optimal matrix-chain multiplication: today
more examples in book and next week
5
1 4 5 4
TU/e Algorithms (2IL15) – Lecture 3
6
Matrix-chain multiplication
Input: n matrices A1, A2, …, An
Required output: A1 • A2 • … • An
= a
b c
a
c
a x b matrix b
b x c matrix
a x c matrix
cost = a∙b∙c scalar multiplications = Θ(a∙b∙c ) time
multiplying two matrices
TU/e Algorithms (2IL15) – Lecture 3
7
Matrix-chain mutiplication
Multiplying three matrices:
A • B • C
2 x 10 10 x 50 50 x 20
Does it matter in which order we multiply?
Note for answer: (A•B)•C = A•(B•C) matrix multiplication is associative:
What about the cost?
(A•B)•C costs (2∙10∙50) + (2∙50∙20) = 3,000 scalar multiplications
A•(B•C) costs (10∙50∙20) + (2∙10∙20) = 10,400 scalar multiplications
TU/e Algorithms (2IL15) – Lecture 3
8
Matrix-chain multiplication: the optimization problem
Input: n matrices A1, A2, …, An, where Ai is pi-1 x pi matrix
In fact: we only need p0, … ,pn as input Required output: an order to multiply the matrices minimizing the cost
in other words: the best way to place brackets
So we have
valid solution = complete parenthesization: ((A1 • A2 ) • (A3 •(A4 •(A5 • A6 ))))
cost = total number of scalar multiplications needed to multiply
according to the given parenthesization
TU/e Algorithms (2IL15) – Lecture 3
9
(A1 • (A2 • A3 ) ) • ( (A4 • A5) • (A6 • A7) )
choice: final multiplication optimal way to multiply A1 ,…, A3
optimal way to multiply A4 ,…, A7
optimal substructure: optimal solution is composed of optimal solutions to subproblems of same type as original problem
optimal solution
necessary for dynamic programming (and for greedy)
Let’s study the structure of an optimal solution
what are the choices that need to be made?
what are the subproblems that remain? do we have optimal substructure?
TU/e Algorithms (2IL15) – Lecture 3
10
(A1 • (A2 • A3 ) ) • ( (A4 • A5) • (A6 • A7) ) optimal solution
Let’s study the structure of an optimal solution
what are the choices that need to be made?
what are the subproblems that remain? do we have optimal substructure?
choice: final multiplication
Do we have a good greedy choice ?
no …
then what to do?
try all possible options for position of final multiplication
TU/e Algorithms (2IL15) – Lecture 3
11
Approach:
try all possible options for final multiplication
for each option recursively solve subproblems
Need to specify exactly what the subproblems are
initial problem: compute A1 • … • An in cheapest way
(A1 • … • Ak ) • ( Ak+1 • … • An )
subproblem: compute A1 • … • Ak in cheapest way
(A1 • … • Ai) • ( Ai+1 • … • Ak )
subproblem: compute Ai+1 • … • Ak in cheapest way
general form: given i,j with 1≤i<j ≤n, compute Ai • … • Aj in cheapest way
TU/e Algorithms (2IL15) – Lecture 3
12
Now let’s prove that we indeed have optimal substructure
Subproblem: given i,j with 1≤i<j ≤n, compute Ai • … • Aj in cheapest way
Define m [ i, j ] = value of optimal solution to subproblem
= minimum cost to compute Ai • … • Aj
Lemma: m [i,j ] = 0 if i = j
min { m [i,k ] + m [k+1,j ] + pi-1 pk pj } if i < j
i≤k<j
optimal solution composed of optimal solutions to subproblems
but we don’t know the best way to decompose into subproblems
TU/e Algorithms (2IL15) – Lecture 3
13
Lemma: m [i,j ] = 0 if i = j
min { m [i,k ] + m [k+1,j ] + pi-1 pk pj } if i < j
Proof:
i=j : trivial
i<j : Consider optimal solution OPT for computing Ai • .. • Aj and let k* be the index such that OPT has the form (Ai • .. • Ak* ) • (Ak*+1 • ..• Aj ). Then
m [ i,j ] = (cost in OPT for Ai • .. • Ak* ) + (cost in OPT for Ak*+1 • .. • An) + pi-1 pk* pj
≥ m [i,k* ] + m [k*+1,j ] + pi-1 pk* pj
≥ min { m [i,k ] + m [k+1,j ] + pi-1 pk pj }
On the other hand, for any i ≤ k <j, there is a solution of cost m [i,k ] + m [k+1,j ] + pi-1 pk pj so m [ i,j ] ≤ min { m [i,k ] + m [k+1,j ] + pi-1 pk pj }.
i≤k<j
i≤k<j
i≤k<j
“cut-and-paste” argument: replace solution that OPT uses for subproblem by optimal solution to subproblem, without making overall solution worse.
TU/e Algorithms (2IL15) – Lecture 3
14
RMC (p,i, j )
\\ RMC (RecursiveMatrixChain) determines min cost for computing Ai • … • Aj
\\ p [0..n] is array such that Ai = p[i-1] x p[i ] matrix
1. if i = j
2. then
3. cost ← 0
4. else
5. cost ← ∞
6. for k ← i to j-1
7. do cost ← min(cost, RMC(p,i,k) + RMC(p,k+1,j) + pi-1 pk pj )
8. return cost
Lemma: m [i,j ] = 0 if i = j
min { m [i,k ] + m [k+1,j ] + pi-1 pk pj } if i < j i≤k<j
initial call: RMC(p[0..n],1,n)
TU/e Algorithms (2IL15) – Lecture 3
15
Correctness:
by induction and lemma on optimal substructure
Analysis of running time:
Define T(m) = worst-case running time of RMC(i,j), where m = j - i +1. Then:
T(m) = Θ(1) if m = 1 Θ(1) + ∑1≤s<m { T(s) + T(m-s) + Θ(1) } if m >1
Claim: T(m) = Ω (2m)
Proof: by induction (exercise)
Algorithm is faster than completely brute-force, but still very slow …
TU/e Algorithms (2IL15) – Lecture 3
16
(1,n)
(1,1) (2,n) (1,2) (3,n) (1,3) (4,n) … (1,n-1) (n,n)
(2,2) (3,n) (2,3) (4,n) … (2,n-1) (n,n)
(3,3) (4,n) …
overlapping subproblems, so same subproblem is solved many times
Why is the algorithm so slow?
optimal substructure + overlapping subproblems: then you can often use dynamic programming
recursive calls
TU/e Algorithms (2IL15) – Lecture 3
17
(1,n)
(1,1) (2,n) (1,2) (3,n) (1,3) (4,n) … (1,n-1) (n,n)
(2,2) (3,n) (2,3) (4,n) … (2,n-1) (n,n)
(3,3) (4,n) …
How many different subproblems are there?
subproblem: given i,j with 1≤i<j ≤n, compute Ai • … • Aj in cheapest way
number of subproblems = Θ (n2)
recursive calls
TU/e Algorithms (2IL15) – Lecture 3
18
0
0 0
0 0
0 0
0
Lemma: m [i,j ] = 0 if i = j
min { m [i,k ] + m [k+1,j ] + pi-1 pk pj } if i < j i≤k<j
Idea: fill in the values m [i,j ] in a table (that is, an array) m [1..n,1..n]
0 0
i
j
1 1 n
n
value of optimal solution to original problem
Fill in the table in an order so that the entries needed to compute a new entry are already available.
or or …
TU/e Algorithms (2IL15) – Lecture 3
19
Lemma: m [i,j ] = 0 if i = j
min { m [i,k ] + m [k+1,j ] + pi-1 pk pj } if i < j i≤k<j
MatrixChainDP ( p [0..n] )
\\ algorithm uses two-dimensional table (array) m[1..n,1..n]
to store values of solutions to subproblems
1. for i ← 1 to n
2. do m[i,i] ← 0
3. for i ← n-1 downto 1
4. do for j ← i +1 to n
5. do m[i,j] ← min { m[i,k] + m[k+1,j] + pi-1 pk pj }
6. return m[1,n] i≤k<j
TU/e Algorithms (2IL15) – Lecture 3
20
i≤k<j
∑ 1≤i≤n-1 ∑ i+1≤j≤n Θ(j-i)
= ∑ 1≤i≤n-1 ∑ 1≤j≤n-i Θ(j)
= ∑ 1≤i≤n-1 Θ((n-i)2)
= ∑ 1≤i≤n-1 Θ(i2)
= Θ(n3)
Analysis of running time
Θ(n)
Θ(1)
MatrixChainDP ( p [0..n] )
1. for i ← 1 to n
2. do m[i,i] ← 0
3. for i ← n-1 downto 1
4. do for j ← i +1 to n
5. do m[i,j] ← min { m[i,k] + m[k+1,j] + pi-1 pk pj }
6. return m[1,n]
for each of the O(n2) cells we spend O(n) time
TU/e Algorithms (2IL15) – Lecture 3
21
Designing dynamic-programming algorithms
1. Investigate structure of optimal solution: do we have optimal substructure, no greedy choice, and overlapping subproblems?
2. Give recursive formula for the value of an optimal solution
i. define subproblem in terms of a few parameters
ii. define variable m[..] = value of optimal solution for subproblem
iii. give recursive formula for m[..]
3. Algorithm: fill in table for m[..] in suitable order
4. Extend algorithm so that it computes an actual solution that is optimal, and not just the value of an optimal solution
m [i,j ] =minimum cost to compute Ai • … • Aj
given i,j with 1≤i<j ≤n, compute Ai • … • Aj in cheapest way
i≤k<j
m [i,j ] = 0 if i = j
min { m [i,k ] + m [k+1,j ] + pi-1 pk pj } if i< j
TU/e Algorithms (2IL15) – Lecture 3
22
4. Extend algorithm so that it computes an actual solution that is optimal, and not just the value of an optimal solution
i. introduce extra table that remembers choices leading to optimal solution
m [i,j ] = minimum cost to compute Ai •…• Aj
s [i,j ] = index k such that there is an optimal solution
of the form (Ai •…• Ak ) • (Ak+1•…•Aj )
ii. modify algorithm such that it also fills in the new table
iii. write another algorithm that computes an optimal solution by walking “backwards” through the new table
choice leading to opt
value of opt
TU/e Algorithms (2IL15) – Lecture 3
23
MatrixChainDP ( p [0..n] )
1. for i ← 1 to n
2. do m[i,i] ← 0
3. for i ← n-1 downto 1
4. do for j ← i +1 to n
5. do m[i,j] ← min { m[i,k] + m[k+1,j] + pi-1 pk pj }
6. return m[1,n] i≤k<j
m[i,j] ← ∞
for k ← i to j-1
do begin
cost ← m[i,k] + m[k+1,j] + pi-1 pk pj
if cost < m[i,j] then m[i,j] ← cost
end
s[i,j] ← k
TU/e Algorithms (2IL15) – Lecture 3
24
PrintParentheses ( i, j )
1. if i = j
2. then print “Ai”
3. else begin
4. print “(“
5. PrintParentheses ( i, s[i,j ] )
6. PrintParentheses ( s[i,j ]+1, j )
7. print “)”
8. end
s[i,j ] = index k such that there is an optimal solution of the form (Ai •…• Ak ) • (Ak+1•…•Aj ) to compute Ai •…• Aj
TU/e Algorithms (2IL15) – Lecture 3
25
RMC(i,j)
if i = j
1. then
2. return 0
3. else
4. cost ← ∞
5. for k ← i to j-1
6. do cost ← min(m, RMC(i,k) + RMC(k+1,j) + pi-1 pk pj )
7. return cost
initialize array m[i,j] (global variable): m[i,j] = ∞ for all 1 ≤ i,j ≤ n
if m[i,j] < ∞
then return m[i,j]
else lines 4 – 7
m[i,j] ← cost
Alternative to filling in table in suitable order: memoization
recursive algorithm, but remember which subproblems have been solved already
TU/e Algorithms (2IL15) – Lecture 3
26
Summary dynamic programming
1. Investigate structure of optimal solution: do we have optimal substructure, no greedy choice, and overlapping subproblems?
2. Give recursive formula for the value of an optimal solution
i. define subproblem in terms of a few parameters
ii. define variable m[..] = value of optimal solution for subproblem
iii. give recursive formula for m[..]
3. Algorithm: fill in table for m[..] in suitable order
4. Extend algorithm so that it computes an actual solution that is optimal, and not just the value of an optimal solution
next week more examples of dynamic programming