The standard 0/1 knapsack problem lends itself to a simple DP solution: with n
distinct objects with irrational values, integer weights, and a max weight of W
, make an n x W
array m
and let m[i, j]
be the maximum value achievable with items 1 to i
and a weight of at most j
.
I'm trying to solve the problem where the weights are irrational but the values are rational. I'm told that there is an O(nV)
solution, where V
is the sum of all of the values. I want to say something like this: let m
be an n x V
array, and let m[i, j]
be the minimum possible weight to achieve a value of at least j
with items 1 to i
. This would yield something like the following:
def knapsack(weights, values, max_weight):
max_v = sum(values)
m = [[0 for _ in range(max_v)] for _ in weights]
for i in range(len(weights)):
for j in range(max_v):
if j < values[i]:
m[i][j] = m[i - 1][j]
else:
m[i][j] = min(m[i - 1][j], weights[i] + m[i - 1][j - values[i]])
for val, col in reversed(enumerate(zip(*m))):
wt = min(col)
if wt <= max_weight:
return col
return 0
But this doesn't work: cells like m[0, 100]
get initialized with meaningless junk that propagates downward. I'm not sure how to solve this, and I can't find any info. It looks like this question would provide an algorithm to fill each cell, but it would be too expensive to call for every single one.