390 likes | 401 Views
Understand the dynamic programming approach for finding the optimal solution to coin change problems, analyzing recursive solutions, speeding up algorithms, and implementing dynamic programming.
E N D
18 = 6 + 6 + 6 = 13 + 2 + 2 + 1 24 = 6 + 6 + 6 + 6 = 13 + 6 + 2 +2 +1 31 = 13 + 18 37 = 13 + 24 44 = 13 + 31 50 = 13 + 37
the greedy algorithm doesn’t work How are we going to find an optimal solution ?
Recursive solution try all possibilities Number(n) if n<0 then RETURN if n=0 then RETURN 0 a1 1 + Number(n-1) a2 1 + Number(n-2) a6 1 + Number(n-6) a13 1 + Number(n-13) RETURN min(a1,a2,a6,a13)
Recursive solution try all possibilities Number(n) if n<0 then RETURN if n=0 then RETURN 0 a1 1 + Number(n-1) a2 1 + Number(n-2) a6 1 + Number(n-6) a13 1 + Number(n-13) RETURN min(a1,a2,a6,a13) OK, so now we know the cost of the optimal solution. How do we output the solution?
Outputting solution Solution(n) if n=0 then RETURN ; else if Number(n)=1+Number(n-1) then print(1); Solution(n-1); elif Number(n)=1+Number(n-2) then print(2); Solution(n-2); elif Number(n)=1+Number(n-6) then print(6); Solution(n-6); else print(13); Solution(n-6);
How to make it faster? Time = n Time = Fn 1.618n
How to make it faster? Number[0] 0 for i 1 to n do A 1 + Number[i-1] if i 2 then A min(A,1+Number[i-2]) if i 6 then A min(A,1+Number[i-6]) if i 13 then A min(A,1+Number[i-13]) Number[i] A Dynamic programming
Example Number[0] 0 for i 1 to n do A 1 + Number[i-1] if i 2 then A min(A,1+Number[i-2]) if i 6 then A min(A,1+Number[i-6]) if i 13 then A min(A,1+Number[i-13]) Number[i] A $0 - 0 $1 - 1 $2 - 1 $3 - 2 $4 - 2 $5 - 3 $6 - 1 $7 - 2 $8 - 2 $9 - 3 $10 $11 $12 $13 $14 $15
Example Number[0] 0 for i 1 to n do A 1 + Number[i-1] if i 2 then A min(A,1+Number[i-2]) if i 6 then A min(A,1+Number[i-6]) if i 13 then A min(A,1+Number[i-13]) Number[i] A $0 - 0 $1 - 1 $2 - 1 $3 - 2 $4 - 2 $5 - 3 $6 - 1 $7 - 2 $8 - 2 $9 - 3 $10 - 3 $11 $12 $13 $14 $15
Example Number[0] 0 for i 1 to n do A 1 + Number[i-1] if i 2 then A min(A,1+Number[i-2]) if i 6 then A min(A,1+Number[i-6]) if i 13 then A min(A,1+Number[i-13]) Number[i] A $0 - 0 $1 - 1 $2 - 1 $3 - 2 $4 - 2 $5 - 3 $6 - 1 $7 - 2 $8 - 2 $9 - 3 $10 - 3 $11 $12 $13 $14 $15
Example Number[0] 0 for i 1 to n do A 1 + Number[i-1] if i 2 then A min(A,1+Number[i-2]) if i 6 then A min(A,1+Number[i-6]) if i 13 then A min(A,1+Number[i-13]) Number[i] A $0 - 0 $1 - 1 $2 - 1 $3 - 2 $4 - 2 $5 - 3 $6 - 1 $7 - 2 $8 - 2 $9 - 3 $10 - 3 $11 - 4 $12 $13 $14 $15
Heart of the algorithm Let Number[n] be the optimal number of coins needed to pay $n. Let Number[n]= for n<0, and Number[0]=0 For n1 Number[n]=1+min { Number[n-1] Number[n-2] Number[n-6] Number[n-13]
Dynamic programming vs. greedy What is the input size for the coin change problem? Is the dynamic programming algorithm for the coin change polynomial-time? Is the greedy algorithm polynomial-time?
Knapsack INPUT: n items wi = weight of item i vi = value of item i M = capacity of knapsack SOLUTION: a subset S of items whose total weight does not exceed M OBJECTIVE: maximize the total value of S
Knapsack INPUT: n items wi = weight of item i vi = value of item i M = capacity of knapsack SOLUTION: a subset S of items whose total weight does not exceed M OBJECTIVE: maximize the total value of S M = 5lb book 2lb $10 MP3 player 1lb $100 potatoes 3lb $2 oranges 2lb $3
Knapsack INPUT: n items wi = weight of item i vi = value of item i M = capacity of knapsack SOLUTION: a subset S of items whose total weight does not exceed M OBJECTIVE: maximize the total value of S M = 5lb book 2lb $10 MP3 player 1lb $100 potatoes 3lb $2 oranges 2lb $3 Value = $113 Weight = 5lb
Knapsack Algorithm 1 1. sort the items by “price per pound” vi/wi 2. go through the items in this order, if the item fits, put it in the knapsack. Is solution output by Algorithm 1 always optimal ?
Knapsack K [0..M] where K[ j ] = optimal value of items in knapsack of size j K[ j ] = ?
Knapsack K [0..M,0..n] where K[ j,i ] = optimal value of items in knapsack of size j, using only items 1,…,i K[ j,0 ] = ?
Knapsack K [0..M,0..n] where K[ j,i ] = optimal value of items in knapsack of size j, using only items 1,…,i K[ j,0 ] = 0
Knapsack K [0..M,0..n] where K[ j,i ] = optimal value of items in knapsack of size j, using only items 1,…,i K[ j,i ] = ?
Knapsack K [0..M,0..n] where K[ j,i ] = optimal value of items in knapsack of size j, using only items 1,…,i K[ j,i ] = ? use item i do not use item i
Knapsack K [0..M,0..n] where K[ j,i ] = optimal value of items in knapsack of size j, using only items 1,…,i K[ j,i ] = ? use item i K[ j-wi,i-1]+vi do not use item i K[ j,i-1]
Knapsack K [0..M,0..n] where K[ j,i ] = optimal value of items in knapsack of size j, using only items 1,…,i K[ j,0] = 0 K[ j,i ] = max( K[ j-wi,i-1] +vi , K[ j,i-1] ) if j wi K[ j,i ] = K[ j, i-1 ] if j < wi Heart of the algorithm
Knapsack K [0..M,0..n] where K[ j,i ] = optimal value of items in knapsack of size j, using only items 1,…,i K[ j,0] = 0 K[ j,i ] = max( K[ j-wi,i-1] +vi , K[ j,i-1] ) if j wi K[ j,i ] = K[ j, i-1 ] if j < wi What order shall we compute the K [j,i] in?
K[ j,0] = 0 K[ j,i ] = max( K[ j-wi,i-1] +vi , K[ j,i-1] ) if j wi K[ j,i ] = K[ j, i-1 ] if j < wi for j 0 to M do K[ j,0 ] 0 for i 1 to n do for j 0 to K[ j,i ] K[ j,i-1 ] if j wi and vi+K[ j-wi,i-1 ] > K[ j,i] then K[ j,i ] vi+K[ j-wi,i-1 ]
INPUT: n items wi = weight of item i vi = value of item i M = capacity of knapsack SOLUTION: a subset S of items whose total weight does not exceed M OBJECTIVE: maximize the total value of S for j 0 to M do K[ j,0 ] 0 for i 1 to n do for j 0 to K[ j,i ] K[ j,i-1 ] if j wi and vi+K[ j-wi,i-1 ] > K[ j,i] then K[ j,i ] vi+K[ j-wi,i-1 ] Ok, know value of the optimal solution, how to output it?
for j 0 to M do K[ j,0 ] 0 for i 1 to n do for j 0 to K[ j,i ] K[ j,i-1 ] Get [ j,i] false if j wi and vi+K[ j-wi,i-1 ] > K[ j,i] then K[ j,i ] vi+K[ j-wi,i-1 ] Get [ j,I ] true j M for i n downto 1 do if Get[ j,I ] then print(i); j j-wi
Back to 1 knapsack What if the weights are real numbers and values are integers. Can we still use dynamic programming? K[0..M,0..n] where K[ j,i ] = optimal value of items in knapsack of size j, using only items 1,…,i
Back to 1 knapsack What if the weights are real numbers and values are integers. Can we still use dynamic programming? L[0..S,0..n] where L[ j,i ] = minimal weight of items in knapsack of total value j, using only items 1,…,i S = total value of all items
Knapsack S = total value of all items L[0..S,0..n] where L[ j,i ] = minimal weight of items in knapsack of total value j, using only items 1,…,i
Knapsack S = total value of all items L[0..S,0..n] where L[ j,i ] = minimal weight of items in knapsack of total value j, using only items 1,…,i L[ j,0 ] = ? L[ 0,i ] = ?
Knapsack S = total value of all items L[0..S,0..n] where L[ j,i ] = minimal weight of items in knapsack of total value j, using only items 1,…,i L[ j,0 ] = 0 L[ 0,i ] = ?
Knapsack S = total value of all items L[0..S,0..n] where L[ j,i ] = minimal weight of items in knapsack of total value j, using only items 1,…,i L[ j,i ] = get item i don’t get item i
Knapsack S = total value of all items L[0..S,0..n] where L[ j,i ] = minimal weight of items in knapsack of total value j, using only items 1,…,i L[ j,i ] = get item i don’t get item i L[ j-vi , i-1] + wi L[ j,i-1]
Knapsack S = total value of all items L[0..S,0..n] where L[ j,i ] = minimal weight of items in knapsack of total value j, using only items 1,…,i L[ j,i ] = min ( L[j,i-1] , L[j-vi,i-1] + wi ) get item i don’t get item i if j vi L[ j-vi , i-1] + wi L[ j,i-1]
Knapsack for j 0 to S do L[ j,0 ] 0 for i 0 to n do for j 0 to S do L[ j,i ] = L[ j,i-1] if j vi and L[ j-vi,i-1 ] + wi < L[ j,i ] then L[ j,i ] L [ j-vi, i-1 ] + wi L[0..S,0..n] where L[ j,i ] = minimal weight of items in knapsack of total value j, using only items 1,…,i What is the value of the optimal solution?