#!/usr/bin/env python3 # -*- coding: utf-8 -*- # ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ # IMPORTS # ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ from src.thirdparty.code import *; from src.thirdparty.maths import *; from src.thirdparty.types import *; from src.models.stacks import *; # ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ # EXPORTS # ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ __all__ = [ 'display_order', 'display_sum', 'display_branch_and_bound', ]; # ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ # METHOD display order # ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ def display_order( order: List[int], weights: np.ndarray, values: np.ndarray, items: np.ndarray, one_based: bool = False, ) -> str: table = pd.DataFrame({ 'items': items, 'order': order, 'values': values, 'weights': weights, 'u': (values/weights), }) \ .reset_index(drop=True); if one_based: table['order'] += 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( vector: List[float], values: np.ndarray, as_maximum: bool = True, ) -> str: value = sum([ u*x for u, x in zip(vector,values)]); expr = '+'.join([ f'{x:g}' if u == 1 else f'{Fraction(str(u))}·{x:g}' for u, x in zip(vector,values) if u > 0 ]); if as_maximum: return f'{value:g} = {expr}'; else: 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, List[float], bool, bool]] ) -> str: # füge Summen-Ausdrücke für Greedy-Alg hinzu: rows = []; used_vectors = []; for lb_estimate, lb, S, u, can_add_all, can_add_none in steps: pad = '1' if can_add_all else ('0' if can_add_none else ''); if u in used_vectors: expr = f'{lb:g}'; else: used_vectors.append(u) expr = display_sum(vector=u, values=values, as_maximum=False); rows.append((f'{lb_estimate:g}', expr, pad, S)); table = pd.DataFrame(rows) \ .rename(columns={0: 'b', 1: 'g(TOP(S))', 2: 'pad?', 3: 'S'}) \ .reset_index(drop=True); # benutze pandas-Dataframe + tabulate, um schöner darzustellen: repr = tabulate( pd.DataFrame(table), headers=['b', 'g(TOP(S))', 'pad?', 'S'], showindex=False, colalign=('left', 'left', 'center', 'right'), tablefmt='rst' ); return repr;