Knapsack problem/Unbounded: Difference between revisions

Content deleted Content added
Line 568: Line 568:
A dynamic programming approach using a 2-dimensional table (One dimension for weight and one for volume). Because this approach requires that all weights and volumes be integer, I multiplied the weights and volumes by enough to make them integer. This algorithm takes O(w*v) space and O(w*v*n) time, where w = weight of sack, v = volume of sack, n = number of types of items. To solve this specific problem it's much slower than the brute force solution.
A dynamic programming approach using a 2-dimensional table (One dimension for weight and one for volume). Because this approach requires that all weights and volumes be integer, I multiplied the weights and volumes by enough to make them integer. This algorithm takes O(w*v) space and O(w*v*n) time, where w = weight of sack, v = volume of sack, n = number of types of items. To solve this specific problem it's much slower than the brute force solution.


<python>from itertools import product, izip
<python>
from itertools import product, izip
from collections import namedtuple
from collections import namedtuple


Line 589: Line 588:




def tot_value(items_count):
def tot_value(items_count, items, sack):
"""
"""
Given the count of each item in the sack return -1 if they can't be carried or their total value.
Given the count of each item in the sack return -1 if they can't be carried or their total value.
Line 596: Line 595:
values will minimise the weight if values tie, and minimise the volume if values and weights tie).
values will minimise the weight if values tie, and minimise the volume if values and weights tie).
"""
"""
global items, sack
weight = sum(n * item.weight for n, item in izip(items_count, items))
weight = sum(n * item.weight for n, item in izip(items_count, items))
volume = sum(n * item.volume for n, item in izip(items_count, items))
volume = sum(n * item.volume for n, item in izip(items_count, items))
Line 605: Line 603:




def knapsack_dp():
def knapsack_dp(items, sack):
"""
"""
Solves the Knapsack problem, with two sets of weights,
Solves the Knapsack problem, with two sets of weights,
using a dynamic programming approach
using a dynamic programming approach
"""
"""
global items, sack

# (weight+1) x (volume+1) table
# (weight+1) x (volume+1) table
# table[w][v] is the maximum value that can be achieved
# table[w][v] is the maximum value that can be achieved
Line 637: Line 633:
while table[w][v]:
while table[w][v]:
# Find the last item that was added:
# Find the last item that was added:
i = [table[w-item.weight][v-item.volume] + item.value for item in items].index(table[w][v])
aux = [table[w-item.weight][v-item.volume] + item.value for item in items]
i = aux.index(table[w][v])


# Record it in the result, and remove it:
# Record it in the result, and remove it:
Line 647: Line 644:




max_items = knapsack_dp()
max_items = knapsack_dp(items, sack)
max_value, max_weight, max_volume = tot_value(max_items)
max_value, max_weight, max_volume = tot_value(max_items, items, sack)
max_weight = -max_weight
max_weight = -max_weight
max_volume = -max_volume
max_volume = -max_volume
Line 655: Line 652:
item_names = ", ".join(item.name for item in items)
item_names = ", ".join(item.name for item in items)
print " The number of %s items to achieve this is: %s, respectively." % (item_names, max_items)
print " The number of %s items to achieve this is: %s, respectively." % (item_names, max_items)
print " The weight to carry is %.3g, and the volume used is %.3g." % (max_weight, max_volume)
print " The weight to carry is %.3g, and the volume used is %.3g." % (max_weight, max_volume)</python>
</python>


Sample output
Sample output