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 nicht mehr übertrifft.
Ein Teilproblem wird nicht weiter verzweigt, wenn:
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 ().
Die optimale ganzzahlige Lösung von steckt in oder .
Frage: Welches offene Teilproblem als Nächstes?
: ,
: ,
verzweige zuerst (Maximum-Upper-Bound).
In ist nicht ganzzahlig:
: , , ganzzahlig
: , , 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 gebrochen, UB (= ) 5,43, verzweigen nach .
verspricht mehr (MUB). wartet.
und sind ganzzahlig (3b); lotet aus (3a).
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 gebrochen verzweige nach , und zwar, da binär, in die Äste und .
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.
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.
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 | Zur Webseite