Advertisement
Guest User

Untitled

a guest
Oct 18th, 2019
93
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 3.15 KB | None | 0 0
  1. """
  2. Solves the Knapsack overflow problem.
  3.  
  4. In this problem, we attempt to fill a Knapsack with items.
  5.  
  6. The constraints:
  7. - The Knapsack may not underflow (i.e. the Knapsack must have no space left)
  8. - The Knapsack may overflow
  9. - The value of items should be minimized
  10. - The quantity should be minimized
  11.  
  12. Computational complexity: O(n)
  13. """
  14. from copy import deepcopy
  15. from typing import List, Dict
  16. from collections import defaultdict
  17.  
  18.  
  19. class Knapsack:
  20. def __init__(self, min_weight: int):
  21. self.min_weight = min_weight
  22. self.weight = 0
  23. self.items = []
  24. self.price = 0
  25.  
  26. def add(self, item: dict):
  27. self.weight += item['quantity']
  28. self.price += item['price']
  29. self.items.append(item)
  30.  
  31. def remove(self, item: dict):
  32. self.weight -= item['quantity']
  33. self.price -= item['price']
  34. self.items.remove(item)
  35.  
  36. def fits(self, item: Dict[str, int]):
  37. return item['quantity'] <= self.min_weight - self.weight
  38.  
  39. def __str__(self):
  40. items = defaultdict(int)
  41. for item in self.items:
  42. items[item['quantity']] += 1
  43. formatted_items = ["{} x {}".format(i, items[i]) for i in items]
  44. return "KnapSack(price={}, weight={}, items={})".format(
  45. self.price, self.weight, formatted_items
  46. )
  47.  
  48. __repr__ = __str__
  49.  
  50.  
  51. def best_price(items: List[Dict[str, int]]) -> Dict[str, int]:
  52. """
  53. Given a list of items, find the best price/quantity ratio.
  54. """
  55. best_ratio = None
  56. cheapest_item = None
  57. for item in items:
  58. ratio = item["price"] / item["quantity"]
  59. if best_ratio is None or best_ratio > ratio:
  60. best_ratio = ratio
  61. cheapest_item = item
  62. return cheapest_item
  63.  
  64.  
  65. def find_solutions(knap_sack: Knapsack, items: List[Dict[str, int]]):
  66. """
  67. Find ways to fill the Knapsack, given the items.
  68.  
  69. Algorithm:
  70. 1. Find the item that has the best quantity/price ratio
  71. 2. Check if it fits
  72. If it does, fill it.
  73. if exact match: stop
  74. If it doesn't fill it anyway and mark it as a solution.
  75. Remove item from Knapsack
  76. Remove item from availabile items
  77. 3. Goto 1.
  78. solution := min(price), min(quantity)
  79. """
  80. solutions = []
  81. while knap_sack.weight < knap_sack.min_weight:
  82. item = best_price(items)
  83. if not item:
  84. print('items exhausted')
  85. break
  86. if not knap_sack.fits(item):
  87. knap_sack.add(item)
  88. solution = deepcopy(knap_sack)
  89. solutions.append(solution)
  90.  
  91. knap_sack.remove(item)
  92. items.remove(item)
  93. continue
  94.  
  95. knap_sack.add(item)
  96. if knap_sack.weight == knap_sack.min_weight:
  97. solution = deepcopy(knap_sack)
  98. solutions.append(solution)
  99. return solutions
  100.  
  101.  
  102. desired_quantity = 3780 # grams
  103. knapsack = Knapsack(desired_quantity)
  104. items = [{"quantity": 60, "price": 4}, {"quantity": 100, "price": 6}, {"quantity": 200, "price": 10}]
  105. solutions = find_solutions(knapsack, items)
  106.  
  107. # Minimalize price and then quantity. If there are solutions
  108. # with the same price, choose the one with the lowest quantity
  109. print(solutions)
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement