Grundlagen Operations Research
Für einige oder alle Variablen sind nur ganze Zahlen zulässig:
Lässt man die Ganzzahligkeit weg, entsteht die LP-Relaxation, ein gewöhnliches lineares Problem.
Die schwarzen Punkte sind die ganzzahligen Kandidaten.
Das LP-Optimum ist nicht ganzzahlig.
Frage: Warum nicht einfach runden?
Die Antwort folgt am Ende des Kapitels.
LP-Relaxation : , , obere Schranke .
Ein Teilproblem ist ausgelotet, wenn seine obere Schranke die untere Schranke nicht mehr übertrifft.
Ein Teilproblem wird nicht weiter verzweigt, wenn:
Im Baum stehen ✗ für ausgelotet (3a, 3c), ✓ für eine neue beste Lösung (3b) und ★ für die Lösung, die am Ende optimal ist.
Bei Minimierung tauschen obere und untere Schranke die Rollen:
Die LP-Relaxation ist nur eine Möglichkeit, Schranken zu gewinnen:
Wähle eine nicht ganzzahlige Variable und verzweige, um den nicht ganzzahligen Bereich auszuschließen:
Übliche Regel: die Variable mit dem geringsten Abstand zur nächsten ganzen Zahl, hier (). Einfache Alternative: die nicht ganzzahlige Variable mit dem kleinsten Index.
Die optimale ganzzahlige Lösung von steckt in oder .
Frage: Welches offene Teilproblem als Nächstes?
Backtracking (beide Tiefensuchen, am Ende eines Astes): zurück zum vorangegangenen Knoten, dessen nächstes Teilproblem betrachten, sofern noch nicht ausgelotet.
Bei Minimierung drehen sich die Suchstrategien mit:
verzweige zuerst (Maximum-Upper-Bound).
In ist nicht ganzzahlig:
und sind ganzzahlig gelöst. Die beste untere Schranke ist jetzt .
kann keine bessere Lösung mehr enthalten. Es muss nicht weiter untersucht werden.
: LP-Optimum nicht ganzzahlig, UB (= ) 5,43, verzweigen nach .
mit : , , nicht ganzzahlig: offen.
mit : , : offen. verspricht mehr (MUB), wartet.
mit : ganzzahlig, (3b) .
mit : ganzzahlig, (3b) .
ausgelotet (3a), denn .
Alle Teilprobleme sind ausgelotet. Die beste ganzzahlige Lösung ist optimal:
Optimale Lösung
Beachten Sie: das gerundete LP-Optimum ist gar nicht zulässig. Runden führt oft in die Irre.
Ganzzahligkeit ist in JuMP nur ein Zusatz. HiGHS führt Branch & Bound automatisch aus:
using JuMP, HiGHS
modell = Model(HiGHS.Optimizer); set_silent(modell)
@variable(modell, X1 >= 0, Int) # ganzzahlig
@variable(modell, X2 >= 0, Int)
@objective(modell, Max, X1 + 2X2)
@constraint(modell, X1 + 3X2 <= 7)
@constraint(modell, 3X1 + 2X2 <= 10)
optimize!(modell)
println("F* = ", objective_value(modell),
" mit X1 = ", value(X1), ", X2 = ", value(X2))F* = 5.0 mit X1 = 1.0, X2 = 2.0
Ein Fuhrunternehmer kann vier Aufträge annehmen. Welche maximieren den Erlös? Kapazität: 30 t und 50 Paletten.
| Auftrag | 1 | 2 | 3 | 4 |
|---|---|---|---|---|
| Gewicht [t] | 10 | 15 | 12 | 14 |
| Paletten | 12 | 30 | 16 | 10 |
| Erlös | 200 | 350 | 250 | 180 |
Mit (Auftrag annehmen?):
LP-Relaxation: statt nur .
Die LP-Relaxation ist nicht ganzzahlig:
ist nicht ganzzahlig verzweige nach , und zwar, da binär, in die Äste und .
: , nicht ganzzahlig offen, verzweige nach , immer zuerst.
mit : , nicht ganzzahlig offen, verzweige nach .
mit : ganzzahlig, (3b) .
Backtracking zu , Ast : mit ausgelotet (3a).
Zurück zu , Ast : mit , nicht ganzzahlig offen, verzweige nach .
mit : , nicht ganzzahlig offen, verzweige nach .
mit : ganzzahlig, aber ausgelotet (3a).
Zurück zu , Ast : mit ausgelotet (3a).
Zurück zu , Ast : mit , nicht ganzzahlig offen, verzweige nach .
mit : ausgelotet (3a).
Zurück zu , Ast : unzulässig (3c), Gewicht . bleibt optimal.
: , nicht ganzzahlig offen, verzweige nach und löse beide Äste.
mit : , nicht ganzzahlig offen.
mit : , nicht ganzzahlig offen. MUB: , weiter mit .
mit : , nicht ganzzahlig offen.
mit : , nicht ganzzahlig offen. MUB: , weiter mit .
mit : , nicht ganzzahlig offen.
mit : unzulässig (3c), Gewicht . Weiter mit , verzweige nach .
mit : ganzzahlig, (3b) . , bleiben offen.
mit : unzulässig (3c), Gewicht . Backtracking zum tiefsten offenen Knoten, .
, Ast : mit ganzzahlig, (3b) .
mit : ausgelotet (3a). Backtracking zu : , offen.
, Ast : mit ganzzahlig, (3b) .
mit : ausgelotet (3a). Nichts mehr offen, ist optimal.
: , nicht ganzzahlig offen, verzweige nach und löse beide Äste.
mit : , nicht ganzzahlig offen.
mit : , nicht ganzzahlig offen. Größte Schranke aller offenen: .
mit : , nicht ganzzahlig offen.
mit : , nicht ganzzahlig offen. Größte Schranke aller offenen hat .
mit : ganzzahlig, (3b) .
mit : ausgelotet (3a). , bleiben offen, weiter mit .
mit : ausgelotet (3a).
mit : unzulässig (3c), Gewicht . Offen bleibt nur , verzweige nach .
mit : ganzzahlig, aber ausgelotet (3a).
mit : ausgelotet (3a). Nichts mehr offen, ist optimal.
Beste Auftragsauswahl
Aufträge 2 und 3: , .
Von möglichen Auftragskombinationen hat Branch & Bound nur einen Teil explizit geprüft. Der Rest war implizit ausgelotet: implizite vollständige Enumeration.
Gleich ausprobieren
Auf der nächsten Folie führen Sie Branch & Bound selbst aus, mit allen drei Suchstrategien von vorhin.
HiGHS geht genauso vor, nur mit geschickteren Regeln für Variable und Reihenfolge:
using JuMP, HiGHS
e = [200,350,250,180]; g = [10,15,12,14]; p = [12,30,16,10]
G, P, J = 30, 50, 1:4
modell = Model(HiGHS.Optimizer); set_silent(modell)
@variable(modell, X[J], Bin)
@objective(modell, Max, sum(e[j]*X[j] for j in J))
@constraint(modell, sum(g[j]*X[j] for j in J) <= G)
@constraint(modell, sum(p[j]*X[j] for j in J) <= P)
optimize!(modell)
println("F* = ", round(Int, objective_value(modell)),
", angenommen: ", [j for j in J if value(X[j]) > 0.5])F* = 600, angenommen: [2, 3]
Vorlesung 08: Ganzzahlige Optimierung | Prof. Dr. Knut Haase | Zur Webseite