Vorlesung 08: Ganzzahlige Optimierung
Grundlagen Operations Research
Ganzzahligkeit
Nur ganze Einheiten
Was ist neu?
Für einige oder alle Variablen sind nur ganze Zahlen zulässig:
- Ganzzahlig: und ganzzahlig (Stückzahlen, Fahrzeuge, …).
- Binär: für Ja/Nein-Entscheidungen.
- Gemischt-ganzzahlig: ganzzahlige und kontinuierliche Variablen.
Lässt man die Ganzzahligkeit weg, entsteht die LP-Relaxation, ein gewöhnliches lineares Problem.
Warum schwierig?
- Ganzzahlige Probleme gelten als schwer: kein Algorithmus mit polynomialem Aufwand für die optimale Lösung bekannt.
- Naiv: vollständige Enumeration aller ganzzahligen Möglichkeiten.
- In der Praxis: Meta-Heuristiken (Genetische Algorithmen, Tabu-Suche, …) oder das exakte Branch-&-Bound-Verfahren.
LP-Relaxation grafisch
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.
Branch & Bound
Ausgangsproblem
LP-Relaxation : , , obere Schranke .
Schranken (Bounding)
- Jede LP-Relaxation liefert eine obere Schranke für ihr Teilproblem.
- Jede bekannte ganzzahlige Lösung liefert eine globale untere Schranke .
- Start: ist ganzzahlig zulässig .
- Ist keine zulässige Lösung bekannt, startet man mit .
Ein Teilproblem ist ausgelotet, wenn seine obere Schranke die untere Schranke nicht mehr übertrifft.
Die Auslotungsregeln
Ein Teilproblem wird nicht weiter verzweigt, wenn:
- (3a) : es kann nichts Besseres mehr liefern.
- (3b) die Relaxationslösung ganzzahlig ist und verbessert (): neue beste Lösung.
- (3c) die Relaxation unzulässig ist: dann auch .
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.
Auslotung bei Minimierung
Bei Minimierung tauschen obere und untere Schranke die Rollen:
- Jede bekannte ganzzahlige Lösung liefert eine globale obere Schranke .
- Jede Relaxation liefert eine untere Schranke .
- (3a) : es kann nichts Besseres mehr liefern.
- (3b) die Relaxationslösung ist ganzzahlig und verbessert (): neue beste Lösung.
- (3c) unverändert: Relaxation unzulässig, dann auch .
Relaxationen
Die LP-Relaxation ist nur eine Möglichkeit, Schranken zu gewinnen:
- LP-Relaxation: Ganzzahligkeit weglassen (unser Standard).
- Weglassen von Nebenbedingungen: jedes entspannte Problem schrankt.
- Lagrange-Relaxation: verletzte Restriktionen wandern bestraft in die Zielfunktion.
Verzweigen (Branching)
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 .
Suchstrategien
Frage: Welches offene Teilproblem als Nächstes?
- Reine Tiefensuche: einen Ast bis zum Ende, schnell eine erste Lösung.
- Tiefensuche + MUB: nach vollständiger Verzweigung den Ast mit größter oberer Schranke (Maximum Upper Bound).
- Breitensuche: unter allen offenen Knoten den mit größter Schranke.
Backtracking (beide Tiefensuchen, am Ende eines Astes): zurück zum vorangegangenen Knoten, dessen nächstes Teilproblem betrachten, sofern noch nicht ausgelotet.
Suchstrategien bei Minimierung
Bei Minimierung drehen sich die Suchstrategien mit:
- Tiefensuche + MLB (verzweigte Tiefensuche): nach vollständiger Verzweigung den Ast mit kleinster unterer Schranke (Minimum Lower Bound).
- Breitensuche: unter allen offenen Knoten den mit kleinster unterer Schranke.
- Ohne bekannte Lösung startet .
Teilprobleme und
Weiter mit dem besten Ast
verzweige zuerst (Maximum-Upper-Bound).
In ist nicht ganzzahlig:
Teilprobleme und
wird ausgelotet
und sind ganzzahlig gelöst. Die beste untere Schranke ist jetzt .
kann keine bessere Lösung mehr enthalten. Es muss nicht weiter untersucht werden.
Der Branch-&-Bound-Baum
: 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 .
Optimale Lösung
Alle Teilprobleme sind ausgelotet. Die beste ganzzahlige Lösung ist optimal:
Beachten Sie: das gerundete LP-Optimum ist gar nicht zulässig. Runden führt oft in die Irre.
Kontrolle mit Julia
Ganzzahlig mit JuMP
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
Binäres Beispiel
Auftragsauswahl
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 |
Das Binärmodell
Mit (Auftrag annehmen?):
LP-Relaxation: statt nur .
LP-Relaxation lösen
Die LP-Relaxation ist nicht ganzzahlig:
ist nicht ganzzahlig verzweige nach , und zwar, da binär, in die Äste und .
Reine Tiefensuche
: , 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.
Tiefensuche + MUB
: , 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.
Breitensuche
: , 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.
Optimum
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.
Auf der nächsten Folie führen Sie Branch & Bound selbst aus, mit allen drei Suchstrategien von vorhin.
Sie sind dran
Kontrolle mit Julia
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]
Zusammenfassung
Das Wichtigste auf einen Blick
- Die LP-Relaxation lässt die Ganzzahligkeit weg und liefert eine obere Schranke.
- Branch & Bound verzweigt nach nicht ganzzahligen Variablen und lotet Teilprobleme über Schranken aus.
- Ein Teilproblem ist erledigt, wenn es ganzzahlig ist oder seine obere Schranke die untere Schranke nicht übertrifft.
- Runden der LP-Lösung ist keine verlässliche Methode.