Created
January 28, 2015 12:38
-
-
Save vterron/65febebcfdb83878c420 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#! /usr/bin/env python | |
import collections | |
import functools | |
import random | |
class Item(collections.namedtuple('_Item', "value weight")): | |
@classmethod | |
def random(cls): | |
""" Return a random Item object. """ | |
value = random.randint(1, 100) | |
weight = random.randint(1, 25) | |
return cls(value, weight) | |
@functools.lru_cache(maxsize=None) | |
def knapsack(items, capacity): | |
""" A Pythonic solution to the 0/1 knapsack problem. | |
Kudos to this answer on Stack Exchange: | |
http://codereview.stackexchange.com/a/20581 | |
""" | |
if not items or not capacity: | |
return 0, [] | |
item = items[-1] | |
rest = items[:-1] | |
# If we put this item in the knapsack, we need to solve the problem | |
# for the remaining items, subtracting the weight of the item from | |
# the capacity of the knapsack. If we do not select the item, also | |
# solve for the remaining items, but without subtracting the weight. | |
# Return the maximum of both possibilities (select / don't select). | |
subproblems = [] | |
# Two element tuple: (total, items) | |
dont_choose = knapsack(rest, capacity) | |
subproblems.append(dont_choose) | |
if item.weight <= capacity: | |
sub_max, sub_items = knapsack(rest, capacity - item.weight) | |
choose_it = item.value + sub_max, [item] + sub_items | |
subproblems.append(choose_it) | |
return max(subproblems) | |
items = (Item(4, 12), Item(2, 1), Item(6, 4), Item(1, 1), Item(2, 2)) | |
capacity = 15 | |
print(knapsack(items, capacity)) | |
#items = tuple(Item.random() for _ in range(25)) | |
#capacity = sum(i.weight for i in items) // 2 | |
#print(knapsack(items, capacity)) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment