Grundlagen Operations Research
Ein zeitlich, räumlich und sachlich begrenztes komplexes Arbeitsvorhaben mit einer bestimmten Zielsetzung.
Netzplantechnik
Zeitliche Planung der Vorgänge eines Projekts: Bestimmung der frühesten und spätesten Anfangs- und Endzeitpunkte.
Wir betrachten den MPM-Netzplan: Vorgänge sind Knoten, Pfeile tragen Mindestabstände.
Zwei Phasen der Netzplantechnik:
Mit einem künstlichen Startvorgang und Endvorgang hat jedes Projekt eine eindeutige Quelle und Senke.
| Vorgang | Vorgänger | ||
|---|---|---|---|
| 1 | Fundamente | 3 | – |
| 2 | Erdleitung | 2 | 1 (−1) |
| 3 | Mauern | 3 | 1 (1) |
| 4 | Dach | 2 | 3 (0) |
| 5 | Boden | 3 | 2 (0), 3 (1) |
| 6 | Tore einsetzen | 1 | 4 (0) |
| 7 | Innen verputzen | 2 | 5 (1), 6 (0) |
| 8 | Außen verputzen | 2 | 6 (0) |
| 9 | Tor streichen | 1 | 7 (0), 8 (0) |
Knoten = Vorgänge (oben und , die leeren Felder füllt gleich die Zeitplanung), Pfeile = Mindestabstände .
Zwischen zwei Vorgängen und sind verschiedene Abstände möglich:
Jeder Abstand existiert auch als Maximalabstand : „höchstens so lange“.
Alles wird in Normalfolgen umgerechnet; Maximalabstände werden zu negativen Mindestabständen in Gegenrichtung:
| gegeben | Umrechnung | gegeben | Umrechnung |
|---|---|---|---|
So entstehen Rückwärtspfeile und damit Zyklen im Netzplan.
Zwischen () und () gilt der maximale Normalabstand .
Frage: Welcher Pfeil entsteht daraus im Netzplan?
Ein Rückwärtspfeil von nach mit Bewertung .
Gleich ausprobieren
Zurück zur Lagerhalle. Auf der nächsten Folie gehen Sie selbst Wege durch ihren Netzplan. Welcher Weg dauert am längsten?
Im Spiel haben Sie Wege einzeln durchgerechnet. Die Vorwärtsrechnung findet für jeden Vorgang den längsten Weg auf einmal, topologisch von bis :
/ : frühester Anfangs- / Endzeitpunkt von Vorgang .
Vorgang hat drei Vorgänger:
| Vorgänger | ||
|---|---|---|
| 6 | 3 | |
| 5 | 6 | |
| 12 | −4 |
Frage: Wie groß ist ?
(Projektstart), .
, .
, .
, .
, .
, .
, .
, .
, : Projektdauer 15.
Späteste Zeitpunkte, von zurück bis :
/ : spätester Anfangs- / Endzeitpunkt von Vorgang .
Vorgang hat zwei Nachfolger:
| Nachfolger | ||
|---|---|---|
| 14 | 2 | |
| 12 | −2 |
Frage: Wie groß ist ?
(Projektende), .
, .
, .
, .
, .
, .
, .
, .
, .
Alle Werte als Tabelle:
| 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | |
|---|---|---|---|---|---|---|---|---|---|
| 0 | 2 | 4 | 7 | 8 | 9 | 12 | 10 | 14 | |
| 3 | 4 | 7 | 9 | 11 | 10 | 14 | 12 | 15 | |
| 0 | 6 | 4 | 9 | 8 | 11 | 12 | 12 | 14 | |
| 3 | 8 | 7 | 11 | 11 | 12 | 14 | 14 | 15 |
Projektdauer ; bei gilt , dazu gleich mehr.
Gleich ausprobieren
Auf der nächsten Folie rechnen Sie selbst, Vorgang für Vorgang, erst vorwärts, dann rückwärts. Unter „Neu“ kommen weitere Netzpläne: Welche Vorgänge sind dort kritisch?
Kritischer Weg
Der längste Weg im Netzplan. Für jeden kritischen Vorgang gilt (kein Spielraum).
Der kritische Weg ist .
Konsequenz
Verzögert sich ein kritischer Vorgang, verzögert sich das gesamte Projekt.
Zeitspannen, um die ein Vorgang verschoben werden kann, ohne die Projektdauer zu erhöhen:
Es gilt stets .
| 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | |
|---|---|---|---|---|---|---|---|---|---|
| 0 | 4 | 0 | 2 | 0 | 2 | 0 | 2 | 0 | |
| 0 | 4 | 0 | 0 | 0 | 0 | 0 | 2 | 0 | |
| 0 | 4 | 0 | 2 | 0 | 0 | 0 | 0 | 0 | |
| 0 | 4 | 0 | 0 | 0 | 0 | 0 | 0 | 0 |
Genau die Vorgänge mit sind kritisch: .
Nur Vorgang 2 (Erdleitung) ist völlig frei verschiebbar ().
Enthält der Netzplan Zyklen (z. B. durch Maximalabstände), versagt die topologische Reihenfolge. Dann rechnet ein FIFO-Verfahren wie bei den kürzesten Wegen (Vorlesung 6):
Voraussetzung: alle Zyklen haben nichtpositive Länge. Ein Zyklus positiver Länge macht den Plan unzulässig.
Neue Vorgabe für die Lagerhalle: Vom Ende des Mauerns (3) bis zur Fertigstellung des Außenputzes (8) dürfen höchstens 6 ZE vergehen: .
Frage: Welcher Pfeil entsteht daraus?
Transformationsregel :
Der Zyklus hat die Länge : der Plan bleibt zulässig.
Liste mit Kopf und Ende . Start: , , alle anderen ; .
| 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | |
|---|---|---|---|---|---|---|---|---|---|
| 0 | −∞ | −∞ | −∞ | −∞ | −∞ | −∞ | −∞ | −∞ | |
| 3 | – | – | – | – | – | – | – | – |
L = (1)
Start: , , alle anderen ; .
| 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | |
|---|---|---|---|---|---|---|---|---|---|
| 0 | 2 | 4 | −∞ | −∞ | −∞ | −∞ | −∞ | −∞ | |
| 3 | – | – | – | – | – | – | – | – |
L = (1, 2, 3)
: , 2 stellt sich an; , 3 stellt sich an.
| 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | |
|---|---|---|---|---|---|---|---|---|---|
| 0 | 2 | 4 | −∞ | 4 | −∞ | −∞ | −∞ | −∞ | |
| 3 | 4 | – | – | – | – | – | – | – |
L = (1, 2, 3, 5)
: ; , 5 stellt sich an.
| 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | |
|---|---|---|---|---|---|---|---|---|---|
| 0 | 2 | 4 | 7 | 8 | −∞ | −∞ | −∞ | −∞ | |
| 3 | 4 | 7 | – | – | – | – | – | – |
L = (1, 2, 3, 5, 4)
: ; , 4 stellt sich an; statt 4: korrigiert, 5 wartet schon.
| 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | |
|---|---|---|---|---|---|---|---|---|---|
| 0 | 2 | 4 | 7 | 8 | −∞ | 12 | −∞ | −∞ | |
| 3 | 4 | 7 | – | 11 | – | – | – | – |
L = (1, 2, 3, 5, 4, 7)
: ; , 7 stellt sich an.
| 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | |
|---|---|---|---|---|---|---|---|---|---|
| 0 | 2 | 4 | 7 | 8 | 9 | 12 | −∞ | −∞ | |
| 3 | 4 | 7 | 9 | 11 | – | – | – | – |
L = (1, 2, 3, 5, 4, 7, 6)
: ; , 6 stellt sich an.
| 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | |
|---|---|---|---|---|---|---|---|---|---|
| 0 | 2 | 4 | 7 | 8 | 9 | 12 | −∞ | 14 | |
| 3 | 4 | 7 | 9 | 11 | – | 14 | – | – |
L = (1, 2, 3, 5, 4, 7, 6, 9)
: ; , 9 stellt sich an.
| 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | |
|---|---|---|---|---|---|---|---|---|---|
| 0 | 2 | 4 | 7 | 8 | 9 | 12 | 10 | 14 | |
| 3 | 4 | 7 | 9 | 11 | 10 | 14 | – | – |
L = (1, 2, 3, 5, 4, 7, 6, 9, 8)
: ; für 7: , keine Änderung; , 8 stellt sich an.
| 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | |
|---|---|---|---|---|---|---|---|---|---|
| 0 | 2 | 4 | 7 | 8 | 9 | 12 | 10 | 14 | |
| 3 | 4 | 7 | 9 | 11 | 10 | 14 | – | 15 |
L = (1, 2, 3, 5, 4, 7, 6, 9, 8)
: ; 9 hat keine Nachfolger.
| 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | |
|---|---|---|---|---|---|---|---|---|---|
| 0 | 2 | 4 | 7 | 8 | 9 | 12 | 10 | 14 | |
| 3 | 4 | 7 | 9 | 11 | 10 | 14 | 12 | 15 |
L = (1, 2, 3, 5, 4, 7, 6, 9, 8)
: ; für 9: , keine Änderung; für 3: , keine Änderung. Liste leer: Abbruch.
Der Rückwärtspfeil hat vorwärts nichts geändert (): Die frühesten Zeitpunkte sind dieselben wie ohne Zyklus.
Start: , , alle anderen ; .
Jetzt greift der Zyklus: Zu den Vorgängern von 3 gehört auch 8.
| 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | |
|---|---|---|---|---|---|---|---|---|---|
| ∞ | ∞ | ∞ | ∞ | ∞ | ∞ | ∞ | ∞ | 15 | |
| – | – | – | – | – | – | – | – | 14 |
L = (9)
Start: , , alle anderen ; .
| 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | |
|---|---|---|---|---|---|---|---|---|---|
| ∞ | ∞ | ∞ | ∞ | ∞ | ∞ | 14 | 14 | 15 | |
| – | – | – | – | – | – | – | – | 14 |
L = (9, 7, 8)
: , 7 stellt sich an; , 8 stellt sich an.
| 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | |
|---|---|---|---|---|---|---|---|---|---|
| ∞ | ∞ | ∞ | ∞ | 11 | 12 | 14 | 14 | 15 | |
| – | – | – | – | – | – | 12 | – | 14 |
L = (9, 7, 8, 5, 6)
: ; , 5 stellt sich an; , 6 stellt sich an.
| 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | |
|---|---|---|---|---|---|---|---|---|---|
| ∞ | ∞ | ∞ | ∞ | 11 | 12 | 14 | 14 | 15 | |
| – | – | – | – | – | – | 12 | 12 | 14 |
L = (9, 7, 8, 5, 6)
: ; für 6: , keine Änderung.
| 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | |
|---|---|---|---|---|---|---|---|---|---|
| ∞ | 8 | 7 | ∞ | 11 | 12 | 14 | 14 | 15 | |
| – | – | – | – | 8 | – | 12 | 12 | 14 |
L = (9, 7, 8, 5, 6, 2, 3)
: ; , 2 stellt sich an; , 3 stellt sich an.
| 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | |
|---|---|---|---|---|---|---|---|---|---|
| ∞ | 8 | 7 | 11 | 11 | 12 | 14 | 14 | 15 | |
| – | – | – | – | 8 | 11 | 12 | 12 | 14 |
L = (9, 7, 8, 5, 6, 2, 3, 4)
: ; , 4 stellt sich an.
| 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | |
|---|---|---|---|---|---|---|---|---|---|
| 7 | 8 | 7 | 11 | 11 | 12 | 14 | 14 | 15 | |
| – | 6 | – | – | 8 | 11 | 12 | 12 | 14 |
L = (9, 7, 8, 5, 6, 2, 3, 4, 1)
: ; , 1 stellt sich an.
| 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | |
|---|---|---|---|---|---|---|---|---|---|
| 3 | 8 | 7 | 11 | 11 | 12 | 14 | 13 | 15 | |
| – | 6 | 4 | – | 8 | 11 | 12 | 12 | 14 |
L = (9, 7, 8, 5, 6, 2, 3, 4, 1, 8)
: ; statt 7: korrigiert, 1 wartet schon; statt 14, 8 stellt sich erneut an.
| 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | |
|---|---|---|---|---|---|---|---|---|---|
| 3 | 8 | 7 | 11 | 11 | 12 | 14 | 13 | 15 | |
| – | 6 | 4 | 9 | 8 | 11 | 12 | 12 | 14 |
L = (9, 7, 8, 5, 6, 2, 3, 4, 1, 8)
: ; für 3: , keine Änderung.
| 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | |
|---|---|---|---|---|---|---|---|---|---|
| 3 | 8 | 7 | 11 | 11 | 12 | 14 | 13 | 15 | |
| 0 | 6 | 4 | 9 | 8 | 11 | 12 | 12 | 14 |
L = (9, 7, 8, 5, 6, 2, 3, 4, 1, 8)
: ; 1 hat keine Vorgänger.
| 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | |
|---|---|---|---|---|---|---|---|---|---|
| 3 | 8 | 7 | 11 | 11 | 11 | 14 | 13 | 15 | |
| 0 | 6 | 4 | 9 | 8 | 11 | 12 | 11 | 14 |
L = (9, 7, 8, 5, 6, 2, 3, 4, 1, 8, 6)
: ; statt 12, 6 stellt sich erneut an.
| 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | |
|---|---|---|---|---|---|---|---|---|---|
| 3 | 8 | 7 | 10 | 11 | 11 | 14 | 13 | 15 | |
| 0 | 6 | 4 | 9 | 8 | 10 | 12 | 11 | 14 |
L = (9, 7, 8, 5, 6, 2, 3, 4, 1, 8, 6, 4)
: ; statt 11, 4 stellt sich erneut an.
| 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | |
|---|---|---|---|---|---|---|---|---|---|
| 3 | 8 | 7 | 10 | 11 | 11 | 14 | 13 | 15 | |
| 0 | 6 | 4 | 8 | 8 | 10 | 12 | 11 | 14 |
L = (9, 7, 8, 5, 6, 2, 3, 4, 1, 8, 6, 4)
: ; für 3: , keine Änderung. Liste leer: Abbruch.
Die Vorwärtsrechnung ändert sich nicht (), aber rückwärts zieht der Pfeil die späten Zeitpunkte zusammen:
| 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | |
|---|---|---|---|---|---|---|---|---|---|
| (ohne) | 0 | 6 | 4 | 9 | 8 | 11 | 12 | 12 | 14 |
| (mit Zyklus) | 0 | 6 | 4 | 8 | 8 | 10 | 12 | 11 | 14 |
: die Puffer von schrumpfen auf .
Die Projektdauer ist der längste Weg, als LP formuliert:
using JuMP, HiGHS
t = Dict(1=>3,2=>2,3=>3,4=>2,5=>3,6=>1,7=>2,8=>2,9=>1)
# (Vorgänger h, Vorgang i, Mindestabstand d_hi)
kanten = [(1,2,-1),(1,3,1),(3,4,0),(2,5,0),(3,5,1),(4,6,0),
(5,7,1),(6,7,0),(6,8,0),(7,9,0),(8,9,0)]
modell = Model(HiGHS.Optimizer); set_silent(modell)
@variable(modell, S[keys(t)] >= 0) # Anfangszeitpunkte (FAZ)
@variable(modell, C >= 0) # Projektdauer
@constraint(modell, [(h,i,d) in kanten], S[i] >= S[h] + t[h] + d)
@constraint(modell, [i in keys(t)], C >= S[i] + t[i])
@objective(modell, Min, C)
optimize!(modell)
println("Projektdauer = ", objective_value(modell))Projektdauer = 15.0
Frühestmögliche Zeitpunkte: minimiere die Summe aller Endzeitpunkte:
tv = [3, 2, 3, 2, 3, 1, 2, 2, 1]
modell = Model(HiGHS.Optimizer); set_silent(modell)
@variable(modell, FAZ[1:9] >= 0)
@constraint(modell, FAZ[1] == 0)
@constraint(modell, [(h,i,d) in kanten], FAZ[i] >= FAZ[h] + tv[h] + d)
@objective(modell, Min, sum(FAZ[i] + tv[i] for i in 1:9)) # min Σ FEZ
optimize!(modell)
println("FAZ = ", round.(Int, value.(FAZ)))FAZ = [0, 2, 4, 7, 8, 9, 12, 10, 14]
Spätestmögliche Zeitpunkte: maximiere, bei fixiertem Projektende:
modell = Model(HiGHS.Optimizer); set_silent(modell)
@variable(modell, SAZ[1:9] >= 0)
@constraint(modell, SAZ[9] + tv[9] == 15) # SEZ_9 = FEZ_9*
@constraint(modell, [(h,i,d) in kanten], SAZ[i] >= SAZ[h] + tv[h] + d)
@objective(modell, Max, sum(SAZ))
optimize!(modell)
println("SAZ = ", round.(Int, value.(SAZ)))SAZ = [0, 6, 4, 9, 8, 11, 12, 12, 14]
Beide Vektoren stimmen mit dem Terminplan von vorhin überein.
Vorlesung 09: Netzplantechnik | Prof. Dr. Knut Haase | Zur Webseite