Knapsack problem/Unbounded/Python dynamic programming: Difference between revisions

imported>Katsumi
 
(4 intermediate revisions by 4 users not shown)
Line 1:
{{collection|Knapsack problem/Unbounded}}
 
===Dynamic Programming Solution===
=={{header|Python}}==
===Dynamic Programming Solution===
This solution trades off having to search over all possible combinations of items by having to enumerate over all possible sizes of (weight, volume) for each item. The example builds in complexity to the final DP program.
 
====Brute force, single size attribute====
A brute-force solution for items with only one 'size' attribute would look like the following and would not scale:
<syntaxhighlight lang="python">
<lang python>from operator import itemgetter as iget
from itertools import product
from random import shuffle
Line 45:
 
return value, size, numbagged, bagged
</syntaxhighlight>
</lang>
 
====DP, single size dimension====
The dynamic programming version where 'size' has only one dimension would be the following and produces an optimal solution:
<syntaxhighlight lang="python">
<lang python>def knapsack_unbounded_dp(items, C):
# order by max value per item size
items = sorted(items, key=lambda item: item[VALUE]/float(item[SIZE]), reverse=True)
Line 73 ⟶ 74:
bagged = sorted((items[i][NAME], n) for i,n in enumerate(bagged) if n)
 
return value, size, numbagged, bagged</lang>
</syntaxhighlight>
 
====DP, multiple size dimensions====
Our original problem has two dimensions to 'size': weight and volume. We can create a python size object, that kowsknows how to enumerate itself over its given dimensions, as well as perform logical and simple mathematical operations. With the use of the Size object, a correct solution to the given unbounded knapsack problem can be found by the following proceedure:
<syntaxhighlight lang="python">
<lang python>from knapsack_sizer import makesize
 
Size = makesize('wt vol')
Line 117 ⟶ 120:
 
dp = knapsack_unboundedmulti_dp(items, capacity)
print(capacity, dp)</lang>
</syntaxhighlight>
 
====Sample output====
The solution found is printed as:
<pre>
<pre>Size(wt=250, vol=250) (54500, Size(247, 247), 20, [('gold', 11), ('panacea', 9)])</pre>
</langpre>
I.e. a choice of 20 items: 11 gold and 9 panacea, for a total value of 54500.
 
====Ancillary module====
An ancillary file called knapsack_sizer.py must be made available on your PYTHONPATH with the following contents:
<syntaxhighlight lang="python">
<lang python>from operator import itemgetter as _itemgetter
from collections import namedtuple as _namedtuple
from math import sqrt as _sqrt
Line 137 ⟶ 144:
'''
Return Size, an extended namedtuple that represents a container
of N integer independantindependent dimensions, e.g. weight and volume
a dimension cannot be less than zero and will instead force all
dimensions to zero.
Line 419 ⟶ 426:
Size = makesize('wt vol')
x,y = Size(*[1,2]), Size(*[3,4])
</syntaxhighlight>
</lang>
Anonymous user