Knapsack
Page content
-
For given weights and values of $n$ items, we have to choose sets of weights that can fill up the maximum capacity $w$ in a bag of capacity $W$.
-
This set should contain a maximum number of items.
-
The expected output is an integer with a count of a maximum number of items.
-
Applications
- Resource allocation
-
Approaches
- Greedy
- DP
- Brute force
0-1 Knapsack
# O(2^n) as there are redundant subproblems
def knapSack(W, wt, val, n):
if n == 0 or W == 0:
return 0
if wt[n-1] > W:
return knapSack(W, wt, val, n-1)
# pick or don't pick
return max( knapSack(W - wt[n-1], wt, val, n-1) + val[n-1],
knapSack(W, wt, val, n-1) )
val = [60, 100, 120]
wt = [10, 20, 30]
W = 50
n = len(val)
print(knapSack(W, wt, val, n))
0-1 Knapsack DP
- You cannot break an item
- pick OR
- don’t pick
def knapSack(W, w, val):
num_items = len(val)
m = {}
for c in range(W+1):
m[(0,c)] = 0
for i in range(1, num_items+1):
for c in range(W+1):
if w[i-1] <= c:
m[(i,c)] = max(m[i-1,c], val[i-1]+m[(i-1,c-w[i-1])])
else:
m[(i,c)] = m[(i-1,c)]
return m[(num_items,W)]
print(knapSack(W=50, w=[10, 20, 30], val=[60, 100, 120]))