Vorlesung 08: Ganzzahlige Optimierung
Grundlagen Operations Research
Ganzzahlige Optimierung
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 .
Ein Teilproblem ist ausgelotet, wenn seine obere 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 .
Bei Minimierung tauschen obere und untere Schranke die Rollen.
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 ().
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.
Teilprobleme und
: ,
: ,
Weiter mit dem besten Ast
verzweige zuerst (Maximum-Upper-Bound).
In ist nicht ganzzahlig:
Teilprobleme und
: , , ganzzahlig
: , , ganzzahlig
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 gebrochen, UB (= ) 5,43, verzweigen nach .
verspricht mehr (MUB). wartet.
und sind ganzzahlig (3b); lotet aus (3a).
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 gebrochen verzweige nach , und zwar, da binär, in die Äste und .
Reine Tiefensuche
Immer zuerst, tief hinab: ist ganzzahlig (3b) .
Zurück und rechts: mit , ausgelotet (3a).
Rechter Ast: verspricht , aber und (beide 3a) bringen nichts Besseres.
(3a) und (unzulässig, 3c) beenden die Suche. bleibt 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.
Kontrolle mit Julia
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 nicht übertrifft.
- Runden der LP-Lösung ist keine verlässliche Methode.