diff --git a/code/python/src/algorithms/rucksack/algorithms.py b/code/python/src/algorithms/rucksack/algorithms.py index a72196c..525d54c 100644 --- a/code/python/src/algorithms/rucksack/algorithms.py +++ b/code/python/src/algorithms/rucksack/algorithms.py @@ -42,7 +42,16 @@ def rucksack_greedy_algorithm( eine obere Schranke des maximalen Wertes beim Originalproblem. ''' # sortiere daten: - resort_by_value_per_weight(weights=weights, values=values, items=items); + order = resort_by_value_per_weight(weights=weights, values=values, items=items); + + # verbose output hier behandeln (irrelevant für Algorithmus): + if verbose: + repr = display_order(order=order, weights=weights, values=values, items=items, one_based=True); + print(''); + print('\x1b[1mRucksack Problem - Greedy\x1b[0m'); + print(''); + print(repr); + print(''); # führe greedy aus: n = len(weights); @@ -74,8 +83,7 @@ def rucksack_greedy_algorithm( if verbose: expr_value = display_sum(vector=soln.vector, values=values); expr_weight = display_sum(vector=soln.vector, values=weights); - print(''); - print('\x1b[1mRucksack Problem - Greedy\x1b[0m'); + print('\x1b[1mEingeschätztes Maximum\x1b[0m'); print(''); print(f'Rucksack: {", ".join(soln.items)}.'); if fractional: @@ -103,9 +111,18 @@ def rucksack_branch_and_bound_algorithm( unter Rücksicht der Kapizitätsschranke exakt und effizienter bestimmt. ''' - resort_by_value_per_weight(weights=weights, values=values, items=items); - logged_steps = []; + order = resort_by_value_per_weight(weights=weights, values=values, items=items); + # verbose output hier behandeln (irrelevant für Algorithmus): + if verbose: + repr = display_order(order=order, weights=weights, values=values, items=items, one_based=True); + print(''); + print('\x1b[1mRucksack Problem - Branch & Bound\x1b[0m'); + print(''); + print(repr); + print(''); + + logged_steps = []; vector = empty_mask(n=len(weights)); lb_estimate = np.inf; S = Stack(); @@ -144,8 +161,7 @@ def rucksack_branch_and_bound_algorithm( expr_value = display_sum(vector=soln.vector, values=values); expr_weight = display_sum(vector=soln.vector, values=weights); repr = display_branch_and_bound(values=values, steps=logged_steps); - print(''); - print('\x1b[1mRucksack Problem - Branch & Bound\x1b[0m'); + print('\x1b[1mMaximum\x1b[0m'); print(''); print(repr); print(''); @@ -154,7 +170,6 @@ def rucksack_branch_and_bound_algorithm( print(f'∑ Weights = {expr_weight}'); print(''); - # Lösung ausgeben return soln; diff --git a/code/python/src/algorithms/rucksack/display.py b/code/python/src/algorithms/rucksack/display.py index 2d81c8e..5223182 100644 --- a/code/python/src/algorithms/rucksack/display.py +++ b/code/python/src/algorithms/rucksack/display.py @@ -5,9 +5,11 @@ # IMPORTS # ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -from src.thirdparty.types import *; +from src.thirdparty.code import *; from src.thirdparty.maths import *; +from src.thirdparty.types import *; +from src.core.utils import *; from src.models.stacks import *; # ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ @@ -15,12 +17,46 @@ from src.models.stacks import *; # ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ __all__ = [ + 'display_order', 'display_sum', 'display_branch_and_bound', ]; # ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -# METHODS display +# METHOD display order +# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +def display_order( + order: List[int], + weights: np.ndarray, + values: np.ndarray, + items: np.ndarray, + one_based: bool = False, +) -> str: + index = range(len(order)); + uorder = iperm(order); + table = pd.DataFrame({ + 'items': items, + 'index': index, + 'values': values, + 'weights': weights, + 'u': (values/weights), + }, index=index) \ + .reindex(uorder); + if one_based: + table['index'] += 1; + # benutze pandas-Dataframe + tabulate, um schöner darzustellen: + repr = tabulate( + pd.DataFrame(table), + headers=['item', 'greedy order', 'value', 'weight', 'value/weight'], + showindex=False, + colalign=('left', 'center', 'center', 'center', 'right'), + tablefmt='rst' + ); + return repr; + +# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +# METHOD display sum # ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ def display_sum( @@ -34,6 +70,10 @@ def display_sum( ]); return f'{value:g} (={expr})'; +# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +# METHOD display result of branch and bound +# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + def display_branch_and_bound( values: np.ndarray, steps: List[Tuple[float, float, Stack]] diff --git a/code/python/src/core/utils.py b/code/python/src/core/utils.py new file mode 100644 index 0000000..0585607 --- /dev/null +++ b/code/python/src/core/utils.py @@ -0,0 +1,30 @@ +#!/usr/bin/env python3 +# -*- coding: utf-8 -*- + +# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +# IMPORTS +# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +from src.thirdparty.code import *; +from src.thirdparty.types import *; + +# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +# EXPORTS +# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +__all__ = [ + 'iperm', +]; + +# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +# METHODS permutations +# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +def iperm(order: List[int]) -> List[int]: + ''' + Computes the inverse of a permutation. + ''' + n = len(order); + perm = list(enumerate(order)); + uorder = list(map(lambda x: x[0], sorted(perm, key=lambda x: x[1]))); + return uorder;