Greedy-Algorithms: Knapsack small code cleanup
This commit is contained in:
@@ -9,10 +9,10 @@ Honor Code and Acknowledgments:
|
||||
"""
|
||||
|
||||
from dataclasses import dataclass
|
||||
from typing import override
|
||||
from typing import Self, override
|
||||
|
||||
|
||||
# I don't like tuples
|
||||
# I don't like tuples, dataclasses ftw
|
||||
@dataclass(frozen=True)
|
||||
class KnapsackItem:
|
||||
name: str
|
||||
@@ -20,42 +20,42 @@ class KnapsackItem:
|
||||
weight: float
|
||||
|
||||
@property
|
||||
def value_per(self) -> float:
|
||||
def value_ratio(self) -> float:
|
||||
return self.value / self.weight
|
||||
|
||||
@override
|
||||
def __str__(self) -> str:
|
||||
return f"{self.name}({self.value:.2f}, {self.weight:.2f})"
|
||||
|
||||
@staticmethod
|
||||
def from_str(string: str) -> "KnapsackItem":
|
||||
values: list[str] = string.split()
|
||||
@classmethod
|
||||
def parse(cls, string: str) -> Self:
|
||||
values: list[str] = string.strip().split()
|
||||
name, value, weight = values[0], float(values[1]), float(values[2])
|
||||
return KnapsackItem(name, value, weight)
|
||||
return cls(name, value, weight)
|
||||
|
||||
|
||||
def knapsack(
|
||||
capacity: int, items: list[KnapsackItem]
|
||||
) -> tuple[list[KnapsackItem], float]:
|
||||
cur_capacity: float = capacity
|
||||
sorted_items: list[KnapsackItem] = sorted(items, key=lambda i: -i.value_per)
|
||||
|
||||
current_capacity: float = float(capacity)
|
||||
sorted_items: list[KnapsackItem] = sorted(items, key=lambda i: -i.value_ratio)
|
||||
|
||||
total_value: float = 0.0
|
||||
fractional_items: list[KnapsackItem] = []
|
||||
|
||||
for item in sorted_items:
|
||||
if abs(cur_capacity) < 1e-8:
|
||||
if abs(current_capacity) < 1e-8:
|
||||
break
|
||||
|
||||
if cur_capacity < item.weight:
|
||||
value: float = item.value_per * cur_capacity
|
||||
name, value, weight = item.name, item.value, item.weight
|
||||
if current_capacity < weight:
|
||||
value = item.value_ratio * current_capacity
|
||||
weight = current_capacity
|
||||
|
||||
fractional_items.append(KnapsackItem(name, value, weight))
|
||||
total_value += value
|
||||
fractional_items.append(KnapsackItem(item.name, value, cur_capacity))
|
||||
cur_capacity = 0
|
||||
else:
|
||||
total_value += item.value
|
||||
fractional_items.append(KnapsackItem(item.name, item.value, item.weight))
|
||||
cur_capacity -= item.weight
|
||||
current_capacity -= weight
|
||||
|
||||
return fractional_items, total_value
|
||||
|
||||
@@ -66,7 +66,7 @@ def main():
|
||||
capacity: int = int(input())
|
||||
n: int = int(input())
|
||||
|
||||
items: list[KnapsackItem] = [KnapsackItem.from_str(input()) for _ in range(0, n)]
|
||||
items: list[KnapsackItem] = [KnapsackItem.parse(input()) for _ in range(0, n)]
|
||||
|
||||
fractional_items, total_value = knapsack(capacity, items)
|
||||
|
||||
|
||||
Reference in New Issue
Block a user