In [2]:
from typing import List
In [13]:
# this amounts to a greedy solution, incorrect
def knapsack_one_of_each_attempt1(ws: List[int],
vs: List[int],
b: int) -> int:
n = len(ws)
k = [0] * n
w = [0] * n
k[0] = vs[0] if ws[0] <= b else 0
w[0] = ws[0] if ws[0] <= b else 0
for i in range(1, n):
k[i], w[i] = max(
(vs[i] if ws[i] <= b else 0, ws[i]), # just the item itself
max([
(
(vs[i] if w[j] + ws[i] <= b else 0) + k[j],
w[j] + (ws[i] if w[j] + ws[i] <= b else 0)
)
for j in range(i)
])
)
print(w)
print(k)
return k[-1]
In [15]:
knapsack_one_of_each([15, 12, 10, 5], [15, 10, 8, 1], 22) == 18
Out[15]:
In [16]:
import numpy as np
In [21]:
def knapsack_one_of_each_attempt2(ws: List[int],
vs: List[int],
b: int) -> int:
n = len(ws)
k = np.zeros((n + 1, b + 1))
for i in range(1, n + 1):
for b in range(1, b + 1):
if ws[i - 1] <= b:
k[i, b] = max(k[i, b - ws[i - 1]] + vs[i - 1],
k[i - 1, b])
else:
k[i, b] = k[i - 1, b]
return k[n, b]
In [23]:
knapsack_one_of_each_attempt2([15, 12, 10, 5], [15, 10, 8, 1], 22)
Out[23]: