master > master: code py - pad ones/zeros für einelementige Fälle
This commit is contained in:
parent
56a93bbac9
commit
f45781be71
@ -83,7 +83,7 @@ def rucksack_greedy_algorithm(
|
|||||||
if verbose:
|
if verbose:
|
||||||
# Umsortierung rückgängig machen:
|
# Umsortierung rückgängig machen:
|
||||||
vector = [ soln.vector[i] for i in order ];
|
vector = [ soln.vector[i] for i in order ];
|
||||||
rucksack = [ uorder[r] for r in rucksack ];
|
rucksack = sorted([ uorder[r] for r in rucksack ]);
|
||||||
permute_data(weights=weights, values=values, items=items, perm=uorder);
|
permute_data(weights=weights, values=values, items=items, perm=uorder);
|
||||||
# Ausdrücke bestimmen:
|
# Ausdrücke bestimmen:
|
||||||
expr_value = display_sum(vector=vector, values=values);
|
expr_value = display_sum(vector=vector, values=values);
|
||||||
@ -135,24 +135,29 @@ def rucksack_branch_and_bound_algorithm(
|
|||||||
S = Stack();
|
S = Stack();
|
||||||
S.push(vector);
|
S.push(vector);
|
||||||
while not S.empty():
|
while not S.empty():
|
||||||
lb, u = estimate_lower_bound(mask=S.top(), capacity=capacity, weights=weights, values=values, items=items);
|
lb, u, can_add_all, can_add_none = estimate_lower_bound(mask=S.top(), capacity=capacity, weights=weights, values=values, items=items);
|
||||||
if verbose:
|
if verbose:
|
||||||
logged_steps.append((lb_estimate, lb, u, str(S)));
|
logged_steps.append((lb_estimate, lb, u, str(S)));
|
||||||
# Update nur nötig, wenn die (eingeschätzte) untere Schranke von A das bisherige Minimum verbessert:
|
# Update nur nötig, wenn die (eingeschätzte) untere Schranke von A das bisherige Minimum verbessert:
|
||||||
A: Mask = S.pop();
|
A: Mask = S.pop();
|
||||||
if lb < lb_estimate:
|
if lb < lb_estimate:
|
||||||
# Branch:
|
# Bound, wenn sich A nicht weiter aufteilen lässt od. man A wie eine einelementige Option behandeln kann:
|
||||||
if A.splittable():
|
# Branch sonst
|
||||||
|
if not A.splittable() or can_add_all or can_add_none:
|
||||||
|
lb_estimate = lb;
|
||||||
|
if can_add_all:
|
||||||
|
vector = A.pad_ones();
|
||||||
|
elif can_add_none:
|
||||||
|
vector = A.pad_zeros();
|
||||||
|
else:
|
||||||
|
vector = A;
|
||||||
|
else:
|
||||||
B, C = A.split();
|
B, C = A.split();
|
||||||
# NOTE: per Wahl erfüllt mind. eine Möglichkeit in B die Kapazitätsschranke.
|
# NOTE: per Wahl erfüllt mind. eine Möglichkeit in B die Kapazitätsschranke.
|
||||||
S.push(B);
|
S.push(B);
|
||||||
# Nur dann C auf Stack legen, wenn mind. eine Möglichkeit in C die Kapazitätsschranke erfüllt:
|
# Nur dann C auf Stack legen, wenn mind. eine Möglichkeit in C die Kapazitätsschranke erfüllt:
|
||||||
if sum(weights[C.indexes_one]) <= capacity:
|
if sum(weights[C.indexes_one]) <= capacity:
|
||||||
S.push(C);
|
S.push(C);
|
||||||
# Bound, wenn die Maske den Rucksack komplett bestimmt:
|
|
||||||
else:
|
|
||||||
lb_estimate = lb;
|
|
||||||
vector = A;
|
|
||||||
|
|
||||||
# Aspekte der Lösung speichern
|
# Aspekte der Lösung speichern
|
||||||
rucksack = vector.indexes_one; # Indexes von Items im Rucksack
|
rucksack = vector.indexes_one; # Indexes von Items im Rucksack
|
||||||
@ -169,7 +174,7 @@ def rucksack_branch_and_bound_algorithm(
|
|||||||
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:
|
# Umsortierung rückgängig machen:
|
||||||
vector = [ soln.vector[i] for i in order ];
|
vector = [ soln.vector[i] for i in order ];
|
||||||
rucksack = [ uorder[r] for r in rucksack ];
|
rucksack = sorted([ uorder[r] for r in rucksack ]);
|
||||||
permute_data(weights=weights, values=values, items=items, perm=uorder);
|
permute_data(weights=weights, values=values, items=items, perm=uorder);
|
||||||
# Ausdrücke bestimmen:
|
# Ausdrücke bestimmen:
|
||||||
expr_value = display_sum(vector=vector, values=values);
|
expr_value = display_sum(vector=vector, values=values);
|
||||||
@ -223,7 +228,7 @@ def estimate_lower_bound(
|
|||||||
weights: np.ndarray,
|
weights: np.ndarray,
|
||||||
values: np.ndarray,
|
values: np.ndarray,
|
||||||
items: np.ndarray,
|
items: np.ndarray,
|
||||||
) -> Tuple[float, List[float]]:
|
) -> Tuple[float, List[float], bool]:
|
||||||
'''
|
'''
|
||||||
Wenn partielle Information über den Rucksack festgelegt ist,
|
Wenn partielle Information über den Rucksack festgelegt ist,
|
||||||
kann man bei dem unbekannten Teil das Rucksack-Problem
|
kann man bei dem unbekannten Teil das Rucksack-Problem
|
||||||
@ -257,6 +262,10 @@ def estimate_lower_bound(
|
|||||||
vector[indexes_one] = 1;
|
vector[indexes_one] = 1;
|
||||||
vector[indexes_unset] = soln_rest.vector;
|
vector[indexes_unset] = soln_rest.vector;
|
||||||
|
|
||||||
|
# Prüfe, ob man als Lösung alles hinzufügen kann:
|
||||||
|
can_add_all = all([m == 1 for m in soln_rest.vector]);
|
||||||
|
can_add_none = all([m == 0 for m in soln_rest.vector]);
|
||||||
|
|
||||||
# Einschätzung des max-Wertes (Ausgabe mit -1 multiplizieren):
|
# Einschätzung des max-Wertes (Ausgabe mit -1 multiplizieren):
|
||||||
value_max_est = value_rucksack + value_rest;
|
value_max_est = value_rucksack + value_rest;
|
||||||
return -value_max_est, vector.tolist();
|
return -value_max_est, vector.tolist(), can_add_all, can_add_none;
|
||||||
|
@ -76,5 +76,17 @@ class Mask():
|
|||||||
vector2[self.index] = MaskValue.ONE;
|
vector2[self.index] = MaskValue.ONE;
|
||||||
return Mask(vector1), Mask(vector2);
|
return Mask(vector1), Mask(vector2);
|
||||||
|
|
||||||
|
def pad_zeros(self) -> Mask:
|
||||||
|
'''
|
||||||
|
Completes mask by filling in unset values with zeros
|
||||||
|
'''
|
||||||
|
return Mask([ MaskValue.ZERO if u == MaskValue.UNSET else u for u in self.values ]);
|
||||||
|
|
||||||
|
def pad_ones(self) -> Mask:
|
||||||
|
'''
|
||||||
|
Completes mask by filling in unset values with zeros
|
||||||
|
'''
|
||||||
|
return Mask([ MaskValue.ONE if u == MaskValue.UNSET else u for u in self.values ]);
|
||||||
|
|
||||||
def empty_mask(n: int):
|
def empty_mask(n: int):
|
||||||
return Mask([MaskValue.UNSET for _ in range(n)]);
|
return Mask([MaskValue.UNSET for _ in range(n)]);
|
||||||
|
Loading…
x
Reference in New Issue
Block a user