ads2_2022/code/python/src/algorithms/rucksack/display.py

103 lines
3.3 KiB
Python
Raw Normal View History

#!/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;