Grundlagen Operations Research
Vlćek u. a. (2023)
Bisher lieferte stets eine zulässige Startlösung. Bei -Restriktionen gilt das nicht mehr:
Mit Schlupfvariablen:
Für folgt , : unzulässig.
Der Ursprung (×) liegt außerhalb des zulässigen Bereichs.
Frage: Wo darf der Simplex dann starten?
Er braucht erst eine zulässige Basislösung. Genau die liefert Phase 1.
Wir fügen in die -Zeilen künstliche Variablen ein:
Jetzt ist , , eine formal zulässige Startlösung.
Inhaltlich zulässig erst, wenn : die künstlichen Variablen müssen wieder aus der Basis.
Idee der Zweiphasenmethode
In Phase 1 minimieren wir die Summe der künstlichen Variablen:
Wir drücken durch die Nichtbasisvariablen aus:
Diese Hilfszielfunktion steuert Phase 1, bis erreicht ist.
M-Methode
Statt einer eigenen Phase 1 bestraft die M-Methode die künstlichen Variablen direkt in der Originalzielfunktion: mit sehr großem .
Eine Phase statt zwei, aber numerisch heikler. Wir rechnen mit der Zweiphasenmethode.
Phase 1 startet mit in der Basis; die -Zeile wird nur mitgeführt, die Pivotwahl trifft die -Zeile:
| BV | ||||||||
|---|---|---|---|---|---|---|---|---|
| 1 | 1 | −1 | 0 | 0 | 1 | 0 | 8 | |
| 2 | 1 | 0 | −1 | 0 | 0 | 1 | 10 | |
| 1 | 1 | 0 | 0 | 1 | 0 | 0 | 10 | |
| −2 | −1 | 0 | 0 | 0 | 0 | 0 | 0 | |
| −3 | −2 | 1 | 1 | 0 | 0 | 0 | −18 |
-Zeile: unter aufnehmen; minimaler Quotient verlässt die Basis.
Eine künstliche Variable, die die Basis verlässt, wird gesperrt und im Tableau mit einem Strich markiert:
| BV | ||||||||
|---|---|---|---|---|---|---|---|---|
| 1 | 1 | −1 | 0 | 0 | 1 | 0 | 8 | |
| 2 | 1 | 0 | −1 | 0 | 0 | 1 | 10 | |
| 1 | 1 | 0 | 0 | 1 | 0 | 0 | 10 | |
| −2 | −1 | 0 | 0 | 0 | 0 | 0 | 0 | |
| −3 | −2 | 1 | 1 | 0 | 0 | 0 | −18 |
| BV | ||||||||
|---|---|---|---|---|---|---|---|---|
| 0 | 1/2 | −1 | 1/2 | 0 | 1 | – | 3 | |
| 1 | 1/2 | 0 | −1/2 | 0 | 0 | – | 5 | |
| 0 | 1/2 | 0 | 1/2 | 1 | 0 | – | 5 | |
| 0 | 0 | 0 | −1 | 0 | 0 | – | 10 | |
| 0 | −1/2 | 1 | −1/2 | 0 | 0 | – | −3 |
| BV | ||||||||
|---|---|---|---|---|---|---|---|---|
| 0 | 1 | −2 | 1 | 0 | – | – | 6 | |
| 1 | 1 | −1 | 0 | 0 | – | – | 8 | |
| 0 | 0 | 1 | 0 | 1 | – | – | 2 | |
| 0 | 1 | −2 | 0 | 0 | – | – | 16 | |
| 0 | 0 | 0 | 0 | 0 | – | – | 0 |
| BV | ||||||||
|---|---|---|---|---|---|---|---|---|
| 0 | 1 | 0 | 1 | 2 | – | – | 10 | |
| 1 | 1 | 0 | 0 | 1 | – | – | 10 | |
| 0 | 0 | 1 | 0 | 1 | – | – | 2 | |
| 0 | 1 | 0 | 0 | 2 | – | – | 20 |
Start mit Pivot [2]: hinein, hinaus.
-Zeile: unter und ; Quotienten für : Pivot [1/2], hinaus.
: Phase 1 beendet! Jetzt wählt die -Zeile: unter , einziger positiver Quotient Pivot [1], hinaus.
Alle -Zeilen-Einträge sind , also optimal: , , .
Das Optimum liegt im Eckpunkt , auf der Restriktion .
Optimale Lösung
Zu jedem primalen Problem gehört ein duales Problem.
Grundregel
Ein primales Minimierungsproblem mit ausschließlich -Relationen wird zu einem dualen Maximierungsproblem mit ausschließlich -Relationen.
Herleitung über die beste untere Schranke für den optimalen Zielwert des Minimierungsproblems.
Primales Problem
Aus der zweiten Restriktion ():
Da :
Frage: Geht es noch besser als 90?
Primales Problem
Erste Restriktion :
erste zweite Restriktion:
Frage: Welche Linearkombination liefert die schärfste Schranke?
Faktoren für die beiden Restriktionen:
Primal
Dual
Frage: Kommt Ihnen das duale Problem bekannt vor?
Das duale Problem ist (bis auf die Variablennamen) genau das Frachtführer-Problem aus Vorlesung 1:
Dessen Optimum kennen Sie bereits aus Vorlesung 2: bei .
Starke Dualität
Die sind die Schattenpreise der primalen Restriktionen. Beide Sichten treffen sich im selben Optimum.
Restriktionen unterschiedlichen Typs werden zunächst auf gebracht:
So lässt sich jedes LOP dualisieren.
Ein Beispiel mit allen drei Relationstypen:
Frage: Wie bringen wir alles auf ?
Die Regeln von eben, angewandt:
| Restriktion | wird zu | Dualvariable |
|---|---|---|
| (bleibt) | ||
Die -Restriktion liefert zwei Dualvariablen, zusammengefasst , im Vorzeichen unbeschränkt.
Primal
Dual
; unbeschränkt. Für die Rechnung nutzen wir mit .
Mit Schlupfvariablen wird die dritte Zeile zu .
Die Startlösung ist unzulässig.
Frage: Welches Verfahren kennt genau diese Situation?
Der duale Simplex aus Vorlesung 3: Pivotzeile ist die unzulässige Zeile .
| BV | ||||||||
|---|---|---|---|---|---|---|---|---|
| 2 | −2 | 1 | −1 | 1 | 0 | 0 | 5 | |
| 3 | −3 | 5 | −5 | 0 | 1 | 0 | 2 | |
| 1 | 1 | 2 | −2 | 0 | 0 | 1 | −1 | |
| −20 | 30 | −40 | 40 | 0 | 0 | 0 | 0 |
| BV | ||||||||
|---|---|---|---|---|---|---|---|---|
| 3/2 | −5/2 | 0 | 0 | 1 | 0 | −1/2 | 11/2 | |
| 1/2 | −11/2 | 0 | 0 | 0 | 1 | −5/2 | 9/2 | |
| −1/2 | −1/2 | −1 | 1 | 0 | 0 | −1/2 | 1/2 | |
| 0 | 50 | 0 | 0 | 0 | 0 | 20 | −20 |
Einziger negativer Koeffizient der Zeile : unter Pivot [−2].
Alle und alle -Zeilen-Einträge , also ist das Tableau bereits optimal: .
Die -Zeile unter den Schlupfvariablen liefert die primale Lösung:
Kontrolle im primalen Problem: ✓ und ✓.
Zwei Probleme, eine Rechnung
Das duale Optimaltableau enthält die primale Lösung gleich mit. Sie lösen immer beide Probleme auf einmal.
HiGHS findet selbst eine zulässige Startlösung:
using JuMP, HiGHS
modell = Model(HiGHS.Optimizer)
set_silent(modell)
@variable(modell, X1 >= 0)
@variable(modell, X2 >= 0)
@objective(modell, Max, 2X1 + X2)
@constraint(modell, X1 + X2 >= 8)
@constraint(modell, 2X1 + X2 >= 10)
@constraint(modell, X1 + X2 <= 10)
optimize!(modell)
println("F* = ", objective_value(modell),
" mit X1 = ", value(X1), ", X2 = ", value(X2))F* = 20.0 mit X1 = 10.0, X2 = 0.0
Für das primale Minimierungsproblem liefert JuMP die Dualwerte der Restriktionen, genau die :
modell = Model(HiGHS.Optimizer)
set_silent(modell)
@variable(modell, X1 >= 0)
@variable(modell, X2 >= 0)
@objective(modell, Min, 5X1 + 9X2)
@constraint(modell, r1, X1 + X2 >= 20)
@constraint(modell, r2, X1 + 3X2 >= 30)
optimize!(modell)
println("F* = ", objective_value(modell))
println("W1 = ", round(dual(r1), digits = 2),
", W2 = ", round(dual(r2), digits = 2))F* = 120.0
W1 = 3.0, W2 = 2.0
Auch das Beispiel mit gemischten Relationen bestätigt HiGHS:
modell = Model(HiGHS.Optimizer)
set_silent(modell)
@variable(modell, X[1:3] >= 0)
@objective(modell, Min, 5X[1] + 2X[2] - X[3])
@constraint(modell, 2X[1] + 3X[2] + X[3] >= 20)
@constraint(modell, 2X[1] + 3X[2] - X[3] <= 30)
@constraint(modell, X[1] + 5X[2] + 2X[3] == 40)
optimize!(modell)
println("F* = ", objective_value(modell),
" mit X = ", round.(value.(X), digits = 2))F* = -20.0 mit X = [0.0, 0.0, 20.0]
Vorlesung 04: Dualität & Zweiphasen | Zur Webseite