diff --git a/Pipfile b/Pipfile new file mode 100644 index 0000000..6ba0927 --- /dev/null +++ b/Pipfile @@ -0,0 +1,12 @@ +[[source]] +url = "https://pypi.org/simple" +verify_ssl = true +name = "pypi" + +[packages] +tabulate = "*" + +[dev-packages] + +[requires] +python_version = "3.11" diff --git a/Pipfile.lock b/Pipfile.lock new file mode 100644 index 0000000..2447e20 --- /dev/null +++ b/Pipfile.lock @@ -0,0 +1,30 @@ +{ + "_meta": { + "hash": { + "sha256": "5b2e934e1ca40f369f7dcd74ed36744eae3116276796320e2800026566302307" + }, + "pipfile-spec": 6, + "requires": { + "python_version": "3.11" + }, + "sources": [ + { + "name": "pypi", + "url": "https://pypi.org/simple", + "verify_ssl": true + } + ] + }, + "default": { + "tabulate": { + "hashes": [ + "sha256:0095b12bf5966de529c0feb1fa08671671b3368eec77d7ef7ab114be2c068b3c", + "sha256:024ca478df22e9340661486f85298cff5f6dcdba14f3813e8830015b9ed1948f" + ], + "index": "pypi", + "markers": "python_version >= '3.7'", + "version": "==0.9.0" + } + }, + "develop": {} +} diff --git a/chapter11/knapsack.py b/chapter11/knapsack.py new file mode 100644 index 0000000..45f4c6a --- /dev/null +++ b/chapter11/knapsack.py @@ -0,0 +1,58 @@ +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 Item: + name: str + value: int + weight: int + + +def dynamic(W, items, n): + # create table and zero fill it (required for calculations) + table = [[0 for _ in range(W + 1)] for _ in range(n + 1)] + + # calcalate all possible max values for items in knapsack + for i in range(1, n + 1): + for w in range(1, W + 1): + if items[i - 1].weight <= w: + table[i][w] = max( + items[i - 1].value + table[i - 1][w - items[i - 1].weight], + 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] = items[i - 1].name + table[0] = [i for i in range(W + 1)] + table[0][0] = None + + # print tabularised 2D array + logger.info(tabulate(table, tablefmt="pretty")) + + +items = [Item("Guitar", 1500, 1), Item("Stereo", 3000, 4), Item("Laptop", 2000, 3)] +W = 4 +greatest_value = dynamic(W, items, len(items)) + +print(greatest_value)