#!/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.core.utils 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: 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( vector: Union[List[int], List[float]], values: np.ndarray, ) -> 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 ]); 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]] ) -> str: # füge Summen-Ausdrücke für Greedy-Alg hinzu: rows = []; used_vectors = []; for lb_estimate, lb, u, S in steps: if u in used_vectors: rows.append((f'{lb_estimate:g}', f'{lb:g}', S)); else: used_vectors.append(u) rows.append((f'{lb_estimate:g}', display_sum(vector=u, values=values), S)); table = pd.DataFrame(rows) \ .rename(columns={0: 'b', 1: 'g(TOP(S))', 2: 'S'}) \ .reset_index(drop=True); # benutze pandas-Dataframe + tabulate, um schöner darzustellen: repr = tabulate( pd.DataFrame(table), headers=['b', 'g(TOP(S))', 'S'], showindex=False, colalign=('left', 'left', 'right'), tablefmt='rst' ); return repr;