DynamicProgramming Short
DynamicProgramming Short
Dynamic Programming
Dynamic programming
A divide-and-conquer algorithm :
0 if n=0
Fib(n) = 1 if n=1
Fib(n 1) + Fib(n 2) if n 1
function Fib(n)
if (n 1) then return n ;
else
return(Fib(n 1) + Fib(n 2)) ;
F(n)
F(n-1) F(n-2)
2. Dynamic Programming :
function fib dyn(n)
int *f, i ;
f = malloc((n + 1) ⇤ sizeof(int)) ;
for (i = 0; i n; i + +)
if (i 1)
f[i] = i ;
else
f [i] = f [i 1] + f [i 2] ;
return f [n] ;
Introduction
0 1
Summary
0 1 2 3 4 5 6 7 8 9 10
0 1 2 3
here computing Fib(4) and Fib(5) both require Fib(3), but Fib(3)
is computed only once
When do we need DP
Devise look-up template using the recursive calls of the D&C algorithm
The function containing the for loop returns the last entry that has
been filled in the table.
Solving with dynamic programming
For example, what is the smallest amount of coins needed to pay back
$2.89 (289 cents) using as denominations ”one dollars”, ”quaters”,
”dimes” and ”pennies”.
Amount 0 1 2 3 4 5 6 7 8
d1 = 1
d2 = 4
d3 = 6
The initialization of the table is obtained from the D&C base case :
if (j == 0) then return 0
Amount 0 1 2 3 4 5 6 7 8
d1 = 1 0
d2 = 4 0
d3 = 6 0
Solving with dynamic programming
Amount 0 1 2 3 4 5 6 7 8
d1 = 1 0 1 2 3 4 5 6 7 8
d2 = 4 0
d3 = 6 0
For example, the content of entry t[1 4] = t[1 3] + 1 means that the
minimum number of coins to return 4 units using only denomination 1
is the minimum number of coins to return 3 units + 1 = 4 coins.
Solving with dynamic programming
Amount 0 1 2 3 4 5 6 7 8
d1 = 1 0 1 2 3 4 5 6 7 8
d2 = 4 0 1 2 3
d3 = 6 0 1 2 3 1 2
For all the other entries of the table we write the code of the DP
algorithm using the recursive function
Solving with dynamic programming
The recursive function also tells us that we take the min of these two
values :
t[i j] = min(t[i 1 j] t[i j di ] + 1)
Solving with dynamic programming
The DP algorithm
coins(n N)
int d[1 n] = d[1 4 6] ;
int t[1 n 0 N] ;
for (i = 1; i n; i + +) t[i 0] = 0 ; */base case */
for (i = 1; i n; i + +)
for (j = 1; j N; j + +)
if (i = 1) then t[i j] = t[i j di ] + 1
else if (j d[i]) then t[i j] = t[i 1 j]
else t[i j] = min(t[i 1 j] t[i j d[i]] + 1)
return t[n N] ;
Amount 0 1 2 3 4 5 6 7 8
d1 = 1 0 1 2 3 4 5 6 7 8
d2 = 4 0 1 2 3 1 2 3 4 2
d3 = 6 0 1 2 3 1 2 1 2 2
Amount 0 1 2 3 4 5 6 7 8
d1 = 1 0 1 2 3 4 5 6 7 8
d2 = 4 0 1 2 3 1 2 3 4 2
d3 = 6 0 1 2 3 1 2 1 2 2
We can use the information in the table to get the list of coins that
should be returned :
Start at entry t[n N] ;
If t[i j] = t[i 1 j] then no coin of denomination i has been used
to calculate t[i j], then move to entry t[i 1 j] ;
If t[i j] = t[i j di ] + 1, then add one coin of denomination i and
move to entry t[i j di ].
Optimal substructure
Optimal Substructure
The constraint is the sum of the value of the coins is equal to the
amount to return
Optimal substructure
Optimal Substructure
Optimal Substructure
Make Change() exhibits the optimal substructure property :
The optimal solution of problem (i j) is obtained using optimal
solutions (minimum number of coins) of sub-problems (i 1 j)
and (i j di ).
Amount 0 1 2 3 4 5 6 7 8
d1 = 1 0 1 2 3 4 5 6 7 8
d2 = 4 0 1 2 3 1 2 3 4 2
d3 = 6 0 1 2 3 1 2 1 2 2
Each entry t[i j] in the table is the optimal solution (minimum number
of coins) that can be used to return an amount of j units using only
denominations d1 to di .
Optimal Substructure
Often we start with all optimal subsolutions of size 1, then compute all
optimal subsolutions of size 2 combining some subsolutions of size 1.
We continue in this fashion until we have out solution for n.
Given n objects with integer weights wi and values vi , you are asked to
pack a knapsack with no more than W weight (W is integer) such
that the load is as valuable as possible (maximize). You cannot take
part of an object, you must either take an object or leave it out.
Problem formulation
Given
n integer weights w1 wn ,
n values v1 vn , and
an integer capacity W ,
assign either 0 or 1 to each of x1 xn so that the sum
n
f (x) = xi vi
i=1
is maximized, s.t.
n
xi wi W
i=1
Optimal substructure
Explanation
The value of the chosen load is ni=1 xi vi . We want the most valuable
load, so we want to maximize this sum.
The weight of the chosen load is ni=1 xi wi . We can’t carry more than
W units of weight, so this sum must be W .
Optimal substructure
Optimal Substructure
Claim :
If {x1 x2 xk } is an optimal solution to the knapsack problem with
weight W , then {x1 x2 xk 1 } is an optimal solution to the knapsack
problem with W = W wxk .
Optimal substructure
Optimal Substructure
Proof : Assume {x1 x2 xk 1 } is not an optimal solution to the
subproblem. Then there are objects {y1 y2 yl } such that
and
vy1 + vy2 + · · · + vyl vx1 + vx2 + · · · + vxk 1
Then
Then we have
v1 if w1 j
K [1 j] =
0 if w1 j
int K(i W )
if (i = 1) return (W w [1]) ? 0 : v [1] ;
if (W w [i]) return K(i 1 W ) ;
return max(K(i 1 W ), K(i 1 W w [i]) + v [i]) ;
i 1 2 3 4 5
wi 6 5 4 2 2
vi 6 3 5 4 6
Optimal substructure
Optimal substructure
i 1 2 3 4 5
wi 6 5 4 2 2
vi 6 3 5 4 6
int K(i W )
if (i = 1) return (W w [1]) ? 0 : v [1] ;
if (W w [i]) return K(i 1 W ) ;
return max(K(i 1 W ), K(i 1 W w [i]) + v [i]) ;
5 16 10
4 11 10 4 10 8
3 11 10 3 6 8 3 6 8 3 6 6
2 6 10 2 6 6 2 6 8 2 0 4 2 6 8 2 0 4 2 6 6 2 0 2
1 6 10 1 0 5 1 6 6 1 0 1 1 6 8 1 0 3 1 0 4 1 6 8 1 0 3 1 0 4 1 6 6 1 0 1 1 0 2
Optimal substructure
T (1) = 1
1 n=1
T (n) =
2T (n 1) + c = 1 n 1
Optimal substructure
1 n=1
T (n) =
2T (n 1) + c = 1 n 1
T (n) = 2T (n 1) + 1
= 2[2T (n 2) + 1] + 1
= 22 T (n 2) + 2 + 1
= 22 [2T (n 3) + 1] + 2 + 1
= 23 T (n 3) + 22 + 2 + 1
= ···
= 2n 1
T (n (n 1)) + 2n 1
1
= 2n 1
T (1) + 2n 1 1
= 2n 1
+ 2n 1
1
= 2n 1
Optimal substructure
Basic Step (n = 1) :
T (1) = 1 by definition
= 21 1=1
Optimal substructure
Inductive Step :
Assume the closed formula holds for n-1, that is, T (n 1) = 2n 1 1,
for all n 2. Show the formula also holds for n, that is, T (n) = 2n 1.
Overlapping Subproblems
i\j 0 1 2 3 4 5 6 7 8 9 10
1
2
3
4
5
6
Optimal substructure
i\j 0 1 2 3 4 5 6 7 8 9 10
1 0
2 0
3 0
4 0
5 0
6 0
Optimal substructure
This said that if the capacity is smaller than the weight of object 1,
then the value is 0 (cannot add object 1), otherwise the value is v [1]
i\j 0 1 2 3 4 5 6 7 8 9 10
1 0 0 0 7 7 7 7 7 7 7 7
2 0
3 0
4 0
5 0
6 0
Optimal substructure
int K(i W )
if (i = 1) return (W w [1]) ? 0 : v [1] ;
if (W w [i]) return K(i 1 W ) ;
return max(K(i 1 W ), K(i 1 W w [i]) + v [i]) ;
i\j 0 1 2 3 4 5 6 7 8 9 10
1 0 0 0 7 7 7 7 7 7 7 7
2 0
3 0
4 0
5 0
6 0
Optimal substructure
function 0-1-Knapsack(w v n W )
int K[n W + 1] ;
for(i = 1; i n; i + +) K [i 0] = 0 ;
for(j = 0; j W ; j + +)
if (w [1] j) then K [1 j] = v [1] ;
else K [1 j] = 0 ;
for (i = 2; i n; i + +)
for (j = 1; j W ; j + +)
if (j w [i] && K [i 1 j w [i]] + v [i] K [i 1 j])
K [i j] = K [i 1 j w [i]] + v [i] ;
else
K [i j] = K [i 1 j] ;
return K[n W ] ;
Optimal substructure
for (i = 2; i n; i + +)
for (j = 1; j W ; j + +)
if (j w [i] && K [i 1 j w [i]] + v [i] K [i 1 j])
K [i j] = K [i 1 j w [i]] + v [i] ;
else
K [i j] = K [i 1 j] ;
i\j 0 1 2 3 4 5 6 7 8 9 10
1 0 0 0 7 7 7 7 7 7 7 7
2 0 0 10 10 10 17 17 17 17 17 17
3 0 0 10 10 10 17 17 17 17 17 17
4 0 3 10 13 13 17 20 20 20 20 20
5 0 3 10 13 13 17 20 20 20 20 20
6 0 3 10 13 13 17 20 20 20 23 26
Optimal substructure
With this problem, we don’t have to keep track of anything extra. Let
K [n k] be the maximal value.
i\j 0 1 2 3 4 5 6 7 8 9 10
1 0 0 0 7 7 7 7 7 7 7 7
2 0 0 10 10 10 17 17 17 17 17 17
3 0 0 10 10 10 17 17 17 17 17 17
4 0 3 10 13 13 17 20 20 20 20 20
5 0 3 10 13 13 17 20 20 20 20 20
6 0 3 10 13 13 17 20 20 20 23 26
i 1 2 3 4 5
wi 6 5 4 2 2
vi 6 3 5 4 6
i\j 0 1 2 3 4 5 6 7 8 9 10
1 0
2 0
3 0
4 0
5 0