Académique Documents
Professionnel Documents
Culture Documents
Dynamic programming
an efficient way to implement some divide
and conquer algorithms
Fibonacci numbers …
Problem with recursive method
Fibonacci number F(n)
1 if n = 0 or 1
F(n) =
F(n-1) + F(n-2) if n > 1
n 0 1 2 3 4 5 6 7 8 9 10
F(n) 1 1 2 3 5 8 13 21 34 55 89
Pseudo
Pseudo code
code for
for the
the recursive
recursive algorithm:
algorithm:
Procedure
Procedure F(n)
F(n)
if
if n==0
n==0 or
or n==1
n==1 then
then
return
return 11
else
else
return
return F(n-1)
F(n-1) ++ F(n-2)
F(n-2) 4
(Dynamic Programming)
The execution of F(7)
F7
F6 F5
F5 F4 F4 F3
F3 F2 F3 F2 F2
F1
F4 F3 F2 F1 F0 F2 F1 F0 F1 F0
F1 F1
F3 F2 F2 F1 F0 F1 F0
F1
F1 F0 F1 F0
F2
F1
F1 F0 5
(Dynamic Programming)
The execution of F(7)
F7
F6 F5
F5 F4 F4 F3
F3 F2 F3 F2 F2
F1
F4 F3 F2 F1 F0 F2 F1 F0 F1 F0
F1 F1
F3 F2 F2 F1 F0 F1 F0
F1
F1 F0 F1 F0
F2
F1 Computation of F(2) is
F1 F0 repeated 8 times! 6
(Dynamic Programming)
The execution of F(7)
F7
F6 F5
F5 F4 F4 F3
F3 F2 F3 F2 F2
F1
F4 F3 F2 F1 F0 F2 F1 F0 F1 F0
F1 F1
F3 F2 F2 F1 F0 F1 F0
F1
F1 F0 F1 F0
F2
F1 Computation of F(3) is
F1 F0 also repeated 5 times! 7
(Dynamic Programming)
The execution of F(7)
F7
F6 F5
F5 F4 F4 F3
F3 F2 F3 F2 F2
F1
F4 F3 F2 F1 F0 F2 F1 F0 F1 F0
F1 F1
F3 F2 F2 F1 F0 F1 F0
(Dynamic Programming)
Recursive version - exponential
f(n) = f(n-1) + f(n-2) + 1 Suppose f(n)
denote the time
= [f(n-2)+f(n-3)+1]+f(n-2)+1 complexity to
compute F(n)
> 2 f(n-2)
> 2 [2 f(n-2-2)] = 22 f(n-4)
> 22 [2 f(n-4-2)] = 23 f(n-6)
… exponential in n
> 2k f(n-2k)
Can we avoid If n is even, f(n) > 2n/2 f(0) = 2n/2
exponential time? If n is odd, f(n) > f(n-1) > 2(n-1)/2
9
(Dynamic Programming)
Idea for improvement
Memorization: Procedure F(n)
Store F(i) somewhere if (v[n] < 0) then
after we have computed
its value v[n] = F(n-1)+F(n-2)
Afterward, we don’t return v[n]
need to re-compute F(i);
Main
we can retrieve its value
from our memory. set v[0] = v[1] = 1
for i = 2 to n do
[ ] refers to array v[i] = -1
( ) is parameter for calling a
procedure output F(n) 10
(Dynamic Programming)
Look at the execution of F(7)
F7
F6 F5 v[0] 1
F5 F4 F4 F3
v[1] 1
v[2] -1
F3 F2 F3 F2 F2
F1 v[3] -1
F4 F3 F2 F1 F0 F2 F1 F0 F1 F0
F1 F1
v[4] -1
F1 F0 F1 F0
-1
F3 F2 F2
v[5]
F1
F1 F0 F1
-1
F0
F2 v[6]
F1
F1 F0 v[7] -1 11
(Dynamic Programming)
Look at the execution of F(7)
F7
F6 F5 v[0] 1
F5 F4 F4 F3
v[1] 1
v[2] -1
F3 F2 F3 F2 F2
F1 v[3] -1
F4 F3 F2 F1 F0 F2 F1 F0 F1 F0
F1 F1
v[4] -1
F1 F0 F1 F0
-1
F3 F2 F2
v[5]
F1
F1 F0 F1
-1
F0
F2 v[6]
F1
F1 F0 v[7] -1 12
(Dynamic Programming)
Look at the execution of F(7)
F7
F6 F5 v[0] 1
F5 F4 F4 F3
v[1] 1
v[2] 2
F3 F2 F3 F2 F2
F1 v[3] -1
F4 F3 F2 F1 F0 F2 F1 F0 F1 F0
F1 F1
v[4] -1
F1 F0 F1 F0
-1
F3 F2 F2
v[5]
F1
F1 F0 F1
-1
F0
F2 v[6]
F1
F1 F0 v[7] -1 13
(Dynamic Programming)
Look at the execution of F(7)
F7
F6 F5 v[0] 1
F5 F4 F4 F3
v[1] 1
v[2] 2
F3 F2 F3 F2 F2
F1 v[3] -1
F4 F3 F2 F1 F0 F2 F1 F0 F1 F0
F1 F1
v[4] -1
F1 F0 F1 F0
-1
F3 F2 F2
v[5]
F1
F1 F0 F1
-1
F0
F2 v[6]
F1
F1 F0 v[7] -1 14
(Dynamic Programming)
Look at the execution of F(7)
F7
F6 F5 v[0] 1
F5 F4 F4 F3
v[1] 1
v[2] 2
F3 F2 F3 F2 F2
F1 v[3] 3
F4 F3 F2 F1 F0 F2 F1 F0 F1 F0
F1 F1
v[4] -1
F1 F0 F1 F0
-1
F3 F2 F2
v[5]
F1
F1 F0 F1
-1
F0
F2 v[6]
F1
F1 F0 v[7] -1 15
(Dynamic Programming)
Look at the execution of F(7)
F7
F6 F5 v[0] 1
F5 F4 F4 F3
v[1] 1
v[2] 2
F3 F2 F3 F2 F2
F1 v[3] 3
F4 F3 F2 F1 F0 F2 F1 F0 F1 F0
F1 F1
v[4] -1
F1 F0 F1 F0
-1
F3 F2 F2
v[5]
F1
F1 F0 F1
-1
F0
F2 v[6]
F1
F1 F0 v[7] -1 16
(Dynamic Programming)
Look at the execution of F(7)
F7
F6 F5 v[0] 1
F5 F4 F4 F3
v[1] 1
v[2] 2
F3 F2 F3 F2 F2
F1 v[3] 3
F4 F3 F2 F1 F0 F2 F1 F0 F1 F0
F1 F1
v[4] 5
F1 F0 F1 F0
-1
F3 F2 F2
v[5]
F1
F1 F0 F1
-1
F0
F2 v[6]
F1
F1 F0 v[7] -1 17
(Dynamic Programming)
Look at the execution of F(7)
F7
F6 F5 v[0] 1
F5 F4 F4 F3
v[1] 1
v[2] 2
F3 F2 F3 F2 F2
F1 v[3] 3
F4 F3 F2 F1 F0 F2 F1 F0 F1 F0
F1 F1
v[4] 5
F1 F0 F1 F0
-1
F3 F2 F2
v[5]
F1
F1 F0 F1
-1
F0
F2 v[6]
F1
F1 F0 v[7] -1 18
(Dynamic Programming)
Look at the execution of F(7)
F7
F6 F5 v[0] 1
F5 F4 F4 F3
v[1] 1
v[2] 2
F3 F2 F3 F2 F2
F1 v[3] 3
F4 F3 F2 F1 F0 F2 F1 F0 F1 F0
F1 F1
v[4] 5
F1 F0 F1 F0
8
F3 F2 F2
v[5]
F1
F1 F0 F1
-1
F0
F2 v[6]
F1
F1 F0 v[7] -1 19
(Dynamic Programming)
Look at the execution of F(7)
F7
F6 F5 v[0] 1
F5 F4 F4 F3
v[1] 1
v[2] 2
F3 F2 F3 F2 F2
F1 v[3] 3
F4 F3 F2 F1 F0 F2 F1 F0 F1 F0
F1 F1
v[4] 5
F1 F0 F1 F0
8
F3 F2 F2
v[5]
F1
F1 F0 F1
-1
F0
F2 v[6]
F1
F1 F0 v[7] -1 20
(Dynamic Programming)
Look at the execution of F(7)
F7
F6 F5 v[0] 1
F5 F4 F4 F3
v[1] 1
v[2] 2
F3 F2 F3 F2 F2
F1 v[3] 3
F4 F3 F2 F1 F0 F2 F1 F0 F1 F0
F1 F1
v[4] 5
F1 F0 F1 F0
8
F3 F2 F2
v[5]
F1
F1 F0 F1
13
F0
F2 v[6]
F1
F1 F0 v[7] -1 21
(Dynamic Programming)
Look at the execution of F(7)
F7
F6 F5 v[0] 1
F5 F4 F4 F3
v[1] 1
v[2] 2
F3 F2 F3 F2 F2
F1 v[3] 3
F4 F3 F2 F1 F0 F2 F1 F0 F1 F0
F1 F1
v[4] 5
F1 F0 F1 F0
8
F3 F2 F2
v[5]
F1
F1 F0 F1
13
F0
F2 v[6]
F1
F1 F0 v[7] -1 22
(Dynamic Programming)
Look at the execution of F(7)
F7
F6 F5 v[0] 1
F5 F4 F4 F3
v[1] 1
v[2] 2
F3 F2 F3 F2 F2
F1 v[3] 3
F4 F3 F2 F1 F0 F2 F1 F0 F1 F0
F1 F1
v[4] 5
F1 F0 F1 F0
8
F3 F2 F2
v[5]
F1
F1 F0 F1
13
F0
F2 v[6]
F1
F1 F0 v[7] 21 23
(Dynamic Programming)
Can we do even better?
Observation
The 2nd version stills make many function calls, and each
wastes times in parameters passing, dynamic linking, ...
In general, to compute F(i), we need F(i-1) & F(i-2) only
(Dynamic Programming)
Recursive vs DP approach
Recursive
Recursive version:
version:
Procedure
Procedure F(n)
F(n)
if Too Slow!
if n==0
n==0 oror n==1
n==1 then
then
return
return 11 exponential
else
else
return
return F(n-1)
F(n-1) ++ F(n-2)
F(n-2)
Dynamic
Dynamic Programming
Programming version:
version:
Procedure
Procedure F(n)
F(n) Efficient!
Set
Set A[0]
A[0] == A[1]
A[1] == 11 Time complexity is O(n)
for
for ii == 22 to
to nn do
do
A[i]
A[i] == A[i-1]
A[i-1] ++ A[i-2]
A[i-2]
return
return A[n]
A[n]
25
(Dynamic Programming)
Summary of the methodology
Write down a formula that relates a solution of a problem
with those of sub-problems.
E.g. F(n) = F(n-1) + F(n-2).
Index the sub-problems so that they can be stored and
retrieved easily in a table (i.e., array)
Fill the table in some bottom-up manner; start filling the
solution of the smallest problem.
This ensures that when we solve a particular sub-problem, the
solutions of all the smaller sub-problems that it depends are available.
(Dynamic Programming)
Exercise
Consider the following function
1 if 0 n2
G(n) =
G(n-1) + G(n-2) + G(n-3) if n > 2
1. Draw the execution tree of computing G(6)
recursively
2. Using dynamic programming, write a pseudo
code to compute G(n) efficiently
3. What is the time complexity of your
algorithm?
27
(Dynamic Programming)
Exercise
1 if 0 n2
G(n) =
G(n-1) + G(n-2) + G(n-3) if n > 2
Dynamic
Dynamic Programming
Programming version:
version:
Procedure
Procedure G(n)
G(n)
Set
Set A[0]
A[0] == A[1]
A[1] == A[2]
A[2] == 11
for
for ii == 33 to
to nn do
do
A[i]
A[i] == A[i-1]
A[i-1] ++ A[i-2]
A[i-2] ++ A[i-3]
A[i-3]
return
return A[n]
A[n]
(Dynamic Programming)
Assembly line scheduling …
Assembly line scheduling
2 assembly lines, each with n stations (Si,j: line i station j)
S1,j and S2,j perform same task but time taken is different
S1,1 S1,2 S1,3 S1,4 S1,n-1 S1,n
Line 1 a1,1 a1,2 a1,3 a1,4 a1,n-1 a1,n
31
(Dynamic Programming)
Example (2)
S1,1 S1,2 S1,3 S1,4
Line 1 5 5 9 4
2 4 1
start end
1 11 2
Line 2 15 4 3 7
S2,1 S2,2 S2,3 S2,4
(Dynamic Programming)
Example
S1,1 S1,2 S1,3 S1,4
Line 1 5 5 9 4
(Dynamic Programming)
Good news: Dynamic Programming
We don’t need to try all possible choices.
We can make use of dynamic programming:
1. If we can compute the fastest ways to get thro’
station S1,n and S2,n, then the faster of these two
ways is the overall fastest way.
2. To compute the fastest ways to get thro’ S1,n
(similarly for S2,n), we need to know the fastest
way to get thro’ S1,n-1 and S2,n-1
3. In general, we want to know the fastest way to get
thro’ S1,j and S2,j, for all j. 34
(Dynamic Programming)
Example again
S1,1 S1,2 S1,3 S1,4
Line 1 5 5 9 4
2 4 1
start end
1 11 2
Line 2 15 4 3 7
S2,1 S2,2 S2,3 S2,4
S1,1 S1,2 S1,3 S14
minimum cost: 5
S2,1 S2,2 S2,3 S2,4
15 35
(Dynamic Programming)
Example again
S1,1 S1,2 S1,3 S1,4
Line 1 5 5 9 4
2 4 1
start end
1 11 2
Line 2 15 4 3 7
S2,1 S2,2 S2,3 S2,4
S1,1 S1,2 S1,3 S14
5+5
minimum cost: 5 15+1+5
S2,1 S2,2 S2,3 S2,4
15 5+2+4
36
15+4 (Dynamic Programming)
Example again
S1,1 S1,2 S1,3 S1,4
Line 1 5 5 9 4
2 4 1
start end
1 11 2
Line 2 15 4 3 7
S2,1 S2,2 S2,3 S2,4
S1,1 S1,2 S1,3 S14
5+5 10+9
minimum cost: 5 15+1+5 11+11+9
S2,1 S2,2 S2,3 S2,4
15 5+2+4 10+4+3
37
15+4 11+3 (Dynamic Programming)
Example again
S1,1 S1,2 S1,3 S1,4
Line 1 5 5 9 4
2 4 1
start end
1 11 2
Line 2 15 4 3 7
S2,1 S2,2 S2,3 S2,4
S1,1 S1,2 S1,3 S14
5+5 10+9 19+4
minimum cost: 5 15+1+5 11+11+9 14+2+4 20
S2,1 S2,2 S2,3 S2,4
15 5+2+4 10+4+3 19+1+7 21 38
15+4 11+3 14+7 (Dynamic Programming)
A dynamic programming solution
What are the sub-problems?
given j, what is the fastest way to get thro' S1,j
given j, what is the fastest way to get thro' S2,j
Definitions:
f [j] = the fastest time to get thro' S1,j
1
start
Line 2
S2,1 S2,j-1 S2,j
40
(Dynamic Programming)
Solving the sub-problems (1)
Q1: what is the fastest way to get thro' S1,j?
A: either
the fastest way thro' S1,j-1, then directly to S1,j, or
(Dynamic Programming)
Solving the sub-problems (1)
Q1: what is the fastest way to get thro' S1,j?
A: either
the fastest way thro' S1,j-1, then directly to S1,j, or
the fastest way thro' S2,j-1, a transfer from line 2
to line 1, and then through S1,j
S1,1 S1,j-1 S1,j
Line 1 a1,j
Line 2
S2,1 S2,j-1 S2,j
42
(Dynamic Programming)
Solving the sub-problems (1)
Q1: what is the fastest way to get thro' S1,j?
A: either
the fastest way thro' S1,j-1, then directly to S1,j, or
the fastest way thro' S2,j-1, a transfer from line 2
to line 1, and then through S1,j
f1[j] = min( f1[j-1]+a1,j , f2[j-1]+t2,j-1+a1,j )
Conclusion:
S1,1 S1,j-1 S1,j
Boundary case: f1[1] = a1,1 Line 1
start
Line 2
S2,1 S2,j-1 S43
2,j
(Dynamic Programming)
Solving the sub-problems (2)
Q2: what is the fastest way to get thro' S2,j?
By exactly the same analysis, we obtain the formula for
the fastest way to get thro' S2,j:
f2[j] = min( f2[j-1]+a2,j , f1[j-1]+t1,j-1+a2,j )
Line 1
start
Line 2
S2,1 S2,j-1 S2,j 44
(Dynamic Programming)
Summary
a1,1 if j=1,
f1[j] =
min ( f1[j-1]+a1,j , f2[j-1]+t2,j-1+a1,j ) if j>1
a2,1 if j=1,
f2[j] =
min ( f2[j-1]+a2,j , f1[j-1]+t1,j-1+a2,j ) if j>1
f* = min( f1[n] , f2[n] )
Line 1 f2[j
5 5 9 4 j f1[j]
]
2 4 1
1
start end
1 11 2 2
3
Line 2 15 4 3 7
4 45
(Dynamic Programming)
Summary
a1,1 if j=1,
f1[j] =
min ( f1[j-1]+a1,j , f2[j-1]+t2,j-1+a1,j ) if j>1
a2,1 if j=1,
f2[j] =
min ( f2[j-1]+a2,j , f1[j-1]+t1,j-1+a2,j ) if j>1
f* = min( f1[n] , f2[n] )
5
Line 1 f2[j
5 5 9 4 j f1[j]
]
2 4 1
1 5 15
start end
1 11 2 2
3
Line 2 15 4 3 7
15
4 46
(Dynamic Programming)
Summary
a1,1 if j=1,
f1[j] =
min ( f1[j-1]+a1,j , f2[j-1]+t2,j-1+a1,j ) if j>1
a2,1 if j=1,
f2[j] =
min ( f2[j-1]+a2,j , f1[j-1]+t1,j-1+a2,j ) if j>1
f* = min( f1[n] , f2[n] )
5 10
Line 1 f2[j
5 5 9 4 j f1[j]
]
2 21 4 1
1 5 15
start end
1 11 11 2 2 10 11
3
Line 2 15 4 3 7
15 19
4 47
(Dynamic Programming)
Summary
a1,1 if j=1,
f1[j] =
min ( f1[j-1]+a1,j , f2[j-1]+t2,j-1+a1,j ) if j>1
a2,1 if j=1,
f2[j] =
min ( f2[j-1]+a2,j , f1[j-1]+t1,j-1+a2,j ) if j>1
f* = min( f1[n] , f2[n] )
5 10 19
Line 1 f2[j
5 5 9 4 j f1[j]
]
2 4 31 1
1 5 15
start end
1 11 11 17 2 2 10 11
3 19 14
Line 2 15 4 3 7
15 14
4 48
(Dynamic Programming)
Summary
a1,1 if j=1,
f1[j] =
min ( f1[j-1]+a1,j , f2[j-1]+t2,j-1+a1,j ) if j>1
a2,1 if j=1,
f2[j] =
min ( f2[j-1]+a2,j , f1[j-1]+t1,j-1+a2,j ) if j>1
f* = min( f1[n] , f2[n] )
5 10 19 23
Line 1 f2[j
5 5 9 4 j f1[j]
]
2 4 1 20 1 5 15
start end
1 11 11 2 27 2 10 11
3 19 14
Line 2 15 4 3 7
15 14 21
4 20 21 49
(Dynamic Programming)
Summary
a1,1 if j=1,
f1[j] =
min ( f1[j-1]+a1,j , f2[j-1]+t2,j-1+a1,j ) if j>1
a2,1 if j=1,
f2[j] =
min ( f2[j-1]+a2,j , f1[j-1]+t1,j-1+a2,j ) if j>1
f* = min( f1[n] , f2[n] )
f* = 20
5 10 19
Line 1 f2[j
5 5 9 4 j f1[j]
]
2 4 1 20 1 5 15
start end
1 11 11 2 2 10 11
3 19 14
Line 2 15 4 3 7
15 14 21
4 20 21 50
(Dynamic Programming)
Pseudo code
Time
set f1[1] = a1,1
complexity is
set f2[1] = a2,1 O(n)
for j = 2 to n do
begin
set f1[j] = min ( f1[j-1]+a1,j , f2[j-1]+t2,j-1+a1,j )
set f2[j] = min ( f2[j-1]+a2,j , f1[j-1]+t1,j-1+a2,j )
end
set f* = min (f1[n] , f2[n] )
51
(Dynamic Programming)
One more example
Line 1 10 20 15 15
2 3 2
start end
1 2 4
j f1[j] f2[j]
Line 2 10 15 20 10
1
2
3
4 52
(Dynamic Programming)
One more example – solution
Line 1 10 20 15 15
2 3 2
start end f* = 54
1 2 4
j f1[j] f2[j]
Line 2 10 15 20 10
1 10 10
2 30 25
3 42 45
4 57 54 53
(Dynamic Programming)
What if there are 3 or more lines?
In general, m assembly lines: use multi-
dimensional arrays.
a[i][j] – represents assemble time of station j
on line i
t[i][j][k] – represents transfer time from
station j on line i to station (j+1) on line k
t[i][j][i] =0
f[i][j] – represents the best so far way of going
thro’ station j on line i
f[i][j] = min1 k m ( f[k][j-1]+t[k][j-1][i] + a[i][j] ) 54
(Dynamic Programming)
Pseudo code – calculate f[i][j]
for i = 1 to m do set f[i][1] = a[i][1]
for j = 2 to n do begin // station by station optional
for i = 1 to m do begin // line by line to find f[i][j]
min_cost = f[1][j-1] + t[1][j-1][i]
transfer from line 1 to line i
min_line = 1
for k = 2 to m do begin transfer from line k to line i
if (f[k][j-1]+t[k][j-1][i] < min_cost) then begin
min_cost = f[k][j-1]+t[k][j-1][i]
min_line = k
end
end
f[i][j] = min_cost + a[i][j]
from_line[i][j] = min_line assume that
end t[i][j][i] = 0
55
end (Dynamic Programming)
Pseudo code – find optimal cost
min_line = 1
optional
min = f[1][n]
for i = 2 to m do
begin
if (f[i][n] < min) then begin
min_line = i
min = f[i][n]
end
end
f* = min
output f* 56
(Dynamic Programming)
Pseudo code – find optimal path
output "Station n: Line " + min_line optional
for j = n downto 2 do
begin
min_line = from_line[min_line][j]
output "Station " + (j-1) + ": Line " + min_line
end
57
(Dynamic Programming)
Time Complexity optional
O(m): for i = 1 to m do set f[i][1] = a[i][1]
O(nm2): for j = 2 to n do begin
for i = 1 to m do begin
for k = 2 to m do begin
O(n): for i = 2 to m do
O(n): for j = n downto 2 do
Overall time complexity: O(nm2)
O(m)+O(nm2)+O(m)+O(n)
58
(Dynamic Programming)