Here's my code:
def knapsack_dynamic(ws, vs, W):
n = len(ws)
K = [[0] * (W+1)] * (n+1)
for i in range(n+1):
for w in range(W+1):
if i == 0 or w == 0: # knapsack is empty or no more weight to carry
K[i][w] = 0
else:
if ws[i-1] > w:
K[i][w] = K[i-1][w]
else:
K[i][w] = max(vs[i-1] + K[i-1][w-ws[i-1]], K[i-1][w])
return K[n][W]
Here's how to test it:
maxw = 50
ws = [10, 20, 30]
vs = [60, 100, 120]
print(knapsack_dynamic(ws, vs, maxw)) # should print 220
I'm not sure why I'm getting 300
instead of 220
.
Can you help me figuring it out please?
The error is made during the matrix initialization:
Replace
K = [[0] * (W+1)] * (n+1)
by
K = [[0] * (W+1) for i in range(n+1)]
or by
K = [[0 for w in range(W+1)] for i in range(n+1)]
When applying the repeat operator *
on nested lists, only the reference is repeated not the values.
Try this simple example:
m = [[0] * 4] * 3
print(m) # --> [[0, 0, 0, 0], [0, 0, 0, 0], [0, 0, 0, 0]]
m[0][0] = 5
print(m) # --> [[5, 0, 0, 0], [5, 0, 0, 0], [5, 0, 0, 0]]