Sie sind auf Seite 1von 9

CSCE 310J CSCE 310J

Data Structures & Algorithms Data Structures & Algorithms

Giving credit where credit is due:


Dynamic programming » Most of slides for this lecture are based on slides
created by Dr. David Luebke, University of Virginia.
0-1 Knapsack problem » Some slides are based on lecture notes created by Dr.
Chuck Cusack, UNL.
Dr. Steve Goddard » I have modified them and added new slides.
goddard@cse.unl.edu

http://www.cse.unl.edu/~goddard/Courses/CSCE310J

1 2

Dynamic Programming Dynamic programming


Another strategy for designing algorithms is It is used when the solution can be recursively
dynamic programming described in terms of solutions to subproblems
» A metatechnique, not an algorithm (optimal substructure).
(like divide & conquer) Algorithm finds solutions to subproblems and
» The word “programming” is historical and predates stores them in memory for later use.
computer programming
More efficient than “brute-force methods”, which
Use when problem breaks down into recurring
solve the same subproblems over and over again.
small subproblems

3 4

Summarizing the Concept of


Dynamic Programming Knapsack problem (Review)
Basic idea: Given some items, pack the knapsack to get
» Optimal substructure: optimal solution to problem the maximum total value. Each item has some
consists of optimal solutions to subproblems weight and some value. Total weight that we can
» Overlapping subproblems: few subproblems in total, carry is no more than some fixed number W.
many recurring instances of each So we must consider weights of items as well as
» Solve bottom-up, building a table of solved their value.
subproblems that are used to solve larger ones
Variations: Item # Weight Value
» “Table” could be 3-dimensional, triangular, a tree, etc. 1 1 8
2 3 6
3 5 5
5 6

1
Knapsack problem 0-1 Knapsack problem
There are two versions of the problem: Given a knapsack with maximum capacity W, and
1. “0-1 knapsack problem” and
2. “Fractional knapsack problem” a set S consisting of n items
Each item i has some weight wi and benefit value
1. Items are indivisible; you either take an item or bi (all wi , bi and W are integer values)
not. Solved with dynamic programming
Problem: How to pack the knapsack to achieve
2. Items are divisible: you can take any fraction of maximum total value of packed items?
an item. Solved with a greedy algorithm.
We have already seen this version

7 8

0-1 Knapsack problem: a


picture 0-1 Knapsack problem
Weight Benefit value Problem, in other words, is to find
Items
wi bi max bi subject to wi ≤ W
i∈T i∈T
2 3
This is a knapsack 3 4 The problem is called a “0-1” problem,
Max weight: W = 20 4 5 because each item must be entirely
8
accepted or rejected.
5
W = 20 In the “Fractional Knapsack Problem,” we
can take fractions of items.
9 10
9 10

0-1 Knapsack problem: 0-1 Knapsack problem:


brute-force approach brute-force approach

Let’s first solve this problem with a Can we do better?


straightforward algorithm Yes, with an algorithm based on dynamic
Since there are n items, there are 2n possible programming
combinations of items. We need to carefully identify the subproblems
We go through all combinations and find the one
with maximum value and with total weight less or Let’s try this:
equal to W If items are labeled 1..n, then a subproblem
Running time will be O(2n) would be to find an optimal solution for
Sk = {items labeled 1, 2, .. k}
11 12

2
Defining a Subproblem Defining a Subproblem
w1 =2 w2 =4 w3 =5 w4 =3 Weight Benefit
If items are labeled 1..n, then a subproblem would be b1 =3 b2 =5 b3 =8 b4 =4 Item wi bi
#
to find an optimal solution for Sk = {items labeled ? 1 2 3
1, 2, .. k} Max weight: W = 20
S4 2 3 4
For S4:
Total weight: 14; S5
3 4 5
This is a reasonable subproblem definition. Maximum benefit: 20
4 5 8
The question is: can we describe the final solution 5 9 10
(Sn ) in terms of subproblems (Sk)? w1 =2 w2 =4 w3 =5 w5 =9
b1 =3 b2 =5 b3 =8 b5 =10
Unfortunately, we can’t do that. Solution for S4 is
For S5:
Total weight: 20 not part of the
13
Maximum benefit: 26 solution for S5!!! 14

Defining a Subproblem Recursive Formula for


(continued) subproblems

As we have seen, the solution for S4 is not part of Recursive formula for subproblems:
the solution for S5 B[ k − 1, w ] if wk > w
B[ k , w ] =
 

So our definition of a subproblem is flawed and max{ B[ k − 1, w], B[ k − 1, w − wk ] + bk } else


we need another one!
It means, that the best subset of Sk that has total
Let’s add another parameter: w, which will weight w is:
represent the exact weight for each subset of 1) the best subset of Sk-1 that has total weight w, or
items
2) the best subset of Sk-1 that has total weight w-wk plus the
The subproblem then will be to compute B[k,w] item k

15 16

Recursive Formula 0-1 Knapsack Algorithm


for w = 0 to W
B[ k − 1, w ] if wk > w
B[ k , w ] = B[0,w] = 0
 

max{ B[ k − 1, w], B[ k − 1, w − wk ] + bk } else




for i = 1 to n
B[i,0] = 0
The best subset of Sk that has the total weight w, for i = 1 to n
either contains item k or not. for w = 0 to W
First case: wk>w. Item k can’t be part of the if wi <= w // item i can be part of the solution
solution, since if it was, the total weight would be if bi + B[i-1,w-wi] > B[i-1,w]
> w, which is unacceptable. B[i,w] = bi + B[i-1,w- wi]
Second case: wk ≤ w. Then the item k can be in else
the solution, and we choose the case with greater B[i,w] = B[i-1,w]
value. else B[i,w] = B[i-1,w] // wi > w
17 18

3
Running time Example
for w = 0 to W
O(W)
B[0,w] = 0
for i = 1 to n Let’s run our algorithm on the
B[i,0] = 0 following data:
for i = 1 to n Repeat n times
for w = 0 to W O(W) n = 4 (# of elements)
< the rest of the code >
W = 5 (max weight)
What is the running time of this algorithm?
Elements (weight, benefit):
O(n*W) (2,3), (3,4), (4,5), (5,6)
Remember that the brute-force algorithm
takes O(2n) 19 20

Example (2) Example (3)


i\W 0 1 2 3 4 5 i\W 0 1 2 3 4 5
0 0 0 0 0 0 0 0 0 0 0 0 0 0
1 1 0
2 2 0
3 3 0
4 4 0

for w = 0 to W for i = 1 to n
B[0,w] = 0 B[i,0] = 0

21 22

Items: Items:
1: (2,3) 1: (2,3)
Example (4) 2: (3,4) Example (5) 2: (3,4)
3: (4,5) 3: (4,5)
i\W 0 1 2 3 4 5 i\W 0 1 2 3 4 5
i=1 4: (5,6) i=1 4: (5,6)
0 0 0 0 0 0 0 0 0 0 0 0 0 0
bi=3 bi=3
1 0 0 1 0 0 3
wi=2 wi=2
2 0 2 0
w=1 w=2
3 0 3 0
w-wi =-1 w-wi =0
4 0 4 0
if wi <= w // item i can be part of the solution if wi <= w // item i can be part of the solution
if bi + B[i-1,w-wi] > B[i-1,w] if bi + B[i-1,w-wi] > B[i-1,w]
B[i,w] = bi + B[i-1,w- wi] B[i,w] = bi + B[i-1,w- wi]
else else
B[i,w] = B[i-1,w] B[i,w] = B[i-1,w]
else B[i,w] = B[i-1,w] // wi > w else B[i,w] = B[i-1,w] // wi > w
23 24

4
Items: Items:
1: (2,3) 1: (2,3)
Example (6) 2: (3,4) Example (7) 2: (3,4)
3: (4,5) 3: (4,5)
i\W 0 1 2 3 4 5 i\W 0 1 2 3 4 5
i=1 4: (5,6) i=1 4: (5,6)
0 0 0 0 0 0 0 0 0 0 0 0 0 0
bi=3 bi=3
1 0 0 3 3 1 0 0 3 3 3
wi=2 wi=2
2 0 2 0
w=3 w=4
3 0 3 0
w-wi =1 w-wi =2
4 0 4 0
if wi <= w // item i can be part of the solution if wi <= w // item i can be part of the solution
if bi + B[i-1,w-wi] > B[i-1,w] if bi + B[i-1,w-wi] > B[i-1,w]
B[i,w] = bi + B[i-1,w- wi] B[i,w] = bi + B[i-1,w- wi]
else else
B[i,w] = B[i-1,w] B[i,w] = B[i-1,w]
else B[i,w] = B[i-1,w] // wi > w else B[i,w] = B[i-1,w] // wi > w
25 26

Items: Items:
1: (2,3) 1: (2,3)
Example (8) 2: (3,4) Example (9) 2: (3,4)
3: (4,5) 3: (4,5)
i\W 0 1 2 3 4 5 i\W 0 1 2 3 4 5
i=1 4: (5,6) i=2 4: (5,6)
0 0 0 0 0 0 0 0 0 0 0 0 0 0
bi=3 bi=4
1 0 0 3 3 3 3 1 0 0 3 3 3 3
wi=2 wi=3
2 0 2 0 0
w=5 w=1
3 0 3 0
w-wi =3 w-wi =-2
4 0 4 0
if wi <= w // item i can be part of the solution if wi <= w // item i can be part of the solution
if bi + B[i-1,w-wi] > B[i-1,w] if bi + B[i-1,w-wi] > B[i-1,w]
B[i,w] = bi + B[i-1,w- wi] B[i,w] = bi + B[i-1,w- wi]
else else
B[i,w] = B[i-1,w] B[i,w] = B[i-1,w]
else B[i,w] = B[i-1,w] // wi > w else B[i,w] = B[i-1,w] // wi > w
27 28

Items: Items:
1: (2,3) 1: (2,3)
Example (10) 2: (3,4) Example (11) 2: (3,4)
3: (4,5) 3: (4,5)
i\W 0 1 2 3 4 5 i\W 0 1 2 3 4 5
i=2 4: (5,6) i=2 4: (5,6)
0 0 0 0 0 0 0 0 0 0 0 0 0 0
bi=4 bi=4
1 0 0 3 3 3 3 1 0 0 3 3 3 3
wi=3 wi=3
2 0 0 3 2 0 0 3 4
w=2 w=3
3 0 3 0
w-wi =-1 w-wi =0
4 0 4 0
if wi <= w // item i can be part of the solution if wi <= w // item i can be part of the solution
if bi + B[i-1,w-wi] > B[i-1,w] if bi + B[i-1,w-wi] > B[i-1,w]
B[i,w] = bi + B[i-1,w- wi] B[i,w] = bi + B[i-1,w- wi]
else else
B[i,w] = B[i-1,w] B[i,w] = B[i-1,w]
else B[i,w] = B[i-1,w] // wi > w else B[i,w] = B[i-1,w] // wi > w
29 30

5
Items: Items:
1: (2,3) 1: (2,3)
Example (12) 2: (3,4) Example (13) 2: (3,4)
3: (4,5) 3: (4,5)
i\W 0 1 2 3 4 5 i\W 0 1 2 3 4 5
i=2 4: (5,6) i=2 4: (5,6)
0 0 0 0 0 0 0 0 0 0 0 0 0 0
bi=4 bi=4
1 0 0 3 3 3 3 1 0 0 3 3 3 3
wi=3 wi=3
2 0 0 3 4 4 2 0 0 3 4 4 7
w=4 w=5
3 0 3 0
w-wi =1 w-wi =2
4 0 4 0
if wi <= w // item i can be part of the solution if wi <= w // item i can be part of the solution
if bi + B[i-1,w-wi] > B[i-1,w] if bi + B[i-1,w-wi] > B[i-1,w]
B[i,w] = bi + B[i-1,w- wi] B[i,w] = bi + B[i-1,w- wi]
else else
B[i,w] = B[i-1,w] B[i,w] = B[i-1,w]
else B[i,w] = B[i-1,w] // wi > w else B[i,w] = B[i-1,w] // wi > w
31 32

Items: Items:
1: (2,3) 1: (2,3)
Example (14) 2: (3,4) Example (15) 2: (3,4)
3: (4,5) 3: (4,5)
i\W 0 1 2 3 4 5 i\W 0 1 2 3 4 5
i=3 4: (5,6) i=3 4: (5,6)
0 0 0 0 0 0 0 0 0 0 0 0 0 0
bi=5 bi=5
1 0 0 3 3 3 3 1 0 0 3 3 3 3
wi=4 wi=4
2 0 0 3 4 4 7 2 0 0 3 4 4 7
w= 1..3 w= 4
3 0 0 3 4 3 0 0 3 4 5
w- wi=0
4 0 4 0
if wi <= w // item i can be part of the solution if wi <= w // item i can be part of the solution
if bi + B[i-1,w-wi] > B[i-1,w] if bi + B[i-1,w-wi] > B[i-1,w]
B[i,w] = bi + B[i-1,w- wi] B[i,w] = bi + B[i-1,w- wi]
else else
B[i,w] = B[i-1,w] B[i,w] = B[i-1,w]
else B[i,w] = B[i-1,w] // wi > w else B[i,w] = B[i-1,w] // wi > w
33 34

Items: Items:
1: (2,3) 1: (2,3)
Example (16) 2: (3,4) Example (17) 2: (3,4)
3: (4,5) 3: (4,5)
i\W 0 1 2 3 4 5 i\W 0 1 2 3 4 5
i=3 4: (5,6) i=4 4: (5,6)
0 0 0 0 0 0 0 0 0 0 0 0 0 0
bi=5 bi=6
1 0 0 3 3 3 3 1 0 0 3 3 3 3
wi=4 wi=5
2 0 0 3 4 4 7 2 0 0 3 4 4 7
w= 5 w= 1..4
3 0 0 3 4 5 7 3 0 0 3 4 5 7
w- wi=1
4 0 4 0 0 3 4 5
if wi <= w // item i can be part of the solution if wi <= w // item i can be part of the solution
if bi + B[i-1,w-wi] > B[i-1,w] if bi + B[i-1,w-wi] > B[i-1,w]
B[i,w] = bi + B[i-1,w- wi] B[i,w] = bi + B[i-1,w- wi]
else else
B[i,w] = B[i-1,w] B[i,w] = B[i-1,w]
else B[i,w] = B[i-1,w] // wi > w else B[i,w] = B[i-1,w] // wi > w
35 36

6
Items:
1: (2,3)
Example (18) 2: (3,4) Comments
3: (4,5)
i\W 0 1 2 3 4 5 This algorithm only finds the max possible value
i=4 4: (5,6)
0 0 0 0 0 0 0
bi=6 that can be carried in the knapsack
1 0 0 3 3 3 3 » I.e., the value in B[n,W]
wi=5
2 0 0 3 4 4 7 To know the items that make this maximum value,
w= 5
3 0 0 3 4 5 7 an addition to this algorithm is necessary.
w- wi=0
4 0 0 3 4 5 7
if wi <= w // item i can be part of the solution
if bi + B[i-1,w-wi] > B[i-1,w]
B[i,w] = bi + B[i-1,w- wi]
else
B[i,w] = B[i-1,w]
else B[i,w] = B[i-1,w] // wi > w
37 38

Items:
How to find actual Knapsack 1: (2,3)
Items Finding the Items 2: (3,4)
3: (4,5)
All of the information we need is in the table. i\W 0 1 2 3 4 5 i=4 4: (5,6)
B[n,W] is the maximal value of items that can be 0 0 0 0 0 0 0 k= 5
placed in the Knapsack. 1 0 0 3 3 3 3 bi=6
Let i=n and k=W 2 0 0 3 4 4 7 wi=5
if B[i,k] ≠ B[i−1,k] then 3 0 0 3 4 5 7 B[i,k] = 7
mark the ith item as in the knapsack B[i−1,k] =7
4 0 0 3 4 5 7
i = i−1, k = k-wi i=n, k=W
else while i,k > 0
if B[i,k] ≠ B[i−1,k] then
i = i−1 // Assume the ith item is not in the knapsack mark the ith item as in the knapsack
// Could it be in the optimally packed knapsack? i = i−1, k = k-wi
else
39
i = i−1 40

Items: Items:
1: (2,3) 1: (2,3)
Finding the Items (2) 2: (3,4) Finding the Items (3) 2: (3,4)
3: (4,5) 3: (4,5)
i\W 0 1 2 3 4 5 i=4 i\W 0 1 2 3 4 5 i=3
4: (5,6) 4: (5,6)
0 0 0 0 0 0 0 k= 5 0 0 0 0 0 0 0 k= 5
1 0 0 3 3 3 3 bi=6 1 0 0 3 3 3 3 bi=6
2 0 0 3 4 4 7 wi=5 2 0 0 3 4 4 7 wi=4
3 0 0 3 4 5 7 B[i,k] = 7 3 0 0 3 4 5 7 B[i,k] = 7
B[i−1,k] =7 B[i−1,k] =7
4 0 0 3 4 5 7 4 0 0 3 4 5 7
i=n, k=W i=n, k=W
while i,k > 0 while i,k > 0
if B[i,k] ≠ B[i−1,k] then if B[i,k] ≠ B[i−1,k] then
mark the ith item as in the knapsack mark the ith item as in the knapsack
i = i−1, k = k-wi i = i−1, k = k-wi
else else
i = i−1 41
i = i−1 42

7
Items: Items:
1: (2,3) 1: (2,3)
Finding the Items (4) 2: (3,4) Finding the Items (5) 2: (3,4)
3: (4,5) 3: (4,5)
i\W 0 1 2 3 4 5 i=2 i\W 0 1 2 3 4 5 i=1
4: (5,6) 4: (5,6)
0 0 0 0 0 0 0 k= 5 0 0 0 0 0 0 0 k= 2
1 0 0 3 3 3 3 bi=4 1 0 0 3 3 3 3 bi=3
2 0 0 3 4 4 7 wi=3 2 0 0 3 4 4 7 wi=2
3 0 0 3 4 5 7 B[i,k] = 7 3 0 0 3 4 5 7 B[i,k] = 3
B[i−1,k] =3 B[i−1,k] =0
4 0 0 3 4 5 7 4 0 0 3 4 5 7
k − wi=2 k − wi=0
i=n, k=W i=n, k=W
while i,k > 0 while i,k > 0
if B[i,k] ≠ B[i−1,k] then if B[i,k] ≠ B[i−1,k] then
mark the ith item as in the knapsack mark the ith item as in the knapsack
i = i−1, k = k-wi i = i−1, k = k-wi
else else
i = i−1 43
i = i−1 44

Items: Items:
1: (2,3) 1: (2,3)
Finding the Items (6) 2: (3,4) Finding the Items (7) 2: (3,4)
3: (4,5) 3: (4,5)
i\W 0 1 2 3 4 5 i=0 i\W 0 1 2 3 4 5
4: (5,6) 4: (5,6)
0 0 0 0 0 0 0 k= 0 0 0 0 0 0 0 0
1 0 0 3 3 3 3 1 0 0 3 3 3 3
2 0 0 3 4 4 7 2 0 0 3 4 4 7
3 0 0 3 4 5 7 The optimal 3 0 0 3 4 5 7 The optimal
knapsack knapsack
4 0 0 3 4 5 7 4 0 0 3 4 5 7
should contain should contain
i=n, k=W {1, 2} i=n, k=W {1, 2}
while i,k > 0 while i,k > 0
if B[i,k] ≠ B[i−1,k] then if B[i,k] ≠ B[i−1,k] then
mark the nth item as in the knapsack mark the nth item as in the knapsack
i = i−1, k = k-wi i = i−1, k = k-wi
else else
i = i−1 45
i = i−1 46

Review: The Knapsack Problem Solving The Knapsack


And Optimal Substructure Problem
Both variations exhibit optimal substructure The optimal solution to the fractional knapsack
To show this for the 0-1 problem, consider the problem can be found with a greedy algorithm
» Do you recall how?
most valuable load weighing at most W pounds
» Greedy strategy: take in order of dollars/pound
» If we remove item j from the load, what do we know
about the remaining load? The optimal solution to the 0-1 problem cannot be
found with the same greedy strategy
» A: remainder must be the most valuable load weighing
at most W - wj that thief could take, excluding item j » Example: 3 items weighing 10, 20, and 30 pounds,
knapsack can hold 50 pounds
Suppose item 2 is worth $100. Assign values to the other items
so that the greedy strategy will fail

47 48

8
The Knapsack Problem:
Greedy Vs. Dynamic Memoization

The fractional problem can be solved Memoization is another way to deal with overlapping
subproblems in dynamic programming
greedily » After computing the solution to a subproblem, store it in a table
The 0-1 problem can be solved with a » Subsequent calls just do a table lookup
With memoization, we implement the algorithm
dynamic programming approach recursively:
» If we encounter a subproblem we have seen, we look up the
answer
» If not, compute the solution and add it to the list of subproblems
we have seen.
Must useful when the algorithm is easiest to implement
recursively
» Especially if we do not need solutions to all subproblems.
49 50

Conclusion

Dynamic programming is a useful technique of


solving certain kind of problems
When the solution can be recursively described in
terms of partial solutions, we can store these
partial solutions and re-use them as necessary
(memoization)
Running time of dynamic programming algorithm
vs. naïve algorithm:
» 0-1 Knapsack problem: O(W*n) vs. O(2n)

51

Das könnte Ihnen auch gefallen