2022-06-14 01:35:10 +02:00
|
|
|
#!/usr/bin/env python3
|
|
|
|
# -*- coding: utf-8 -*-
|
|
|
|
|
|
|
|
# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
|
|
# IMPORTS
|
|
|
|
# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
|
|
|
2022-06-14 09:03:29 +02:00
|
|
|
from src.thirdparty.code import *;
|
2022-06-14 01:35:10 +02:00
|
|
|
from src.thirdparty.maths import *;
|
2022-06-14 09:03:29 +02:00
|
|
|
from src.thirdparty.types import *;
|
2022-06-14 01:35:10 +02:00
|
|
|
|
|
|
|
from src.models.stacks import *;
|
2022-06-14 20:02:22 +02:00
|
|
|
from src.models.rucksack import *;
|
2022-06-14 01:35:10 +02:00
|
|
|
|
|
|
|
# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
|
|
# EXPORTS
|
|
|
|
# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
|
|
|
|
|
|
__all__ = [
|
2022-06-14 09:03:29 +02:00
|
|
|
'display_order',
|
2022-06-14 14:40:02 +02:00
|
|
|
'display_rucksack',
|
2022-06-14 01:35:10 +02:00
|
|
|
'display_branch_and_bound',
|
2022-06-14 14:40:02 +02:00
|
|
|
'display_sum',
|
2022-06-14 01:35:10 +02:00
|
|
|
];
|
|
|
|
|
|
|
|
# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
2022-06-14 09:03:29 +02:00
|
|
|
# METHOD display order
|
|
|
|
# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
|
|
|
|
|
|
def display_order(
|
|
|
|
order: List[int],
|
2022-06-14 14:40:02 +02:00
|
|
|
costs: np.ndarray,
|
2022-06-14 09:03:29 +02:00
|
|
|
values: np.ndarray,
|
|
|
|
items: np.ndarray,
|
|
|
|
one_based: bool = False,
|
|
|
|
) -> str:
|
|
|
|
table = pd.DataFrame({
|
2022-06-14 14:40:02 +02:00
|
|
|
'items': items,
|
|
|
|
'order': order,
|
|
|
|
'values': values,
|
|
|
|
'costs': costs,
|
2022-06-14 20:02:22 +02:00
|
|
|
'margin': [str(Fraction(Fraction(value), Fraction(cost))) for cost, value in zip(costs, values)],
|
2022-06-14 10:09:21 +02:00
|
|
|
}) \
|
|
|
|
.reset_index(drop=True);
|
2022-06-14 09:03:29 +02:00
|
|
|
if one_based:
|
2022-06-14 10:09:21 +02:00
|
|
|
table['order'] += 1;
|
2022-06-14 09:03:29 +02:00
|
|
|
# benutze pandas-Dataframe + tabulate, um schöner darzustellen:
|
|
|
|
repr = tabulate(
|
2022-06-14 14:40:02 +02:00
|
|
|
table,
|
|
|
|
headers=['item', 'greedy order', 'value', 'cost', 'value/cost'],
|
2022-06-14 09:03:29 +02:00
|
|
|
showindex=False,
|
|
|
|
colalign=('left', 'center', 'center', 'center', 'right'),
|
|
|
|
tablefmt='rst'
|
|
|
|
);
|
|
|
|
return repr;
|
|
|
|
|
|
|
|
# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
2022-06-14 14:40:02 +02:00
|
|
|
# METHOD display rucksack
|
2022-06-14 01:35:10 +02:00
|
|
|
# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
|
|
|
2022-06-14 14:40:02 +02:00
|
|
|
def display_rucksack(
|
|
|
|
items: np.ndarray,
|
|
|
|
costs: np.ndarray,
|
2022-06-14 01:35:10 +02:00
|
|
|
values: np.ndarray,
|
|
|
|
) -> str:
|
2022-06-14 20:02:22 +02:00
|
|
|
render = lambda r: f'{r:g}';
|
2022-06-14 14:40:02 +02:00
|
|
|
table = pd.DataFrame({
|
|
|
|
'items': items.tolist() + ['----', '∑'],
|
2022-06-14 20:02:22 +02:00
|
|
|
'costs': list(map(render, costs)) + ['', f'\x1b[92;1m{sum(costs):g}\x1b[0m'],
|
|
|
|
'values': list(map(render, values)) + ['', f'\x1b[92;1m{sum(values):g}\x1b[0m'],
|
2022-06-14 14:40:02 +02:00
|
|
|
});
|
|
|
|
repr = tabulate(
|
|
|
|
table,
|
|
|
|
headers=['item', 'cost', 'value'],
|
|
|
|
showindex=False,
|
|
|
|
colalign=('left', 'center', 'center'),
|
|
|
|
tablefmt='rst'
|
|
|
|
);
|
|
|
|
return repr;
|
2022-06-14 01:35:10 +02:00
|
|
|
|
2022-06-14 09:03:29 +02:00
|
|
|
# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
|
|
# METHOD display result of branch and bound
|
|
|
|
# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
|
|
|
2022-06-14 01:35:10 +02:00
|
|
|
def display_branch_and_bound(
|
|
|
|
values: np.ndarray,
|
2022-06-14 20:02:22 +02:00
|
|
|
steps: List[Tuple[float, float, Stack, List[Fraction], List[int], MaskValue]],
|
2022-06-14 01:35:10 +02:00
|
|
|
) -> str:
|
|
|
|
# füge Summen-Ausdrücke für Greedy-Alg hinzu:
|
|
|
|
rows = [];
|
2022-06-14 20:02:22 +02:00
|
|
|
used_choices = [];
|
|
|
|
for lb_estimate, lb, S, choice, order, pad in steps:
|
|
|
|
if choice in used_choices:
|
2022-06-14 12:19:35 +02:00
|
|
|
expr = f'{lb:g}';
|
2022-06-14 01:35:10 +02:00
|
|
|
else:
|
2022-06-14 20:02:22 +02:00
|
|
|
used_choices.append(choice);
|
|
|
|
expr = display_sum(choice=choice, values=values, as_maximum=False, order=order);
|
2022-06-14 20:10:54 +02:00
|
|
|
rows.append((f'{lb_estimate:+g}', expr, S, ('' if pad == MaskValue.UNSET else pad.value)));
|
2022-06-14 01:35:10 +02:00
|
|
|
|
|
|
|
table = pd.DataFrame(rows) \
|
2022-06-14 20:10:54 +02:00
|
|
|
.rename(columns={0: 'bound', 1: 'g(TOP(S))', 2: 'S', 3: 'pad?'}) \
|
2022-06-14 01:35:10 +02:00
|
|
|
.reset_index(drop=True);
|
|
|
|
# benutze pandas-Dataframe + tabulate, um schöner darzustellen:
|
|
|
|
repr = tabulate(
|
2022-06-14 14:40:02 +02:00
|
|
|
table,
|
2022-06-14 20:10:54 +02:00
|
|
|
headers=['bound', 'g(TOP(S))', 'S — stack', 'pad?'],
|
2022-06-14 01:35:10 +02:00
|
|
|
showindex=False,
|
2022-06-14 20:10:54 +02:00
|
|
|
colalign=('left', 'left', 'right', 'center'),
|
2022-06-14 01:35:10 +02:00
|
|
|
tablefmt='rst'
|
|
|
|
);
|
|
|
|
return repr;
|
2022-06-14 14:40:02 +02:00
|
|
|
|
|
|
|
# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
|
|
# METHOD display sum
|
|
|
|
# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
|
|
|
|
|
|
def display_sum(
|
2022-06-14 20:02:22 +02:00
|
|
|
choice: List[Fraction],
|
2022-06-14 14:40:02 +02:00
|
|
|
values: np.ndarray,
|
|
|
|
order: Optional[List[int]] = None,
|
|
|
|
as_maximum: bool = True,
|
|
|
|
) -> str:
|
2022-06-14 20:02:22 +02:00
|
|
|
parts = [ (u, x) for u, x in zip(choice, values)];
|
2022-06-14 14:40:02 +02:00
|
|
|
if not (order is None):
|
|
|
|
parts = [ parts[j] for j in order ];
|
|
|
|
value = sum([ u*x for u, x in parts]);
|
|
|
|
expr = '+'.join([
|
2022-06-14 20:02:22 +02:00
|
|
|
f'{x:g}' if u == 1 else f'{u}·{x:g}'
|
2022-06-14 14:40:02 +02:00
|
|
|
for u, x in parts if u > 0
|
|
|
|
]);
|
|
|
|
if as_maximum:
|
|
|
|
return f'{value:g} = {expr}';
|
|
|
|
else:
|
|
|
|
return f'-{value:g} = -({expr})';
|