Vorlesung 09: Netzplantechnik
Grundlagen Operations Research
Netzplantechnik
Ein Projekt planen
Was ist ein Projekt?
Ein zeitlich, räumlich und sachlich begrenztes komplexes Arbeitsvorhaben mit einer bestimmten Zielsetzung.
Zeitliche Planung der Vorgänge eines Projekts: Bestimmung der frühesten und spätesten Anfangs- und Endzeitpunkte.
Methoden im Überblick
- CPM: Critical Path Method (USA, 1956), vorgangspfeilorientiert.
- MPM: Metra Potential Method (Frankreich, 1957), vorgangsknotenorientiert.
- PERT: stochastische Vorgangsdauern (Polaris-Rakete).
- GERT / Simulation: stochastische Netzstrukturen (F&E-Projekte).
Wir betrachten den MPM-Netzplan: Vorgänge sind Knoten, Pfeile tragen Mindestabstände.
Vom Projekt zum Netzplan
Zwei Phasen der Netzplantechnik:
- Strukturplanung: Vorgänge, Dauern und Anordnungsbeziehungen erheben; daraus entsteht der Netzplan.
- Zeitplanung: früheste und späteste Zeitpunkte, Puffer und kritischen Weg berechnen.
Mit einem künstlichen Startvorgang und Endvorgang hat jedes Projekt eine eindeutige Quelle und Senke.
Beispiel: Bau einer Lagerhalle
| 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) |
Der MPM-Netzplan
Knoten = Vorgänge (oben und , die leeren Felder füllt gleich die Zeitplanung), Pfeile = Mindestabstände .
Mindest- und Maximalabstände
Zwischen zwei Vorgängen und sind verschiedene Abstände möglich:
- Anfangsfolge : Anfang bis Anfang .
- Normalfolge : Ende bis Anfang .
- Endfolge : Ende bis Ende .
- Sprungfolge : Anfang bis Ende .
Jeder Abstand existiert auch als Maximalabstand : „höchstens so lange“.
Transformationsregeln
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.
Kurz geübt: Umrechnung
Zwischen () und () gilt der maximale Normalabstand .
Frage: Welcher Pfeil entsteht daraus im Netzplan?
Ein Rückwärtspfeil von nach mit Bewertung .
Zurück zur Lagerhalle. Auf der nächsten Folie gehen Sie selbst Wege durch ihren Netzplan. Welcher Weg dauert am längsten?
Sie sind dran
Zeitplanung
Vorwärtsrechnung
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 .
Kurz geübt: Vorwärts
Vorgang hat drei Vorgänger:
| Vorgänger | ||
|---|---|---|
| 6 | 3 | |
| 5 | 6 | |
| 12 | −4 |
Frage: Wie groß ist ?
Vorwärts im Netzplan
(Projektstart), .
, .
, .
, .
, .
, .
, .
, .
, : Projektdauer 15.
Rückwärtsrechnung
Späteste Zeitpunkte, von zurück bis :
/ : spätester Anfangs- / Endzeitpunkt von Vorgang .
Kurz geübt: Rückwärts
Vorgang hat zwei Nachfolger:
| Nachfolger | ||
|---|---|---|
| 14 | 2 | |
| 12 | −2 |
Frage: Wie groß ist ?
Rückwärts im Netzplan
(Projektende), .
, .
, .
, .
, .
, .
, .
, .
, .
Der Terminplan
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.
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?
Sie sind dran
Kritischer Weg
Der kritische Weg
Der längste Weg im Netzplan. Für jeden kritischen Vorgang gilt (kein Spielraum).
Kritische Vorgänge
Der kritische Weg ist .
Verzögert sich ein kritischer Vorgang, verzögert sich das gesamte Projekt.
Pufferzeiten
Zeitspannen, um die ein Vorgang verschoben werden kann, ohne die Projektdauer zu erhöhen:
- Gesamte Pufferzeit: .
- Freie Pufferzeit: : Spielraum, wenn alle Nachfolger frühestmöglich beginnen.
Weitere Pufferzeiten
- Freie Rückwärtspufferzeit: : Spielraum, wenn alle Vorgänger spätestmöglich enden.
- Unabhängige Pufferzeit: : Spielraum unabhängig von allen anderen Vorgängen.
Es gilt stets .
Puffer im Beispiel
| 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 ().
Zyklen
Wenn Maximalabstände gelten
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):
- erst vorwärts, dann rückwärts;
- vorwärts wird geprüft, ob Zeitpunkte zu klein sind, rückwärts, ob sie zu groß sind;
- wer aktualisiert wird, kommt hinten in die Liste, sofern er nicht schon darin steht.
Voraussetzung: alle Zyklen haben nichtpositive Länge. Ein Zyklus positiver Länge macht den Plan unzulässig.
Beispiel: Maximalabstand
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 erweiterte Netzplan
Der Zyklus hat die Länge : der Plan bleibt zulässig.
FIFO vorwärts
Liste mit Kopf und Ende . Start: , , alle anderen ; .
- Für jeden Nachfolger : ist ?
- Falls ja: , hinten einreihen (falls nicht bereits enthalten).
- Ist : Liste leer Abbruch.
- Sonst := nächster Knoten der Liste, .
Vorwärts mit der FIFO-Liste
| 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.
Ergebnis vorwärts
Der Rückwärtspfeil hat vorwärts nichts geändert (): Die frühesten Zeitpunkte sind dieselben wie ohne Zyklus.
FIFO rückwärts
Start: , , alle anderen ; .
- Für jeden Vorgänger : ist ?
- Falls ja: , hinten einreihen (falls nicht bereits enthalten).
- Ist : Liste leer Abbruch.
- Sonst := nächster Knoten der Liste, .
Rückwärts mit der FIFO-Liste
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.
Neue späteste Zeitpunkte
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 .
Kontrolle mit Julia
Projektdauer als LP
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
Vorwärtsrechnung als LP
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]
Rückwärtsrechnung als LP
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.
Zusammenfassung
Das Wichtigste auf einen Blick
- MPM-Netzplan: Vorwärtsrechnung liefert früheste, Rückwärtsrechnung späteste Zeitpunkte.
- Der kritische Weg ist der längste Weg; kritische Vorgänge haben .
- Pufferzeiten (GP, FP, FRP, UP) zeigen den Spielraum unkritischer Vorgänge.
- Maximalabstände werden zu negativen Rückwärtspfeilen; die Zyklen löst ein FIFO-Verfahren.