grokking-algorithms/chapter11/travel.py

66 lines
1.7 KiB
Python

import logging
from dataclasses import dataclass
from tabulate import tabulate
logging.basicConfig(
level=logging.DEBUG,
format="%(asctime)s %(levelname)s\n\r%(message)s",
datefmt="%H:%M:%S",
)
logger = logging.getLogger(__name__)
@dataclass
class Location:
name: str
time: int
rating: int
def dynamic(items, n):
# create table and zero fill it (required for calculations)
table = [[0 for _ in range(2 * (W + 1) - 1)] for _ in range(n + 1)]
# calculate all possible max values for items in knapsack
for i in range(1, n + 1):
for w in range(1, 2 * (W + 1) - 1):
if items[i - 1].time <= w:
table[i][w] = max(
items[i - 1].rating + table[i - 1][w - items[i - 1].time],
table[i - 1][w],
)
else:
table[i][w] = table[i - 1][w]
format_and_print(table)
return table[-1][-1]
def format_and_print(table):
# enumerate first row (headings) + label each row in column0
for i, row in enumerate(table):
if i == 0:
continue
row[0] = locations[i - 1].name
table[0] = [None, *[i / 2 for i in range(1, 2 * (W + 1) - 1)]]
# print tabularised 2D array
logger.info([item.name for item in locations])
logger.info(tabulate(table, tablefmt="pretty"))
# values converted to integers
locations = [
Location("Westminster Abbey", 1, 7),
Location("Globe Theater", 1, 6),
Location("National Gallery", 2, 9),
Location("British Museum", 4, 9),
Location("St. Pauls Cathedral", 1, 8),
]
W = 2
greatest_value = dynamic(locations, len(locations))
print(f"Greatest value: {greatest_value}")