06 Graph Algorithms
06 Graph Algorithms
06
Graph Algorithms
Alternative Darstellung:
𝑢, 𝑣
𝑉 = {1,2,3,4,5,6} statt statt
𝐸 = { 1,4 , 1,5 , 1,2 , 2,2 , 2,4 , 4,6 , {5,6}} 𝑢, 𝑣 , (𝑣, 𝑢)
O
Länge des Pfades = 𝑘 − 1 = Anzahl Kanten
3 4 6
4 6
Gerichteter Graph
1 ist stark zusammenhängend,
wenn jeder Knoten von jedem
2 5 anderen Knoten aus
(gemäß Kantenrichtung)
erreichbar ist
nicht stark
4 6 zusammenhängend,
da kein Pfad 51
1 1
2 5 5 2
als (Graphen-)Bäume
=
3 4 6 4 6 3
1 1
2 5 2 5
3 4 6 3 4 6
0 0 0 1 1 0
I 1 1 0 0 0 0
2 5
i
𝐴= 0 0 0 0 0 0
0 1 0 0 0 0
0 0 0 0 0 1
6 0 0 0 1 0 0
3 4 6
bei ungerichteten Graphen ist
Matrix (spiegel-)symmetrisch
zur Hauptdiagonalen
𝑉 = {1,2,3,4,5,6}
𝐸 = { 1,4 , 1,5 , 2,1 , 2,2 , 4,2 , 5,6 , 6,4 } Speicherbedarf = Θ(|𝑉| )
0 0 0 1 0 0
0 0 0 0 1 0
0 0 0 0 0 1
i v j
v 1 Kante
𝐴 = 𝐴 𝐴
𝑎 ,
𝑎 ,
( ) ( ) ( )
𝑎, 𝑎, … 𝑎,
=
⋮
𝑎 ,
1 4 5
2 1 2
2 5
3
4 2
5 6
3 4 6 6 4
Speicherbedarf = Θ( 𝑉 + |𝐸|)
𝑉 = {1,2,3,4,5,6}
𝐸 = { 1,4 , 1,5 , 2,1 , 2,2 , 4,2 , 5,6 , 6,4 }
zusätzlich Funktion
1
w 1,2 =5 𝑤 1,5 = −3 𝑤: 𝐸 → ℝ
Beispiel:
Knoten = Städte Speicher zusätzlich zu Kante
Kanten = Zugverbindungen (𝑢, 𝑣) auch Wert 𝑤((𝑢, 𝑣))
Gewicht = Entfernung
Algorithmen und Datenstrukturen | Marc Fischlin | SS 23 | 06 Graph Algorithms | 15
Für die Adjazenzmatrix 𝐴 eines Graphen beschreibt
der Eintrag 𝑖, 𝑗 in 𝐴 = 𝐴 𝐴 ⋯ 𝐴 die Anzahl der Wege
mit 𝑛 Kanten von Knoten 𝑖 nach 𝑗 im Graphen.
kürzesten
Weg
in
den
2 3
2 2
2
2
2 1 2
2
0
2 2
2
2
2
2
2 2
2 3
2 2
2
Web Crawling
2
2 1 Kontakte in OSN
2
2
Broadcasting
0
2 2
2
2 Garbage Collection
…
2
2
2 2
1 FOREACH u in V–{s} DO
2 [Link]=WHITE; &
[Link]=+∞; [Link]=NIL;
3 [Link]=GRAY; [Link]=0; [Link]=NIL;
4 newQueue(Q);
WHITE =Knoten noch nicht besucht
5 enqueue(Q,s);
GRAY=in Queue für nächsten Schritt
6 WHILE !isEmpty(Q) DO BLACK =fertig
-
7 u=dequeue(Q); -
8 FOREACH v in adj(G,u) DO
9 IF [Link]==WHITE THEN
10 [Link]=GRAY; [Link]=[Link]+1; [Link]=u;
11 enqueue(Q,v);
12 [Link]=BLACK;
O
s=1 Q=(1) Q=(4 5)
1 1 1/1
7-12
↓
2 5 2 5
+∞/NIL
3 4 6 3 4 6
+∞/NIL 1/1
Algorithmen und Datenstrukturen | Marc Fischlin | SS 23 | 06 Graph Algorithms | 21
BFS: Algorithmus (Beispiel II)
BFS(G,s) //G=(V,E), s=source node in V
…
6 WHILE !isEmpty(Q) DO
7 u=dequeue(Q);
#12161
(
8 FOREACH v in adj(G,u) DO
9 IF [Link]==WHITE THEN
10 [Link]=GRAY; [Link]=[Link]+1; [Link]=u;
11 enqueue(Q,v);
12 [Link]=BLACK;
Q=(4 5) Q=(5 2)
+∞/NIL 1 2/4 1
7-12
2 5 2 5
1/1 1/1
3 4 6 3 4 6
1/1 1/1
Algorithmen und Datenstrukturen | Marc Fischlin | SS 23 | 06 Graph Algorithms | 22
BFS >
-
Stecks
***
…
6 WHILE !isEmpty(Q) DO ) (
7 u=dequeue(Q);
- -
8 FOREACH v in adj(G,u) DO
9 IF [Link]==WHITE THEN
10 [Link]=GRAY; [Link]=[Link]+1; [Link]=u;
11 enqueue(Q,v);
12 [Link]=BLACK;
Q=(5 2) Q=(2 6)
2/4 1 2/4 1
7-12
2 5 2 5
1/1 1/1
3 4 6 3 4 -O6
O
2x
3 4 6 3 4 6
8 FOREACH v in adj(G,u) DO
9 IF [Link]==WHITE THEN
10 [Link]=GRAY; [Link]=[Link]+1; [Link]=u;
11 enqueue(Q,v);
12 [Link]=BLACK;
Für u=[Link] ist, da v von u aus per Kante (u,v) ∈ 𝐸 besucht wurde,
der Pfad von s nach u und dann zu v ein Pfad der Länge
1 IF v==s THEN
2 PRINT s
3 ELSE
4 IF [Link]==NIL THEN
5 PRINT ‘no path from s to v‘
6 ELSE
7 PRINT-PATH(G,s,[Link]);
8 PRINT v;
E
0/NIL 1
2/4 1
2 5 5
4
1/1
3 4 6
2 6
+∞/NIL 1/1 2/5
𝐬 𝐬 𝐬
Definiere Subgraph 𝐺𝐩𝐫𝐞𝐝 = (𝑉𝐩𝐫𝐞𝐝 , 𝐸𝐩𝐫𝐞𝐝 ) von 𝐺 durch:
𝐬
𝑉𝐩𝐫𝐞𝐝 = v ∈ 𝑉 [Link] ≠ NIL} ∪ {s}
𝐬 𝐬
𝐸𝐩𝐫𝐞𝐝 = [Link],v v ∈ 𝑉𝐩𝐫𝐞𝐝 − s }
(und v,[Link] für ungerichtete Graphen)
2 5 5
4
1/1
3 4 6
2 6
+∞/NIL 1/1 2/5
𝐬 𝐬 𝐬
Definiere
𝐬 Subgraph
𝐺𝐩𝐫𝐞𝐝 ist BFS-Baum zu 𝐺 𝐩𝐫𝐞𝐝
𝐺, = (𝑉𝐩𝐫𝐞𝐝 𝐩𝐫𝐞𝐝 ) von 𝐺 durch:
, 𝐸
d.h. enthält𝐬 alle von s aus erreichbaren Knoten in 𝐺 und
𝑉𝐩𝐫𝐞𝐝 = v ∈ 𝑉𝐬 [Link] ≠ NIL} ∪ {s}
für jeden𝐸Knoten
𝐬
= ∈ 𝑉𝐩𝐫𝐞𝐝 existiert
[Link],v v ∈genau
𝑉 𝐬 einsPfad
− } von s
𝐬 𝐩𝐫𝐞𝐝 𝐩𝐫𝐞𝐝
in 𝐺𝐩𝐫𝐞𝐝 , der auch ein kürzester Pfad von s zu v in 𝐺 ist.
(und v,[Link] für ungerichtete Graphen)
folgenden Form den kürzesten Weg von Start (S) zu Ziel (Z) -
T Z
- & S
↓
↓
Hinweis: Sie sind selbst nicht im Labyrinth, sondern „schauen von oben darauf“
-
-
2
2
2
2 1
2
2
2 3
2
s
2 2
2 Anfang 2
2
2 usw.
2 2
1 FOREACH 0
u in V DO
time globale Variable =
2 [Link]=WHITE;
3 [Link]=NIL;
4 time=0;
DFS-VISIT(G,u) 5 FOREACH u in V DO
6 IF [Link]==WHITE THEN
1 time=time+1; 7 DFS-VISIT(G,u)
2 [Link]=time;
3 [Link]=GRAY;
4 FOREACH v in adj(G,u) DO
5 IF [Link]==WHITE THEN
6 [Link]=u;
disc = discovery time
7 DFS-VISIT(G,v);
finish=finish time
8 [Link]=BLACK;
9 time=time+1;
10 [Link]=time;
Algorithmen und Datenstrukturen | Marc Fischlin | SS 23 | 06 Graph Algorithms | 35
DFS: Beispiel (I) -
Ordnung auf Knotenlisten gemäß Knotennummern
DFS(G) //G=(V,E)
Aufrufs-Stack: DFS-VISIT(G,1)
-
1 FOREACH u in V DO
2 [Link]=WHITE;
3 [Link]=NIL;
4 time=0;
O
DFS-VISIT(G,u) time=0
5
6
gebrate
FOREACH u in V DO Y
IF T
[Link]==WHITE THEN
1 time=time+1; 7 -DFS-VISIT(G,u)
-
2 * [Link]=time;
−/−/NIL
3 [Link]=GRAY; ↓ -
−/−/NIL
4 FOREACH O & DO
v in adj(G,u) −/−/NIL -1
D
⑨
5 IF [Link]==WHITE THEN
2 5
6 ⑧
[Link]=u; 8
7 & DFS-VISIT(G,v);
8 [Link]=BLACK; 3 6
4
9 time=time+1;
10 [Link]=time; −/−/NIL −/−/NIL −/−/NIL
T
Aufrufs-Stack: DFS-VISIT(G,1)
DFS-VISIT(G,4)
1 FOREACH u in V DO
2 [Link]=WHITE;
3 [Link]=NIL;
4 time=0;
DFS-VISIT(G,u) time=0
time=1
5 FOREACH u in V DO
6 IF [Link]==WHITE THEN
1 time=time+1; 7 DFS-VISIT(G,u)
2 [Link]=time;
−/−/NIL
1/−/NIL
3 [Link]=GRAY;
1 −/−/NIL
4 FOREACH v in adj(G,u) DO −/−/NIL
5 IF [Link]==WHITE THEN
2 5
6 [Link]=u;
7 DFS-VISIT(G,v);
8 [Link]=BLACK; 3 6
4
9 time=time+1;
10 [Link]=time; −/−/NIL −/−/NIL
−/−/1 −/−/NIL
⑳
Aufrufs-Stack: DFS-VISIT(G,1)
DFS-VISIT(G,4)
DFS-VISIT(G,2)
1 FOREACH u in V DO
2 [Link]=WHITE;
3 [Link]=NIL;
4 time=0;
DFS-VISIT(G,u) time=1
time=2 5 FOREACH u in V DO
6 IF [Link]==WHITE THEN
1 time=time+1; 7 DFS-VISIT(G,u)
2 [Link]=time;
−/−/NIL
1/−/NIL
3 [Link]=GRAY;
1 −/−/NIL
4 FOREACH v in adj(G,u) DO
8 −/−/NIL
−/−/4
5 IF [Link]==WHITE THEN
2 5
6 [Link]=u;
7 & DFS-VISIT(G,v);
8 ⑤ [Link]=BLACK;
*
- 3 4 6
9 time=time+1; 7
⑧ -
5 IF [Link]==WHITE THEN
2 5
6 [Link]=u;
7 DFS-VISIT(G,v);
8 [Link]=BLACK; 3 6
4
9 time=time+1;
10 [Link]=time; −/−/NIL −/−/NIL
−/−/1
2/−/1 −/−/NIL
5 IF [Link]==WHITE THEN
2 5
6 [Link]=u;
7 DFS-VISIT(G,v);
8 [Link]=BLACK; 3 6
4
9 time=time+1;
10 [Link]=time; −/−/NIL −/−/NIL
−/−/1
2/−/1 −/−/NIL
5 IF [Link]==WHITE THEN
2 5
6 [Link]=u;
7 DFS-VISIT(G,v);
8 [Link]=BLACK; 3 6
4
9 time=time+1;
10 [Link]=time; −/−/NIL −/−/NIL
−/−/1
2/−/1 −/−/NIL
2 5
4
3 4 6
11/12/NIL
−/−/NIL −/−/NIL
−/−/1
2/−/1
2/9/1 −/−/NIL
−/−/5
6/−/5
6/7/5 2 5
Weg wieder:
-
−/−/NIL
1/−/NIL
1/10/NIL
5/−/4
5/8/4
−/−/4
−/−/NIL Rückwärtskante 1 3
3/−/4
3/4/4
−/−/NIL
−/−/4 1
(back edge)
2 5
4 Vorwärtskante
(forward edge)
3 4 6
11/12/NIL
−/−/NIL −/−/NIL
−/−/1
2/−/1
2/9/1 −/−/NIL
−/−/5
6/−/5
6/7/5 Schleife= 2 5
back edge Baumkante
Kreuzkante (tree edge)
Charakterisierung der (cross edge)
Kanten in 𝐺 mittels DFS 6
5/−/4
−/−/4
−/−/NIL
Beispiel: 56 3/−/4
3/4/4
−/−/NIL
−/−/4 1
2 5
da v noch nicht besucht wurde
und [Link]=u gesetzt wird
und dann ([Link],v)=(u,v) 3 4 6
als Kante in 𝐺𝐩𝐫𝐞𝐝 auftaucht
−/−/NIL −/−/NIL
−/−/1
2/−/1 −/−/NIL
−/−/5
−/−/NIL
1/−/NIL
1 −/−/NIL
Beispiel: 21 3/−/4
−/−/NIL
−/−/4
2 5
da die Kette von
grauen Knoten
auch im DFS-Baum 3 4 6
eine Kette bilden
−/−/NIL −/−/NIL
−/−/1
2/−/1 −/−/NIL
T
.
-
da [Link]<[Link] wurde v erst schwarz,
als u schon grau war;
2 5
[Link]: [Link]<[Link]
u v Hätte nur passieren können, als v von u
aus durch anderen Pfad bereits erreicht
und v in dem Moment grau wurde:
Sei u gerade aktiv (grau).
Betrachtete neue Kante {u,v}
u v
kann nur Vorwärts- oder
Kreuzkante werden, wenn
v schon abgeschlossen
(schwarz). Dann wäre aber Kante {v,u} bereits
bei v Rückwärtskante geworden.
Algorithmen und Datenstrukturen | Marc Fischlin | SS 23 | 06 Graph Algorithms | 55
Kantenarten in ungerichteten Graphen (II)
[Link]: [Link]>[Link]
u v Hätte nur passieren können, wenn u grau
geworden wäre, als v schon aktiv (grau) war:
>
.
-
.
1 Kind
Zuerst schwerf
1 2 3 ,
bevor 2
& kan
.
Do
Ron
nount
ans
Geben Sie eine andere Ordnung für den Durchlauf des DFS an,
.
- O
bei der keine Kreuzkanten entstehen.
#
Algorithmen und Datenstrukturen | Marc Fischlin | SS 23 | 06 Graph Algorithms | 57
Anwendungen DFS:
Topologisches Sortieren und
Starke Zusammenhangskomponenten
Job E
Job A Job G
Job D Job H
Job B
Job I
Job C Job F
gerichteter
-
Graph ohne Zyklen 5
1 4 5 2 3
„Kanten gehen immer nur nach rechts“ z.B. hier 2 und 3 vertauschbar
Algorithmen und Datenstrukturen | Marc Fischlin | SS 23 | 06 Graph Algorithms | 61
Topologisches Sortieren mittels DFS
1 newLinkedList(L);
2 --
run DFS(G) but, each time a node is finished,
-
insert in front of L
3 return [Link]
Laufzeit = 𝑂(|𝑉| + |𝐸|)
da Einfügen
in Liste vorne
in Zeit 𝑂(1)
1 newLinkedList(L);
2 run DFS(G) but, each time a node is finished,
insert in front of L
3 return [Link]
Korrektheit:
Es genügt zu zeigen, dass jede von DFS inspizierte Kante (u,v) ∈ 𝐸 erfüllt:
[Link]<[Link], so dass u zeitlich nach v in Liste eingefügt wird
und daher positionell vor v in Liste zu finden ist
[Link]: v bereits grau
Würde Rückwärtskante erzeugen,
u v
d.h. der Graph hätte einen Zyklus (Widerspruch).
1 newLinkedList(L);
2 run DFS(G) but, each time a node is finished,
insert in front of L
3 return [Link]
Korrektheit:
Es genügt zu zeigen, dass jede von DFS inspizierte Kante (u,v) ∈ 𝐸 erfüllt:
[Link]<[Link], so dass u zeitlich nach v in Liste eingefügt wird
und daher positionell vor v in Liste zu finden ist
[Link]: v noch weiß
Erzeugt Baumkante, also wird v Nachfahre von u
u v und [Link]<[Link], da Aufrufs-Stack
nicht zu u zurückkehrt, bevor v abgeschlossen.
Algorithmen und Datenstrukturen | Marc Fischlin | SS 23 | 06 Graph Algorithms | 64
Topologisches Sortieren: Korrektheit (III)
1 newLinkedList(L);
2 run DFS(G) but, each time a node is finished,
insert in front of L
3 return [Link]
Korrektheit:
Es genügt zu zeigen, dass jede von DFS inspizierte Kante (u,v) ∈ 𝐸 erfüllt:
[Link]<[Link], so dass u zeitlich nach v in Liste eingefügt wird
und daher positionell vor v in Liste zu finden ist
[Link]: v schwarz
Dann [Link] bereits gesetzt,
u v während [Link] erst später gesetzt wird,
also [Link]<[Link].
Algorithmen und Datenstrukturen | Marc Fischlin | SS 23 | 06 Graph Algorithms | 65
Wie können Sie bei der topologischen Sortierung
mittels DFS fast ohne zusätzlichen Aufwand erkennen,
ob ihr Graph einen Zyklus hat?
1 WHILE !isEmpty(V) DO
2 pick vertex u with inbound[u]==0
3 add u at the end of a list L
4 inbound[v]=inbound[v]-1 for each v with (u,v) in E
5 remove u from V and all (u,*) from E
ent
(a) es zwischen je zwei Knoten 𝑢, 𝑣 ∈ 𝐶 einen Pfad vonO
-
𝑢 nach 𝑣 gibt, und
(b) es keine Menge& 𝐷 ⊆ 𝑉 mit C ⊊ 𝐷 gibt, für die (a) auch gilt
- -
(𝐶 ist maximal).
größe unge gibt
1 2 3
𝐶 𝐷
Wenn es für verschiedene SCCs 𝐶, 𝐷 mit
u w
𝑢, 𝑣 ∈ 𝐶 und 𝑤, 𝑥 ∈ 𝐷 einen Pfad 𝑢𝑤 gibt,
dann kann es keinen Pfad 𝑥𝑣 geben,
-
v x
* „Zwei SCCs sind
- -
nur in eine Richtung verbunden.“*
-
Algorithmen und Datenstrukturen | Marc Fischlin | SS 23 | 06 Graph Algorithms | 68
SCC Algorithmus: Ansatz
Depth fist scan
* Algorithmus von Kosaraju
-
𝐸 = 𝑣, 𝑢 𝑢, 𝑣 ∈ 𝐸 }
„drehe Kanten in G um“
𝐺 𝐺
1 2 3 1 2 3
4 5 6 4 5 6
7 8 9 7 8 9
--
SCCs in 𝐺 und 𝐺 bleiben identisch
(in beiden Fällen gibt es in jeder SCC
einen Weg von jedem Knoten zum anderen Knoten)
-
nur Übergänge zwischen SCCs drehen sich um O
𝐺 𝐺
1 2 3 1 2 3
4 5 6 4 5 6
7 8 9 7 8 9
1 run DFS(G)
2 compute GT
3 run DFS(GT) but visit vertices in main loop
in descending finish time from 1
4 output each DFS tree in 3 as one SCC
DFS(G) //G=(V,E)
1 FOREACH u in V DO
2 [Link]=WHITE;
3 [Link]=NIL;
4 time=0;
5 FOREACH u in V DO
6 IF [Link]==WHITE THEN
7 DFS-VISIT(G,u)
1 run DFS(G)
2 compute GT
3 run DFS(GT) but visit vertices in main loop
in descending finish time from 1
4 output each DFS tree in 3 as one SCC
1 run DFS(G)
1 run DFS(G)
2 compute GT
3 run DFS(GT) but visit vertices in main loop
in descending finish time from 1
4 output each DFS tree in 3 as one SCC
2 compute GT
1 run DFS(G)
2 compute GT
3 run DFS(GT) but visit vertices in main loop
in descending finish time from 1
4 output each DFS tree in 3 as one SCC
3 run DFS(GT) …
9
DFS-
Suche
9
1 run DFS(G)
2 compute GT
3 run DFS(GT) but visit vertices in main loop
in descending finish time from 1
4 output each DFS tree in 3 as one SCC
3 run DFS(GT) …
9
DFS-
Suche
9
9 9
9
verbleibender Knoten mit Besucht alle Knoten der SCC
nächsthöheren und kehrt dann zu Hauptschleife usw.
finish time liegt DFS zurück, da kein Übergang
in dieser SCC zum nächsten SCC
Algorithmen und Datenstrukturen | Marc Fischlin | SS 23 | 06 Graph Algorithms | 75
SCC Algorithmus: Beispiel (I)
SCC(G) // G=(V,E) directed graph
1 run DFS(G)
2 compute GT
3 run DFS(GT) but visit vertices in main loop
in descending finish time from 1
4 output each DFS tree in 3 as one SCC
15
18 1 2 3 6
17 4 5 6 5 finish time
14
12
11 7 8 9
13
Algorithmen und Datenstrukturen | Marc Fischlin | SS 23 | 06 Graph Algorithms | 76
-(
1/
11/
67891011 12
-
% 1
-
--T
1415161718
-
-X
*
4 ->
#se
>
-
>
-
..
2
7
.
1
we
SCC Algorithmus: Beispiel (II)
SCC(G) // G=(V,E) directed graph
1 run DFS(G)
2 compute GT
3 run DFS(GT) but visit vertices in main loop
in descending finish time from O
-
1
4 output each DFS tree in 3 as one SCC
⑳
15
umgedrehte Kanten 18 1 2 3 6
17
⑨ 4 5
14
6 5
O ②
12
11
O 7 8 9
13
Algorithmen und Datenstrukturen | Marc Fischlin | SS 23 | 06 Graph Algorithms | 77
Algorithmendesign
sind DFS-basiert
-
Kosaraju 1978
Sharir 1981
Tarjan 1972
asymptotisch alle gleich schnell, aber Tarjans und pfad-basierter Algorithmus schneller in Praxis
-
-
verbindet. spanbaum
Der Spannbaum istO
-
minimal, wenn
-panbaum
𝑤 𝑇 = 𝑤( 𝑢, 𝑣 ) ·
Azyklisch
{ , }∈
alle knoten
minimal für alle Spannbäume vonO
𝐺 ist. verbindet
·
+
2
1 2 3
Spannbaum des Graphen
-
4 7 5 (durch breite
11
Kanten gekennzeichnet)
1
3 4
𝑤 𝑇 = 𝑤( 𝑢, 𝑣 )
-
der Gewicht 00
7 oder 11 enthält,
{ , }∈ -
O
𝑤 𝑇 = 2 + 3 + 7 + 11 = 23
- -
𝑤 𝑇′ = 4 + 2 + 3 + 1 = 10
2 2
1 2 3 1 2 3
4 7 5 4 7 5
11 11
1 1
3 4 3 4
-
zyklisch weiterverteilt
100-Mbit/s
w weight function -
1 A=∅
2 WHILE A does not form a spanning tree for G DO =
-
A Teilmenge der Kanten eines MST & Kante {u,v} ist sicher („safe“) für A,
-
Terminierung:
Da wir zeigen werden, dass es in jeder Iteration eine sichere Kante für
A gibt (sofern A noch kein Spannbaum), terminiert die Schleife nach
=>
-
Korrektheit:
Da in jeder Iteration nur sichere Kanten hinzugefügt werden
(für die A ∪{{u,v}} noch Teilmenge eines MST ist),
ist am Ende der WHILE-Schleife A ein MST.
für Schnitt -
Schnitt überbrückenden Kanten
𝑈 ist Spannbaum, da
Sei A Teilmenge eines MST, jeder Knoten erreichbar ist:
(𝑺,𝑽−𝑺) Schnitt, der A respektiert, Nimm statt „Brücke“ {𝑥, 𝑦} den Pfad
und {𝑢, 𝑣} eine leichte Kante, 𝑥 nach 𝑢, dann {𝑢, 𝑣}, dann 𝑣 nach 𝑦.
die den Schnitt überbrückt.
Dann ist {𝑢, 𝑣} sicher für A.
„Leicht=sicher“
legt Greedy-Strategie
für konkrete Implementierung
nahe
Jarnik 1930
Kruskal 1956 Prim 1957
Dijkstra 1959
Algorithmus Algorithmus
von Kruskal von Prim
2
Zu jedem Knoten& 𝑣 sei 𝑠𝑒𝑡(𝑣) Menge
1 2 3 von mit 𝑣 durch A verbundenen Knoten.
Zu Beginn ist 𝑠𝑒𝑡(𝑣) = {𝑣}.
4 7 5
11
𝑠𝑒𝑡(𝑢), 𝑠𝑒𝑡(𝑣) sind disjunkt oder identisch
1
3 4
Im Beispiel 𝑠𝑒𝑡 1 = 1,2 , 𝑠𝑒𝑡(4) = {4,5}.
Algorithmen und Datenstrukturen | Marc Fischlin | SS 23 | 06 Graph Algorithms | 91
Algorithmus von Kruskal: Korrektheit
MST-Kruskal(G,w) // G=(V,E) undirected, connected graph
w weight function
1 A=∅
2 FOREACH v in V DO set(v)={v};
3 Sort edges according to weight in nondecreasing order
4 FOREACH {u,v} in E according to order DO
5 IF set(u)!=set(v) THEN
6 A = A ∪{{u,v}}
7 UNION(G,u,v);
8 return A
2
Jede ausgewählte Kante {𝑢, 𝑣} mit
1 2 3 𝑠𝑒𝑡 𝑢 ≠ 𝑠𝑒𝑡 𝑣 ist leicht für Schnitt
𝑠𝑒𝑡 𝑢 , 𝑉 − 𝑠𝑒𝑡 𝑢 .
4 7 5
11
Schnitt respektiert A.
1
3 4 Somit Kante auch sicher für A.
{1} 1 7 7 {7} 4
Initialisierung (1-3) 8 11 0
6 5
{6} -2 {5}
"y
7 UNION(G,u,v);
123456
8 return A {2} {3}
5
2 =3
15 -1 4
I {4}
↑
9
,
1456
-
S
{1} 1 7 7 {7} 4 7456
Schritte 4-8:
Kante {5,6} aufnehmen 8 11 D0
&
3456
6 5
OS
{5,6}
{6} arb
S
-2
O
no
{5,6}
{5}
{1}
{1,2} 1 7 7 {7} 4
Schritte 4-8:
8 11 0
Kante {1,2} aufnehmen
6 5
{5,6}
{6} -2 {5,6}
{5}
{1}
{1,2} 1 7 7 {7} 4
Schritte 4-8:
8 11 0
Kante {4,5} aufnehmen
6 5
{5,6}
{6}
{4,5,6} -2 {4,5,6}
{5,6}
{5}
{1}
{1,2} 1 7 7 {7} 4
Schritte 4-8:
8 11 0
Kante {3,4} aufnehmen
6 5
{5,6}
{3,4,5,6}
{6}
{4,5,6} -2 {4,5,6}
{5,6}
{5}
{3,4,5,6}
{1}
{1,…,6}
{1,2} 1 7 7 {7} 4
Schritte 4-8:
8 11 0
Kante {2,3} aufnehmen
6 5
{1,…,6}
{5,6}
{3,4,5,6}
{6}
{4,5,6} -2 {4,5,6}
{5,6}
{5}
{3,4,5,6}
{1,…,6}
{1}
{1,…,6}
{1,2} 1 7 7 {7} 4
Schritte 4-8:
8 11 0
Kante {2,6} nicht aufnehmen,
da 𝑠𝑒𝑡(2) = 𝑠𝑒𝑡(6) = {1, … , 6} 6 5
{1,…,6}
{5,6}
{3,4,5,6}
{6}
{4,5,6} -2 {4,5,6}
{5,6}
{5}
{3,4,5,6}
{1,…,6}
{1}
{1,…,6}
{1,2} 1 7 7 {7} 4
Schritte 4-8:
8 11 0
Kante {1,6} nicht aufnehmen,
da 𝑠𝑒𝑡(1) = 𝑠𝑒𝑡(6) = {1, … , 6} 6 5
{1,…,6}
{5,6}
{3,4,5,6}
{6}
{4,5,6} -2 {4,5,6}
{5,6}
{5}
{3,4,5,6}
{1,…,6}
{1,…,7}
{1}
{1,…,6}
{1,2} 1 7 7 {1,…,7}
{7} 4
Schritte 4-8:
8 11 0
Kante {3,7} aufnehmen
6 5
{1,…,7}
{1,…,6}
{5,6}
{3,4,5,6}
{6}
{4,5,6} -2 {4,5,6}
{5,6}
{5}
{1,…,7}
{3,4,5,6}
{1,…,6}
5 IF set(u)!=set(v) THEN
6 A = A ∪{{u,v}}
7 UNION(G,u,v); {1,…,7} {1,…,7}
{1,…,6}
{1,2}
{2} {1,…,6}
{3,4,5,6}
{3}
8 return A
5
2 3
-1 9 4 {1,…,6}
{1,…,7}
{3,4,5,6}
{4}
{4,5,6}
{1,…,7}
{1}
{1,…,6}
{1,2} 1 7 7 {1,…,7} 4
Schritte 4-8:
8 11 0
Kante {6,7} nicht aufnehmen,
da 𝑠𝑒𝑡(6) = 𝑠𝑒𝑡(7) = {1, … , 7} 6 5
{1,…,7}
{1,…,6}
{5,6}
{3,4,5,6}
{6}
{4,5,6} -2 {4,5,6}
{5,6}
{5}
{1,…,7}
{3,4,5,6}
{1,…,6}
{1,…,7}
{1}
{1,…,6}
{1,2} 1 7 7 {1,…,7}
{7} 4
8 11 0
𝑤 𝑇 = −1 + 5 + 4 + 0 − 2 + 9 = 15
6 5
{1,…,7}
{1,…,6}
{5,6}
{3,4,5,6}
{6}
{4,5,6} -2 {4,5,6}
{5,6}
{5}
{1,…,7}
{3,4,5,6}
{1,…,6}
da V − 1 ≤ 𝐸 ≤ |𝑉| und
somit log 𝐸 = 𝜃(log |𝑉|)
Shoot
r=6
1 7 7 ∞, NIL 4
8 11 0
𝑄 = {1,2,3,4,5,6,7}
6 5
-2
A= v,[Link] v ∈ 𝑉 − 𝑟 ∪𝑄 −∞, NIL ∞, NIL
Algorithmen und Datenstrukturen | Marc Fischlin | SS 23 | 06 Graph Algorithms | 107
Algorithmus von Prim: Beispiel (II)
MST-Prim(G,w,r) // r root in V, MST given through [Link] values
8 11 0
𝑄
𝑄== {1,2,3,4,5,6,7}
{1,2,3,4,5,7}
6 5
A= v,[Link] v ∈ 𝑉 − 𝑟 ∪𝑄 −∞, NIL O
-2
6
−2,NIL
∞,
Algorithmen und Datenstrukturen | Marc Fischlin | SS 23 | 06 Graph Algorithms | 108
Algorithmus von Prim: Beispiel (III)
MST-Prim(G,w,r) // r root in V, MST given through [Link] values
11
𝑄
𝑄𝑄=
=={1,2,3,4,5,6,7}
{1,2,3,4,5,7}
{1,2,3,4,7} 8
O
0
6 5
-2
A= v,[Link] v ∈ 𝑉 − 𝑟 ∪𝑄 −∞, NIL ∞, 6
−2,NIL
Algorithmen und Datenstrukturen | Marc Fischlin | SS 23 | 06 Graph Algorithms | 109
Algorithmus von Prim: Beispiel (IV)
MST-Prim(G,w,r) // r root in V, MST given through [Link] values
8 11 0
𝑄 𝑄
===
𝑄𝑄= {1,2,3,7}
{1,2,3,4,5,6,7}
{1,2,3,4,5,7}
{1,2,3,4,7}
6 5
-2
A= v,[Link] v ∈ 𝑉 − 𝑟 ∪𝑄 −∞, NIL ∞, 6
−2,NIL
Algorithmen und Datenstrukturen | Marc Fischlin | SS 23 | 06 Graph Algorithms | 110
Algorithmus von Prim: Beispiel (V)
MST-Prim(G,w,r) // r root in V, MST given through [Link] values
2 &
5
3
-1 9 4
Schritte 3-8: 6
8, NIL
∞, &
0, 5NIL
∞,
u=3 extrahieren
1 7 7 11, 36
9, NIL
∞, 4
8 11 0
𝑄 𝑄
𝑄𝑄===
=𝑄 ={1,2,3,7}
{1,2,7}
{1,2,3,4,5,6,7}
{1,2,3,4,5,7}
{1,2,3,4,7}
6 5
-2
A= v,[Link] v ∈ 𝑉 − 𝑟 ∪𝑄 −∞, NIL O
∞, 6
−2,NIL
Algorithmen und Datenstrukturen | Marc Fischlin | SS 23 | 06 Graph Algorithms | 111
Algorithmus von Prim: Beispiel (VI)
MST-Prim(G,w,r) // r root in V, MST given through [Link] values
8 11 0
𝑄 𝑄
𝑄𝑄= =
=𝑄
=𝑄 ={1,2,3,7}
= {1,7}
{1,2,7}
{1,2,3,4,5,6,7}
{1,2,3,4,5,7}
{1,2,3,4,7}
6 5
-2
A= v,[Link] v ∈ 𝑉 − 𝑟 ∪𝑄 −∞, NIL ∞, 6
−2,NIL
Algorithmen und Datenstrukturen | Marc Fischlin | SS 23 | 06 Graph Algorithms | 112
Algorithmus von Prim: Beispiel (VII)
MST-Prim(G,w,r) // r root in V, MST given through [Link] values
3
6
5,NIL
7,
∞,
8 [Link]=u;
4, 4
∞, NIL
5
2 3
-1 9 4
Schritte 3-8: −1,
∞, 62
8, NIL 0, 5NIL
∞,
u=1 extrahieren
1 7 7 11, 36
9, NIL
∞, 4
8 11 0
𝑄 𝑄
=𝑄
𝑄𝑄= =
=𝑄𝑄={1,2,3,7}
=
={1,2,7}
{1,7}
{7}
{1,2,3,4,5,6,7}
{1,2,3,4,5,7}
{1,2,3,4,7}
6 5
-2
A= v,[Link] v ∈ 𝑉 − 𝑟 ∪𝑄 −∞, NIL ∞, 6
−2,NIL
Algorithmen und Datenstrukturen | Marc Fischlin | SS 23 | 06 Graph Algorithms | 113
Algorithmus von Prim: Beispiel (VIII)
MST-Prim(G,w,r) // r root in V, MST given through [Link] values
8 11 0
𝑄 𝑄
=𝑄
𝑄𝑄= =
=𝑄 𝑄
𝑄
={1,2,3,7}
==
= {}
{1,7}
{7}
{1,2,7}
{1,2,3,4,5,6,7}
{1,2,3,4,5,7}
{1,2,3,4,7}
6 5
-2
A= v,[Link] v ∈ 𝑉 − 𝑟 ∪𝑄 −∞, NIL ∞, 6
−2,NIL
Algorithmen und Datenstrukturen | Marc Fischlin | SS 23 | 06 Graph Algorithms | 114
Algorithmus von Prim: Korrektheit
MST-Prim(G,w,r) // r root in V, MST given through [Link] values
2
Länge eines Pfades
- m
2 𝑝 = (𝑣 , … , 𝑣 ) ∈ 𝑉
von 𝑢 = 𝑣 zu 𝑣 = 𝑣 :
Länge=8
7 2
𝑤 𝑝 =∑ 𝑤(( 𝑣 , 𝑣 ))
2 1
2
Länge=6
3 s
2
2 𝑠ℎ𝑜𝑟𝑡𝑒𝑠𝑡(𝑢, 𝑣) =
Länge=7 4
-2 min{𝑤(𝑝) ∶ 𝑝 Pfad von 𝑢 nach 𝑣 }
2 2
3
{ ∞
wenn 𝑣 erreichbar von 𝑢
sonst
- 5
1 2
2
2 5 10 5
1 3
9 4 3
5
Umsteigebraten
-welgen
Kürzester „Kantenweg“ 1 nach 3 = 13 Kürzester Weg 14 mit Gewicht
Kürzester „Gewichtsweg“ = 123
-
5 5
1 2 3
5 5
1 2 3
0
Kürzeste Pfade können keine Zyklen
-
+Annahme über
nicht-negative Zyklen
*
Kürzeste Pfade enthalten höchstens (eliminierbare) Zyklen mit Gewicht 0
-
𝑠 𝑥 𝑧
Gemeinsame Idee:
„Lockerung“ / Relaxation
Laufzeit
Laufzeit = 𝑂( 𝑉 𝐸) Laufzeit = 𝑂( 𝑉 + 𝐸 ) = 𝑂( 𝑉 log |𝑉| + 𝐸 )
↓ Kantengewichte
directed -
>
-
relax(G,u,v,w) ditraliste
, auper
1
-Zir) Quelle
IF [Link] > [Link] + w((u,v)) THEN
+
>
- bei Gleichheit Quese S
nidisiere
,
-
2 [Link]=[Link] + w((u,v));
-
3 [Link]=u;
5 5
1 2 relax 1 2
keine
dist=7 dist=11 dist=7 dist=11
A
ktudisitry
Algorithmen und Datenstrukturen | Marc Fischlin | SS 23 | 06 Graph Algorithms | 124
Bellman-Ford-Algorithmus initSSSP(G,s,w)
Bellman-Ford-SSSP(G,s,w) 1 FOREACH v in V DO
laten 2 [Link]=∞;
alle
1 initSSSP(G,s,w); * Distance nochen - 3 [Link]=NIL;
FOR i=1 TO |V|-1 DO Vergänge auf
-
2 4 [Link]=0;
: 11
3 FOREACH (u,v) in E DO seres
Z
allen Ersten
zur Quelle
von s nach z
-
1 initSSSP(G,s,w);
2 FOR i=1 TO |V|-1 DO Erste Iteration der
3 FOREACH (u,v) in E DO FOR-Schleife in 2
4 relax(G,u,v,w);
erfasst (mindestens)
5 FOREACH (u,v) in E DO
6 IF [Link] > [Link]+w((u,v)) THEN den ersten Schritt
7 return false; von s zum
8 return true; nächsten Knoten
dist=2
Andere Relaxation-
2 -1
3 1 Schritte (auch später)
s z können dies
dist=0 nicht „zerstören“,
da sonst
Wenn keine „negativen Zyklen“, gibt es kürzerer Pfad
kürzesten Pfad der Kantenlänge 𝑉 − 1 ohne Schleifen
Algorithmen und Datenstrukturen | Marc Fischlin | SS 23 | 06 Graph Algorithms | 126
Bellman-Ford: Idee / Korrektheit (II)
Betrachte Wirkung
Bellman-Ford-SSSP(G,s,w) auf kürzesten Pfad
von s nach z
1 initSSSP(G,s,w);
2 FOR i=1 TO |V|-1 DO Zweite Iteration der
3 FOREACH (u,v) in E DO FOR-Schleife in 2
4 relax(G,u,v,w);
erfasst (mindestens)
5 FOREACH (u,v) in E DO
6 IF [Link] > [Link]+w((u,v)) THEN den zweiten Schritt
7 return false; von s zum
8 return true; zweiten Knoten
dist=2 dist=1
2 -1
3 1
s z
dist=0
dist=0
dist=4
Dann wäre wegen 𝑤 𝑐 < 0 und 𝑣 = 𝑣 und 𝑣 . dist<∞ für erreichbare Knoten:
∑ 𝑣 . dist ∑ 𝑣 . dist + ∑𝒌𝒊 𝟏 𝑤((𝑣 , 𝑣 ))
< ∑ 𝑣 . dist = ∑ 𝑣 . dist Widerspruch.
Algorithmen und Datenstrukturen | Marc Fischlin | SS 23 | 06 Graph Algorithms | 131
Bellman-Ford: Beispiel (I)
Bellman-Ford-SSSP(G,s,w)
1 initSSSP(G,s,w);
2 FOR i=1 TO |V|-1 DO
3 FOREACH (u,v) in E DO
4 relax(G,u,v,w);
5 FOREACH (u,v) in E DO
6 IF [Link] > [Link]+w((u,v)) THEN
7 return false;
8 return true;
Initialisierung -3 ∞/NIL
für O
s=1 in 1 ∞/NIL
0
6 2 3 3
Anfang =
1 1
>
-
1 1 7 4 4
-3
-
0/NIL
2 6
∞/NIL
5
2 ∞/NIL
5
∞/NIL ∞/NIL
Algorithmen und Datenstrukturen | Marc Fischlin | SS 23 | 06 Graph Algorithms | 132
Bellman-Ford: Beispiel (II)
Bellman-Ford-SSSP(G,s,w) Kanten in FOREACH in 3 -
gemäß lexikographischer
1 initSSSP(G,s,w); -
1 initSSSP(G,s,w);
2 FOR i=1 TO |V|-1 DO
3 FOREACH (u,v) in E DO
4 relax(G,u,v,w);
5 FOREACH (u,v) in E DO
6 IF [Link] > [Link]+w((u,v)) THEN
7 return false;
8 return true;
3 FOREACH (u,v) in E DO
4 relax(G,u,v,w);
5 FOREACH (u,v) in E DO Algorithmus gibt
6 IF [Link] > [Link]+w((u,v)) THEN true zurück
7 return false;
8 return true;
-3 𝟑/7
𝟔/2
∞/NIL
𝟔/1
∞/NIL
𝟑/6
0
6 2 3 3
1
1 1 7 4 4
0/NIL -3 ∞/NIL
−𝟏/6
𝟕/2 𝟔/3
2 𝟗/3
∞/NIL
2 6 5
5
𝟐/1
∞/NIL 𝟕/6
∞/NIL
Algorithmen und Datenstrukturen | Marc Fischlin | SS 23 | 06 Graph Algorithms | 136
SSSP mittels Topologischer Sortierung
6
4 3
3 11
1
dag 6
mit Gewichten 1 2
-2 4
5
Topologisches Sortieren
6 11
3 -2 4 1
1 4 5 2 3
6
1 initSSSP(G,s,w);
2 execute topological sorting
3 FOREACH u in V in topological order DO
4 FOREACH v in adj(u) DO
5 relax(G,u,v,w);
6 11
3 -2 4 1
1 4 5 2 3
6
6 11
3 -2 4 1
1 4 5 2 3
6
0/NIL ∞/NIL ∞/NIL ∞/NIL ∞/NIL
1 initSSSP(G,s,w);
2 execute topological sorting
3 FOREACH u in V in topological order DO
4 FOREACH v in adj(u) DO
5 relax(G,u,v,w);
3 FOREACH (u=1)
6 11
3 -2 4 1
1 4 5 2 3
6
0/NIL ∞/NIL
𝟑/1 ∞/NIL ∞/NIL
𝟔/1 𝟏𝟏/1
∞/NIL
1 initSSSP(G,s,w);
2 execute topological sorting
3 FOREACH u in V in topological order DO
4 FOREACH v in adj(u) DO
5 relax(G,u,v,w);
3 FOREACH (u=4)
6 11
3 -2 4 1
1 4 5 2 3
6
0/NIL ∞/NIL
𝟑/1 ∞/NIL
𝟏/4 ∞/NIL
𝟔/1 𝟏𝟏/1
𝟗/4
∞/NIL
1 initSSSP(G,s,w);
2 execute topological sorting
3 FOREACH u in V in topological order DO
4 FOREACH v in adj(u) DO
5 relax(G,u,v,w);
3 FOREACH (u=5)
6 11
3 -2 4 1
1 4 5 2 3
6
0/NIL ∞/NIL
𝟑/1 ∞/NIL
𝟏/4 ∞/NIL
𝟔/1
𝟓/5 𝟏𝟏/1
𝟗/4
∞/NIL
1 initSSSP(G,s,w);
2 execute topological sorting
3 FOREACH u in V in topological order DO
4 FOREACH v in adj(u) DO
5 relax(G,u,v,w);
3 FOREACH (u=2)
6 11
3 -2 4 1
1 4 5 2 3
6
0/NIL ∞/NIL
𝟑/1 ∞/NIL
𝟏/4 ∞/NIL
𝟔/1
𝟓/5 𝟔/2
𝟏𝟏/1
𝟗/4
∞/NIL
6 11
3 -2 4 1
1 4 5 2 3
6
0/NIL ∞/NIL
𝟑/1 ∞/NIL
𝟏/4 ∞/NIL
𝟔/1
𝟓/5 𝟔/2
A B
3
4
E
2
Algorithmen und Datenstrukturen | Marc Fischlin | SS 23 | 06 Graph Algorithms | 145
Dijkstra-Algorithmus
D
Dijkstra-SSSP(G,s,w) Voraussetzung: alle
𝒘( 𝒖, 𝒗 ) ≥ 𝟎 laten habe
1 initSSSP(G,s,w); Positive für alle Kanten
2 Q=V; //let S=V-Q Sericht
3 WHILE !isEmpty(Q) DO
4 u=EXTRACT-MIN(Q); //wrt. dist (mittels Fibonacci-Heaps)
5 FOREACH v in adj(u) DO
6 relax(G,u,v,w); Laufzeit = 𝜃(|𝑉| log |𝑉| + |𝐸|)
MST-Prim(G,w,r)
[ Ähnlichkeit zu
Prims Algorithmus
7
8
[Link]=w({u,v});
[Link]=u;
Initialisierung 3 ∞/NIL
in Schritt 1 ∞/NIL
0
6 2 3 3
1
1 1 4
0/NIL 3
∞/NIL
2 6 5 2
5
∞/NIL ∞/NIL
Algorithmen und Datenstrukturen | Marc Fischlin | SS 23 | 06 Graph Algorithms | 147
Dijkstra-Algorithmus: Beispiel (II)
Dijkstra-SSSP(G,s,w) Voraussetzung:
𝒘( 𝒖, 𝒗 ) ≥ 𝟎
1 initSSSP(G,s,w); für alle Kanten
2 Q=V; //let S=V-Q
3 WHILE !isEmpty(Q) DO
4 u=EXTRACT-MIN(Q); //wrt. dist
5 FOREACH v in adj(u) DO
6 relax(G,u,v,w);
5
üsiz
𝟐/1
∞/NIL ∞/NIL
ola ,
sea
Algorithmen und Datenstrukturen | Marc Fischlin | SS 23 | 06 Graph Algorithms | 148
Dijkstra-Algorithmus: Beispiel (III)
Dijkstra-SSSP(G,s,w) Voraussetzung:
𝒘( 𝒖, 𝒗 ) ≥ 𝟎
1 initSSSP(G,s,w); für alle Kanten
2 Q=V; //let S=V-Q
3 WHILE !isEmpty(Q) DO
4 u=EXTRACT-MIN(Q); //wrt. dist
5 FOREACH v in adj(u) DO
6 relax(G,u,v,w);
3 𝟑/2
𝟓/6
∞/NIL
𝟑/6
𝟔/1
∞/NIL
0
6 2 3 3
1
1 1 4
Beispiel: 0/NIL 3
∞/NIL
𝟔/3
kürzester 2 6 5 2
Weg 14 5
𝟐/1
∞/NIL 𝟕/6
𝟒/2
∞/NIL
Algorithmen und Datenstrukturen | Marc Fischlin | SS 23 | 06 Graph Algorithms | 154
Dijkstra-Algorithmus: Korrektheit (I)
Dijkstra-SSSP(G,s,w) Für jeden betrachteten
Knoten u in der
1 initSSSP(G,s,w); WHILE-Schleife gilt:
2 Q=V; //let S=V-Q [Link]= 𝑠ℎ𝑜𝑟𝑡𝑒𝑠𝑡(𝑠, 𝑢)
3 WHILE !isEmpty(Q) DO
4 u=EXTRACT-MIN(Q); //wrt. dist
5 FOREACH v in adj(u) DO Angenommen, u wäre erster
6 relax(G,u,v,w); Knoten, bei dem nicht der Fall
nicht-
Da nur positive
negative
Kantengewichte gilt
s u
𝑠ℎ𝑜𝑟𝑡𝑒𝑠𝑡 𝑠, 𝑦 𝑠ℎ𝑜𝑟𝑡𝑒𝑠𝑡(𝑠, 𝑢),
y und damit
x
Da nur positive
Andererseits
Kantengewichte
wurde gilt
s u
u vor y für S
𝑠ℎ𝑜𝑟𝑡𝑒𝑠𝑡 𝑠, 𝑦 𝑠ℎ𝑜𝑟𝑡𝑒𝑠𝑡(𝑠,
ausgewählt, also 𝑢),
y [Link] damit
≤ [Link] und
x
Folglich
Da nur positive
Andererseits
Kantengewichte
wurde gilt
s u
[Link] u=vor y für S𝑠, 𝑦
𝑠ℎ𝑜𝑟𝑡𝑒𝑠𝑡
𝑠, 𝑦 𝑠, 𝑢𝑠ℎ𝑜𝑟𝑡𝑒𝑠𝑡(𝑠,
ausgewählt,
= 𝑠ℎ𝑜𝑟𝑡𝑒𝑠𝑡
𝑠ℎ𝑜𝑟𝑡𝑒𝑠𝑡 [Link],
=also 𝑢),da
y [Link] damit
≤ [Link] und
x
1
2 3
6
-5
2
1 4
0
5
5
∞/NIL 1
Initialisierung 2 3 ∞/NIL
in Schritt 1
6
-5
2
0/NIL 1 4
∞/NIL 0
5
5
∞/NIL
∞/NIL
𝟔/1 1
3 WHILE (u=1) 2 3 ∞/NIL
6
-5
2
0/NIL 1 4
∞/NIL 0
5
5
𝟓/1
∞/NIL
∞/NIL
𝟔/1 1
3 WHILE (u=5) 2 3 ∞/NIL
6
-5
2
0/NIL 1 4
∞/NIL 0
5
5
𝟓/1
∞/NIL
∞/NIL
𝟔/1 1
3 WHILE (u=2) 2 3 ∞/NIL
𝟕/2
6
-5
2
0/NIL 1 4
∞/NIL
𝟖/2 0
5
5
𝟓/1
∞/NIL
∞/NIL
𝟔/1 1
3 WHILE (u=3) 2 3 ∞/NIL
𝟕/2
6 Der im Augenblick
-5
2 nicht erfasste Weg
von 13 über 4
0/NIL 1 4
wird später zum
∞/NIL
𝟖/2 0 kürzeren Weg
5
5
𝟓/1 wird nicht „relaxed“
∞/NIL
∞/NIL
𝟔/1 1
3 WHILE (u=4) 2 3 ∞/NIL
𝟕/2
𝟑/4
6
-5
2
0/NIL 1 4
∞/NIL
𝟖/2 0
5
5
𝟓/1
∞/NIL Algorithmus terminiert.
-5 0
1 2 1 2
+5
1 2 6 7
3 3
Problem: man addiert den Wert so oft, wie #Kanten auf dem kürzesten Weg
Algorithmen und Datenstrukturen | Marc Fischlin | SS 23 | 06 Graph Algorithms | 167
A*-Algorithmus (I) Hart, Nilsson, Raphael (1968)
Dijkstra-SSSP(G,s,w)
1 initSSSP(G,s,w);
2 Q=V; //let S=V-Q
3 WHILE !isEmpty(Q) DO Dijkstras Algorithmus sucht lokal
-
15
s t
2 3 2 8 2
4 3 2 1 5 6
7 5 2 0 8
Algorithmus sucht erst
-
in falscher Richtung
-
A*(G,s,t,w)
1 init(G,s,t,w);
2 Q=V; //let S=V-Q jeder Knoten u bekommt
=
15
s t
2 3 2 8 2
4 3 2 1 5 6
9 8 6 5 1 0
5 2 0 8 10
Algorithmen und Datenstrukturen | Marc Fischlin | SS 23 | 06 Graph Algorithms | 169
A*-Algorithmus (III) (nicht-negative Kantengewichte)
15
s t
2 3 2 8 2
4 3 2 1 5 6
9 8 6 5 1 0
·
Maximaler Fluss
in Graphen
Kanten haben
(aktuellen) Flusswert
-
2 0/5 -
Jeder Knoten außer s undO
t
3/5 hat gleichen <
2/3
-
s 3 2/5 t
4/5
2
2/7 3/8 Ziel:
1/2 0/3 Finde maximalen Fluss
-
von s nach t
-
1/3 2
2 0/5
Ein Fluss 𝑓: 𝑉 × 𝑉 → ℝ für
3/5
1/3 2 2/3 ein Flussnetzwerk 𝐺 =
1/6
(𝑉, 𝐸) mit KapazitätO 𝑐 und
-
=
1/2 0/3
𝑓(𝑢, 𝑣) = 𝑓(𝑣, 𝑢)
1/3 2 ∈ ∈
2 0/5
Ein Fluss 𝑓: 𝑉 × 𝑉 → ℝ für
O
3/5
b 1/3 2 &
2/3
③
ein Flussnetzwerk 𝐺 =
(𝑉, 𝐸) mit Kapazität 𝑐 und
s
O1/6 3 2/7 Quelle 𝑠 und Senke 𝑡 erfüllt
2/5 4/5 t
& 0 ≤ 𝑓(𝑢, 𝑣) ≤ 𝑐(𝑢, 𝑣) für
2 alle 𝑢, 𝑣 ∈ 𝑉, sowie für alle
&2/7 3/8
1/2 0/3
𝑢 ∈ 𝑉 − {𝑠, 𝑡}:
𝑓(𝑢, 𝑣) = 𝑓(𝑣, 𝑢)
1/3 2 ∈ ∈
3 3
2/5 2/5
s1 Vereinige s1
Quellen
3 t1 und Senken ∞ 3 t1 ∞
∞
s2 s s2 t
↓
3 t2
-
Take
∞
3 t2 ∞ ↓
s3 Quelle s3 Fore
Senke
der
-
Abflüsse beschreibt
2 0/5
3/5
1/3 2 2/3
1/6
s 3 2/5 2/7
4/5 t
2
2/7 3/8
1/2 0/3
1/3 2
-
daher wohldefiniert
2 2 5
⑮ et Ge 3/5 2
3/4 2 1 3 1 2
6 3
& 6/6
s 3 s 3 9
>
-
9/10 6
O
+2
+2 0/5
2 2 5
3/5 2
3/4 t 1 3 1 t
3
6/6
s 3 s 3 9
9/10 6
1 FOREACH e in E DO [Link]=0;
2 WHILE there is path p from s to t in 𝑮𝐟𝐥𝐨𝐰 DO
Z.B. wenn
3 𝒄𝐟𝐥𝐨𝐰 𝒑 = 𝒎𝒊𝒏 𝒄𝐟𝐥𝐨𝐰 𝒖, 𝒗 𝒖, 𝒗 𝒊𝒏 𝒑 }
in jeder Iteration
4 FOREACH e in p DO
der Fluss nur
5 IF e in E THEN um 1/𝑢 = 0.1
6 [Link]=[Link]+ 𝒄𝐟𝐥𝐨𝐰 𝒑 erhöht wird
7 ELSE
8 [Link]=[Link]- 𝒄𝐟𝐥𝐨𝐰 𝒑 Laufzeit = 𝑂(|𝐸| 𝑢 |𝑓 ∗ |)
Pfadsuche z.B. per BFS oder DFS
(wobei 𝑓 ∗ maximaler Fluss
und Fluss um bis zu 1/𝑢 pro Iteration wächst)
(mit Verbesserung
nach Edmonds-Karp)
Algorithmen und Datenstrukturen | Marc Fischlin | SS 23 | 06 Graph Algorithms | 181
Ford-Fulkerson-Algorithmus: Beispiel (I)
auf dem
Ford-Fulkerson(G,s,t,c)
Weg
1 FOREACH e in E DO [Link]=0; Sub trohe
2 WHILE there is path p from s to t in 𝑮𝐟𝐥𝐨𝐰 DO
3 𝒄𝐟𝐥𝐨𝐰 𝒑 = 𝒎𝒊𝒏 𝒄𝐟𝐥𝐨𝐰 𝒖, 𝒗 𝒖, 𝒗 𝒊𝒏 𝒑 }
4 FOREACH e in p DO
5 IF e in E THEN
6 [Link]=[Link]+ 𝒄𝐟𝐥𝐨𝐰 𝒑
7 ELSE Restkapazitäts-
8 [Link]=[Link]- 𝒄𝐟𝐥𝐨𝐰 𝒑 graph
s
+4
0/10 +4 10
0/8 2 2 8 2 2
0/10 10
①
+4 0/4 4
s 0/4 0/6 t s 4 6 t
0/5 0/7 5 7
+4 2 2
0/2 𝒄𝒇𝒍𝒐𝒘 𝒑 =4 2
1 FOREACH e in E DO [Link]=0;
2 WHILE there is path p from s to t in 𝑮𝐟𝐥𝐨𝐰 DO
3 𝒄𝐟𝐥𝐨𝐰 𝒑 = 𝒎𝒊𝒏 𝒄𝐟𝐥𝐨𝐰 𝒖, 𝒗 𝒖, 𝒗 𝒊𝒏 𝒑 }
4 FOREACH e in p DO
5 IF e in E THEN
6 [Link]=[Link]+ 𝒄𝐟𝐥𝐨𝐰 𝒑
7 ELSE Restkapazitäts-
8 [Link]=[Link]- 𝒄𝐟𝐥𝐨𝐰 𝒑 graph
4/10 6
+2
0/8 2 2 8 2 2
4/10 4 6
-2 0/4 4 4
s 4/4 0/6 t s 1 4 t
6
0/7 4 7
4/5
2 +2 2
0/2 𝒄𝒇𝒍𝒐𝒘 𝒑 = 𝟐 2
+2
Algorithmen und Datenstrukturen | Marc Fischlin | SS 23 | 06 Graph Algorithms | 183
Ford-Fulkerson-Algorithmus: Beispiel (III)
Ford-Fulkerson(G,s,t,c)
1 FOREACH e in E DO [Link]=0;
2 WHILE there is path p from s to t in 𝑮𝐟𝐥𝐨𝐰 DO
3 𝒄𝐟𝐥𝐨𝐰 𝒑 = 𝒎𝒊𝒏 𝒄𝐟𝐥𝐨𝐰 𝒖, 𝒗 𝒖, 𝒗 𝒊𝒏 𝒑 }
4 FOREACH e in p DO
5 IF e in E THEN
6 [Link]=[Link]+ 𝒄𝐟𝐥𝐨𝐰 𝒑
7 ELSE Restkapazitäts-
8 [Link]=[Link]- 𝒄𝐟𝐥𝐨𝐰 𝒑 graph
+6 6
+6 4/10 +6
2/8 2 2 6 2 2
4/10 4 6
2
0/4 4 4
s 2/4 0/6 t s 1 2 2 t
6
5
2/7 4
4/5 2
2 2
2/2 𝒄𝒇𝒍𝒐𝒘 𝒑 = 𝟔 2
10/10 10
8/8 2 2 2 2
10/10 8
0/4 4 10
s 2/4 0/6 t s 1 2 2 t
6
5
2/7 4
4/5 2
2 2
2/2 2
10/10 10
8/8 2 2 2 2
10/10 8
0/4 4 10
s 2/4 0/6 t s 1 2 2 t
6
5
2/7 4
4/5 2
2 2
2/2 2
wobei
10/10
8/8 2 2
10/10 𝑐 𝑆, 𝑉 − 𝑆 = ∑ ∈ ∑ ∈ 𝑐(𝑢, 𝑣)
0/4
s 2/4 0/6 t für 𝑠 ∈ 𝑆 und 𝑡 ∈ 𝑉 − 𝑆 die
Kapazität eines Schnitts (𝑺, 𝑽 − 𝑺)
4/5 2/7 ist.
2
2/2
Käufer Verkäufer
2 2
bipartiter Graph:
Knotenmenge zerfällt in
2 2 zwei disjunkte Mengen,
so dass Kanten nur
zwischen den Mengen
2 2
2 2 Kapazität = 1
für jede Kante
2 2
Fluss=1 sagt,
s 2 2 t Kante aktiv
2 2
Wert des Flusses
gibt an, wie viele
aktive Kanten aus
2 2
s ausgehen bzw.
wie viele in t ankommen
A B
3
4
E
2
Algorithmen und Datenstrukturen | Marc Fischlin | SS 23 | 06 Graph Algorithms | 190