Compare commits

..

No commits in common. "56a93bbac9fd44c3578f4be4a4cd54ea09c449ea" and "828000a2ac7e20b6403e4f35b497f28b7e5ed237" have entirely different histories.

4 changed files with 28 additions and 52 deletions

View File

@ -80,7 +80,6 @@
algorithm: GREEDY algorithm: GREEDY
allow-fractional: true allow-fractional: true
capacity: 10 capacity: 10
items: [a, b, c, d, e]
weights: weights:
[3, 4, 5, 2, 1] [3, 4, 5, 2, 1]
values: values:
@ -89,6 +88,7 @@
algorithm: BRANCH-AND-BOUND algorithm: BRANCH-AND-BOUND
- name: RUCKSACK - name: RUCKSACK
algorithm: BRANCH-AND-BOUND algorithm: BRANCH-AND-BOUND
allow-fractional: true
capacity: 90 capacity: 90
items: [ items: [
'Sonnenblumenkerne', 'Sonnenblumenkerne',

View File

@ -116,6 +116,7 @@ components:
type: object type: object
required: required:
- algorithm - algorithm
- allow-fractional
- capacity - capacity
- weights - weights
- values - values

View File

@ -9,7 +9,6 @@ from src.thirdparty.types import *;
from src.thirdparty.maths import *; from src.thirdparty.maths import *;
from models.generated.config import *; from models.generated.config import *;
from src.core.utils import *;
from src.models.rucksack import *; from src.models.rucksack import *;
from src.models.stacks import *; from src.models.stacks import *;
from src.algorithms.rucksack.display import *; from src.algorithms.rucksack.display import *;
@ -44,11 +43,10 @@ def rucksack_greedy_algorithm(
''' '''
# sortiere daten: # sortiere daten:
order = resort_by_value_per_weight(weights=weights, values=values, items=items); order = resort_by_value_per_weight(weights=weights, values=values, items=items);
uorder = iperm(order);
# verbose output hier behandeln (irrelevant für Algorithmus): # verbose output hier behandeln (irrelevant für Algorithmus):
if verbose: if verbose:
repr = display_order(order=order, weights=weights[uorder], values=values[uorder], items=items[uorder], one_based=True); repr = display_order(order=order, weights=weights, values=values, items=items, one_based=True);
print(''); print('');
print('\x1b[1mRucksack Problem - Greedy\x1b[0m'); print('\x1b[1mRucksack Problem - Greedy\x1b[0m');
print(''); print('');
@ -59,19 +57,21 @@ def rucksack_greedy_algorithm(
n = len(weights); n = len(weights);
weight_total = 0; weight_total = 0;
vector = [ 0 for _ in range(n) ]; vector = [ 0 for _ in range(n) ];
rucksack = [];
for i in range(n): for i in range(n):
# füge Item i hinzu, solange das Gesamtgewicht noch <= Schranke # füge Item i hinzu, solange das Gesamtgewicht noch <= Schranke
if weight_total + weights[i] <= capacity: if weight_total + weights[i] <= capacity:
weight_total += weights[i]; weight_total += weights[i];
rucksack.append(i);
vector[i] = 1; vector[i] = 1;
# sonst abbrechen. Falls Bruchteile erlaubt, füge einen Bruchteil des i. Items hinzu # sonst abbrechen. Falls Bruchteile erlaubt, füge einen Bruchteil des i. Items hinzu
else: else:
if fractional: if fractional:
rucksack.append(i);
vector[i] = (capacity - weight_total)/weights[i]; vector[i] = (capacity - weight_total)/weights[i];
break; break;
# Aspekte der Lösung speichern: # Aspekte der Lösung speichern:
rucksack = [i for i, v in enumerate(vector) if v > 0]; # Indexes von Items im Rucksack
soln = Solution( soln = Solution(
vector = vector, vector = vector,
items = items[rucksack].tolist(), items = items[rucksack].tolist(),
@ -81,19 +81,13 @@ def rucksack_greedy_algorithm(
# verbose output hier behandeln (irrelevant für Algorithmus): # verbose output hier behandeln (irrelevant für Algorithmus):
if verbose: if verbose:
# Umsortierung rückgängig machen: expr_value = display_sum(vector=soln.vector, values=values);
vector = [ soln.vector[i] for i in order ]; expr_weight = display_sum(vector=soln.vector, values=weights);
rucksack = [ uorder[r] for r in rucksack ]; print('\x1b[1mEingeschätztes Maximum\x1b[0m');
permute_data(weights=weights, values=values, items=items, perm=uorder);
# Ausdrücke bestimmen:
expr_value = display_sum(vector=vector, values=values);
expr_weight = display_sum(vector=vector, values=weights);
print('\x1b[1mEingeschätzte Lösung\x1b[0m');
print(''); print('');
print(f'Rucksack: {", ".join(soln.items)}.');
if fractional: if fractional:
print(f'Mask: {soln.vector}'); print(f'Vector: {soln.vector_support}');
print(f' ---> {vector} (unter urspr. Sortierung)');
print(f'Rucksack: {", ".join(items[rucksack])}.');
print(f'max. Value ≈ {expr_value}'); print(f'max. Value ≈ {expr_value}');
print(f'∑ Weights = {expr_weight}'); print(f'∑ Weights = {expr_weight}');
print(''); print('');
@ -118,11 +112,10 @@ def rucksack_branch_and_bound_algorithm(
''' '''
order = resort_by_value_per_weight(weights=weights, values=values, items=items); order = resort_by_value_per_weight(weights=weights, values=values, items=items);
uorder = iperm(order);
# verbose output hier behandeln (irrelevant für Algorithmus): # verbose output hier behandeln (irrelevant für Algorithmus):
if verbose: if verbose:
repr = display_order(order=order, weights=weights[uorder], values=values[uorder], items=items[uorder], one_based=True); repr = display_order(order=order, weights=weights, values=values, items=items, one_based=True);
print(''); print('');
print('\x1b[1mRucksack Problem - Branch & Bound\x1b[0m'); print('\x1b[1mRucksack Problem - Branch & Bound\x1b[0m');
print(''); print('');
@ -165,22 +158,14 @@ def rucksack_branch_and_bound_algorithm(
# verbose output hier behandeln (irrelevant für Algorithmus): # verbose output hier behandeln (irrelevant für Algorithmus):
if verbose: if verbose:
# NOTE: Information in Tabelle gemäß permutierten Daten: 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); repr = display_branch_and_bound(values=values, steps=logged_steps);
# Umsortierung rückgängig machen: print('\x1b[1mMaximum\x1b[0m');
vector = [ soln.vector[i] for i in order ];
rucksack = [ uorder[r] for r in rucksack ];
permute_data(weights=weights, values=values, items=items, perm=uorder);
# Ausdrücke bestimmen:
expr_value = display_sum(vector=vector, values=values);
expr_weight = display_sum(vector=vector, values=weights);
print('\x1b[1mLösung\x1b[0m');
print(''); print('');
print(repr); print(repr);
print(''); print('');
print(f'Mask: {soln.vector}'); print(f'Rucksack: {", ".join(soln.items)}.');
print(f' ---> {vector} (unter urspr. Sortierung)');
print(f'Rucksack: {", ".join(items[rucksack])}.');
print(f'max. Value ≈ {expr_value}'); print(f'max. Value ≈ {expr_value}');
print(f'∑ Weights = {expr_weight}'); print(f'∑ Weights = {expr_weight}');
print(''); print('');
@ -203,20 +188,11 @@ def resort_by_value_per_weight(
n = len(weights); n = len(weights);
indexes = list(range(n)); indexes = list(range(n));
order = sorted(indexes, key=lambda i: -values[i]/weights[i]); order = sorted(indexes, key=lambda i: -values[i]/weights[i]);
permute_data(weights=weights, values=values, items=items, perm=order); weights[:] = weights[order];
values[:] = values[order];
items[:] = items[order];
return order; return order;
def permute_data(
weights: np.ndarray,
values: np.ndarray,
items: np.ndarray,
perm: List[int],
):
weights[:] = weights[perm];
values[:] = values[perm];
items[:] = items[perm];
return;
def estimate_lower_bound( def estimate_lower_bound(
mask: Mask, mask: Mask,
capacity: float, capacity: float,

View File

@ -9,6 +9,7 @@ from src.thirdparty.code import *;
from src.thirdparty.maths import *; from src.thirdparty.maths import *;
from src.thirdparty.types import *; from src.thirdparty.types import *;
from src.core.utils import *;
from src.models.stacks import *; from src.models.stacks import *;
# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ # ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
@ -32,16 +33,18 @@ def display_order(
items: np.ndarray, items: np.ndarray,
one_based: bool = False, one_based: bool = False,
) -> str: ) -> str:
index = range(len(order));
uorder = iperm(order);
table = pd.DataFrame({ table = pd.DataFrame({
'items': items, 'items': items,
'order': order, 'index': index,
'values': values, 'values': values,
'weights': weights, 'weights': weights,
'u': (values/weights), 'u': (values/weights),
}) \ }, index=index) \
.reset_index(drop=True); .reindex(uorder);
if one_based: if one_based:
table['order'] += 1; table['index'] += 1;
# benutze pandas-Dataframe + tabulate, um schöner darzustellen: # benutze pandas-Dataframe + tabulate, um schöner darzustellen:
repr = tabulate( repr = tabulate(
pd.DataFrame(table), pd.DataFrame(table),
@ -59,17 +62,13 @@ def display_order(
def display_sum( def display_sum(
vector: Union[List[int], List[float]], vector: Union[List[int], List[float]],
values: np.ndarray, values: np.ndarray,
as_maximum: bool = True,
) -> str: ) -> str:
value = sum([ u*x for u, x in zip(vector,values)]); value = sum([ u*x for u, x in zip(vector,values)]);
expr = '+'.join([ expr = '+'.join([
f'{x:g}' if u == 1 else f'{Fraction(str(u))}·{x:g}' f'{x:g}' if u == 1 else f'{Fraction(str(u))}·{x:g}'
for u, x in zip(vector,values) if u > 0 for u, x in zip(vector,values) if u > 0
]); ]);
if as_maximum: return f'{value:g} (={expr})';
return f'{value:g} = {expr}';
else:
return f'-{value:g} = -({expr})';
# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ # ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
# METHOD display result of branch and bound # METHOD display result of branch and bound
@ -87,7 +86,7 @@ def display_branch_and_bound(
rows.append((f'{lb_estimate:g}', f'{lb:g}', S)); rows.append((f'{lb_estimate:g}', f'{lb:g}', S));
else: else:
used_vectors.append(u) used_vectors.append(u)
rows.append((f'{lb_estimate:g}', display_sum(vector=u, values=values, as_maximum=False), S)); rows.append((f'{lb_estimate:g}', display_sum(vector=u, values=values), S));
table = pd.DataFrame(rows) \ table = pd.DataFrame(rows) \
.rename(columns={0: 'b', 1: 'g(TOP(S))', 2: 'S'}) \ .rename(columns={0: 'b', 1: 'g(TOP(S))', 2: 'S'}) \