(nach Folien von Prof. Martin Dietzfelbinger) · 2012-07-04 · E ziente Algorithmen Graphdurchl...
Transcript of (nach Folien von Prof. Martin Dietzfelbinger) · 2012-07-04 · E ziente Algorithmen Graphdurchl...
Effiziente Algorithmen
Graphdurchlaufe
Vorlesender: Martin Aumuller(nach Folien von Prof. Martin Dietzfelbinger)
April/Mai 2012
FG KTuEA, TU Ilmenau Effiziente Algorithmen – Sommersemester 2012 1
Einleitung
Kapitel 2 Durchsuchen und Strukturanalyse von Graphen
Gerichteter Graph
1
2
3
4
57
8
9
106
(Ungerichteter) Graph
C
R
W
B
E
G
O
J
M
X
A
FG KTuEA, TU Ilmenau Effiziente Algorithmen – Sommersemester 2012 2
Einleitung
Erinnerung(http://www.tu-ilmenau.de/iti/lehre/fruehere-lehrveranstaltungen/lehre-ss2011/aud/, Kapitel 7)
Graphen, gerichtete Graphen (Digraphen)Grad, Ingrad, AusgradWege (gerichtet/ungerichtet), einfache WegeKreise (oder: Zyklen) (gerichtet/ungerichtet)azyklische Digraphenkreisfreie ungerichtete Graphen: (freie) Baume und Walder
FG KTuEA, TU Ilmenau Effiziente Algorithmen – Sommersemester 2012 5
Einleitung
Erinnerung(http://www.tu-ilmenau.de/iti/lehre/fruehere-lehrveranstaltungen/lehre-ss2011/aud/, Kapitel 7)
Zusammenhangende GraphenZusammenhangskomponentenGerichtete Baume und WalderDarstellung uber AdjazenzmatrixDarstellung uber Adjazenzlisten
(einfach/doppelt verkettet)Breitensuche (Breadth-First-Search)Starte in v0. Entdecke alle von v0 erreichbaren Knoten, ein
”Level“ nach
dem anderen, wobei Level ` aus den Knoten besteht, die von v0 den Abstand` haben. (Datenstruktur: Queue.)
FG KTuEA, TU Ilmenau Effiziente Algorithmen – Sommersemester 2012 6
Einfache Tiefensuche
2.1 Einfache Tiefensuche in Digraphen
1 2 3 4 5
6 7 8 9 10
4
2
1
2
3 2 2
12
2 3
1 111
1 1 2
Eingabeformat:Digraph G = (V ,E ), Knotenmenge V = {1, . . . , n} (o. B. d. A.),Adjazenzlisten- oder Adjazenzmatrixformat,aus v ausgehende Kanten sind (implizit) angeordnet.
Ziele:
Besuche alle Knoten und Kanten.Sammle Strukturinformation.
FG KTuEA, TU Ilmenau Effiziente Algorithmen – Sommersemester 2012 7
Einfache Tiefensuche
Tiefensuche (Depth-First-Search)
Zunachst: Gehe von Knoten v0 aus, finde alle auf Wegen von v0 auserreichbaren Knoten und Kanten.
Realisierung: Rekursive Prozedur”dfs(v)“:
•”Besuche“ Knoten v (Aktion an diesem Knoten).
• Dann betrachte die Nachbarn w1, . . . ,woutdeg(v) von v nacheinander,aber:Sobald neuer Knoten w
”entdeckt“ wird, starte sofort dfs(w). (Weitere
Nachbarn von v werden spater betrachtet.)
Vorwartsgehen hat Vorrang!
Effekt:
Die Folge der entdeckten Knoten geht immer so weit wie moglich”in die
Tiefe“.
FG KTuEA, TU Ilmenau Effiziente Algorithmen – Sommersemester 2012 8
Einfache Tiefensuche
Man muss verhindern, dass Knoten v mehrfach besucht wird.
Dazu:”Statusinformation“:
v neu – noch nie gesehen
v aktiv – dfs(v) gestartet, noch nicht beendet
v fertig – dfs(v) beendet
Status wird in einem Array status[1 . . n] gehalten –ein Eintrag pro Knoten.
Parallel zu (oder Teil von) Knotenarray nodes[1 . . n].
Initialisierung: Alle Knoten sind neu .
FG KTuEA, TU Ilmenau Effiziente Algorithmen – Sommersemester 2012 9
Einfache Tiefensuche
Einfachstversion (wird spater ausgebaut):
Knoten werden in der Reihenfolge der Entdeckung durchnummeriert:
dfs num[1 . . n]. Tiefensuch-Nummerierung.
Mitzahlen: in dfs count (globale Variable), mit 0 initialisiert.
dfs-visit(v):Aktion an v bei Entdeckung, anwendungsabhangig.
FG KTuEA, TU Ilmenau Effiziente Algorithmen – Sommersemester 2012 10
Einfache Tiefensuche
Prozedur dfs(v) (∗ Tiefensuche an v , rekursiv, darf nur
fur v mit status[v] = neu aufgerufen werden ∗)(1) dfs count++;(2) dfs num[v]← dfs count;(3) dfs-visit(v); (∗ Aktion an v bei Erstbesuch ∗)(4) status[v]← aktiv ;(5) fur jeden Nachfolger w von v (Adjazenzliste!) tue:
(6) if status[w] = neu (∗ w wird entdeckt! ∗) then(7) dfs(w);
(8) status[v]← fertig .
Tiefensuche von v0 aus:Initialisiere alle Knoten als
”neu “; setze dfs count← 0.
Rufe dfs(v0) auf.
FG KTuEA, TU Ilmenau Effiziente Algorithmen – Sommersemester 2012 11
Einfache Tiefensuche
1 2 3 4 5
6 7 8 9 10
4
2
1
2
3 2 2
12
2 3
1 111
1 1 2
Start von dfs(1),”Roter Weg“: (1).
FG KTuEA, TU Ilmenau Effiziente Algorithmen – Sommersemester 2012 12
Einfache Tiefensuche
1 2 3 4 5
6 7 8 9 10
4
2
1
2
3 2 2
12
2 3
1 111
1 1 2
Ende von dfs(3),”Roter Weg“: (1, 2).
FG KTuEA, TU Ilmenau Effiziente Algorithmen – Sommersemester 2012 12
Einfache Tiefensuche
1 2 3 4 5
6 7 8 9 10
4
2
1
2
3 2 2
12
2 3
1 111
1 1 2
Start von dfs(8),”Roter Weg“: (1, 2, 8).
FG KTuEA, TU Ilmenau Effiziente Algorithmen – Sommersemester 2012 12
Einfache Tiefensuche
1 2 3 4 5
6 7 8 9 10
4
2
1
2
3 2 2
12
2 3
1 111
1 1 2
Kante (8, 3) wird angesehen, Knoten 3 ist fertig .
FG KTuEA, TU Ilmenau Effiziente Algorithmen – Sommersemester 2012 12
Einfache Tiefensuche
1 2 3 4 5
6 7 8 9 10
4
2
1
2
3 2 2
12
2 3
1 111
1 1 2
Kante (8, 7) wird angesehen, Knoten 7 ist neu .
FG KTuEA, TU Ilmenau Effiziente Algorithmen – Sommersemester 2012 12
Einfache Tiefensuche
1 2 3 4 5
6 7 8 9 10
4
2
1
2
3 2 2
12
2 3
1 111
1 1 2
dfs(7) endet,”Roter Weg“: (1, 2, 8).
FG KTuEA, TU Ilmenau Effiziente Algorithmen – Sommersemester 2012 12
Einfache Tiefensuche
1 2 3 4 5
6 7 8 9 10
4
2
1
2
3 2 2
12
2 3
1 111
1 1 2
Erreichbare Knoten und Kanten, DFS-Baum zu Startknoten 1.
FG KTuEA, TU Ilmenau Effiziente Algorithmen – Sommersemester 2012 12
Einfache Tiefensuche
Rv0 := {v ∈ V | v0 v}. (Von v0 aus erreichbare Knoten.)
Ev0 := {(v ,w) ∈ E | v ∈ Rv0}. (Von v0 aus erreichbare Kanten.)
1 2 3 4 5
6 7 8 9 10
4
2
1
2
3 2 2
12
2 3
1 111
1 1 2
Satz 2.1.1
Bei Tiefensuche von v0 aus wird fur jeden Knoten v ∈ Rv0 dfs(v) (genaueinmal) aufgerufen, fur Knoten v /∈ Rv0 wird dfs(v) nicht aufgerufen. JedeKante (v ,w) ∈ Ev0 wird genau einmal betrachtet, andere Kanten nicht.
Anm.: Auch Breitensuche von v0 aus besucht genau diese Knoten/Kanten. .
FG KTuEA, TU Ilmenau Effiziente Algorithmen – Sommersemester 2012 13
Einfache Tiefensuche
Beweis: (1) Da Aufrufe nur entlang von Kanten von G erfolgen,kann dfs(v) nur aufgerufen werden, wenn v ∈ Rv0 gilt.
(2) Sobald dfs(v) aufgerufen wird, wird status[v] auf”aktiv“ gesetzt,
spater auf”fertig“, aber nie mehr zuruck auf
”neu“. Ein Aufruf erfolgt nur
fur neue Knoten.Daher: maximal ein Aufruf fur v .
(3) Sei (v0, v1, . . . , vt = v) ein Weg von v0 nach v .Annahme: Es gibt i > 0, fur das dfs(vi ) nicht aufgerufen wird.Betrachte das kleinste solche i . Dann wird dfs(vi−1) aufgerufen.Dabei wird die Kante (vi−1, vi ) untersucht und festgestellt, dass vi ”
neu“ist. Also wird dfs(vi ) aufgerufen, Widerspruch.
(4) Eine Kante (v ,w) ∈ Ev0 wird im Aufruf dfs(v) untersucht (und inkeinem anderen Aufruf). Kanten (v ,w) mit v /∈ Rv0 werden nie betrachtet.
�
FG KTuEA, TU Ilmenau Effiziente Algorithmen – Sommersemester 2012 14
Einfache Tiefensuche
Beobachtung 1:
Der Zeitaufwand fur die Bearbeitung eines Aufrufs dfs(v) ist (ohne dierekursiven Aufrufe) O(1) + O(outdeg(v)).
Der Zeitaufwand fur”dfs(v0)“ ist linear, namlich
O( ∑v∈Rv0
(1 + outdeg(v)))
= O(|Ev0 |).
(Beachte: |Rv0 | ≤ |Ev0 |+ 1.)
Der Zeitaufwand fur die Initialisierung ist O(n). – Also:
Mit Tiefensuche in G von v0 aus lassen sichin Zeit O(|V |+ |Ev0 |) die Mengen Rv0 und Ev0 ermitteln.
FG KTuEA, TU Ilmenau Effiziente Algorithmen – Sommersemester 2012 15
Einfache Tiefensuche
Definition 2.1.2
Die transitive Hulle eines Digraphen G ist der Graph TH(G) = (V ,E ∗)mit Kantenmenge
E∗ = {(v ,w) | v ,w ∈ V , v G w} =⋃v∈V
({v} × Rv ).
Mit Tiefensuche in G , gestartet von jedem Knoten nacheinander, lassensich in Zeit O(
∑v∈V |ERv |) = O(|V | · |E |) alle Mengen Rv , v ∈ V ,
ermitteln.
(Nach Aufruf dfs(v) kann man mit Hilfe der Liste fur Rv in Zeit O(|Rv |)das status-Array wieder auf
”neu“ setzen.)
D. h.: Mit wiederholter Tiefensuche (oder Breitensuche) kann man TH(G )in Zeit O(
∑v∈V |ERv |) = O(|V | · |E |) berechnen.
FG KTuEA, TU Ilmenau Effiziente Algorithmen – Sommersemester 2012 16
Einfache Tiefensuche
6 5 4
3211 2 3 4 5
6 7 8 9 10
4
2
1
2
3 2 2
12
2 3
1 111
1 1 2
Beobachtung 2:
Jeder Knoten v ∈ Rv0 − {v0} wird von einem eindeutig bestimmtenKnoten w aus
”entdeckt“
(Inspektion der Kante (w , v) zeigt v als neu );dieses w nennen wir p(v), den Vorganger von v .
Kanten (grun) von p(v) zu v :”Entdeckungsrichtung“.
Aufruf”dfs(v)“ beginnt nach und endet vor Aufruf
”dfs(p(v))“.
FG KTuEA, TU Ilmenau Effiziente Algorithmen – Sommersemester 2012 17
Einfache Tiefensuche
6 5 4
3211 2 3 4 5
6 7 8 9 10
4
2
1
2
3 2 2
12
2 3
1 111
1 1 2
Die Kanten (p(v), v) bilden einen (gerichteten) Baum mit Wurzel v0
und Knotenmenge Rv0 , den
Tiefensuch-Baum Tdfs(v0).
Weg im Tiefensuch-Baum entspricht indirekter Aufrufbeziehung.
Die DFS-Nummern (rot) zahlen die Knoten inPraorder- Reihenfolge auf. (Die Anordnung ist durch die Reihenfolge derNachfolger in den Adjazenzlisten vorgegeben.)
FG KTuEA, TU Ilmenau Effiziente Algorithmen – Sommersemester 2012 18
Einfache Tiefensuche
1 2 3 4 5
6 7 8 9 10
4
2
1
2
3 2 2
12
2 3
1 111
1 1 2
Zu jedem Zeitpunkt bilden die aktiven Knoten einen Weg (den”
rotenWeg“) im Tiefensuch-Baum, Startpunkt ist v0, Endpunkt ist der Knoten,in dessen
”dfs(v)“-Aufruf eben gearbeitet wird (hier: Knoten 7).
FG KTuEA, TU Ilmenau Effiziente Algorithmen – Sommersemester 2012 19
Einfache Tiefensuche
• Wie entscheidet sich, ob w in Tdfs(v0) Nachfahr von v ist?
• Wann wird dfs(w) aufgerufen, wahrend v aktiv ist?
Satz 2.1.3 (”Satz vom weißen Weg“)
w ist ein Nachfahr von v im Tiefensuchbaum Tdfs(v0)⇔in dem Moment, in dem dfs(v) aufgerufen wird, existiert ein Wegv = u0, u1, u2, . . . , ut = w von v nach waus Knoten, die alle neu (
”weiß“) sind.
FG KTuEA, TU Ilmenau Effiziente Algorithmen – Sommersemester 2012 20
Einfache Tiefensuche
Beispiel: dfs(2) startet.
1 2 3 4 5
6 7 8 9 10
4
2
1
2
3 2 2
12
2 3
1 111
1 1 2
Knoten 6 ist von 2 aus erreichbar, aber nicht auf einem
”weißen Weg“⇒ Knoten 6 sitzt im DFS-Baum nicht unter 2.
Knoten 3, 7, 8 sind auf”weißen Wegen“ erreichbar
⇒ diese Knoten sitzen im DFS-Baum unter 2.
FG KTuEA, TU Ilmenau Effiziente Algorithmen – Sommersemester 2012 21
Einfache Tiefensuche
1 2 3 4 5
6 7 8 9 10
4
2
1
2
3 2 2
12
2 3
1 111
1 1 2
Beweis von Satz 2.1.3:”⇒“:
Sei w in Tdfs(v0) Nachfahr von v .
Wir nehmen den Weg, der in Tdfs(v0) von v nach w fuhrt:
v = u0, u1, u2, . . . , ut = w . (Beispiel: (2, 8, 7).)
Nach Beobachtung 2 wird erst dfs(u0) aufgerufen, dann dfs(u1), danndfs(u2), usw.;also sind im Moment des Aufrufs dfs(v)
alle Knoten v = u0, u1, u2, . . . , ut = w noch neu .
FG KTuEA, TU Ilmenau Effiziente Algorithmen – Sommersemester 2012 22
Einfache Tiefensuche
Beweis von Satz 2.1.3:”⇐“:
Durch Induktion uber t ≥ 0 zeigen wir:
IBt: Wenn beim Aufruf dfs(v)v = u0, u1, u2, . . . , ut = w ein Weg aus neuen (
”weißen“) Knoten ist, dann
beginnt dfs(w), bevor dfs(v) endet.
I.A.: t = 0: Trivial, weil w = v .
I.Schritt: Sei t > 0 und v = u0, u1, u2, . . . , ut = w ein Weg wie angegeben.
Nach IBt−1 wird dfs(ut−1) aufgerufen, bevor dfs(v) endet. Naturlich wirddfs(ut−1) nach dfs(v) aufgerufen (ut−1 ”
weiß“).
Wahrend der Abarbeitung von dfs(ut−1) wird Nachbar w von ut−1 betrachtet.
1. Fall: w ist aktiv oder fertig. Dann wurde dfs(w) vorher aufgerufen.
2. Fall: w ist neu. Dann wird dfs(w) jetzt aufgerufen.
In beiden Fallen beginnt dfs(w) vor dem Ende von dfs(ut−1), also vor dem Endevon dfs(v).
FG KTuEA, TU Ilmenau Effiziente Algorithmen – Sommersemester 2012 23
Einfache Tiefensuche
Beweis von Satz 2.1.3:”⇐“ (Forts.):
Nun sei v = u0, u1, u2, . . . , ut = w ein Weg aus Knoten, die beim Aufrufdfs(v) alle neu sind.
Nach IBt beginnt dfs(w) vor dem Ende von dfs(v), also ist t = 0 oderdfs(w) wird (indirekt) aus dfs(v) heraus aufgerufen.
Daraus: Die Folge w , p(w), p(p(w)), p(p(p(w))), . . ., mit derVorgangerbeziehung aus Beobachtung 2, erreicht v .
Umgedreht gelesen, ist dies ein Weg von v nach w in Tdfs(v0).
�
FG KTuEA, TU Ilmenau Effiziente Algorithmen – Sommersemester 2012 24
Einfache Tiefensuche
Globale Tiefensuche in Digraphen: Alle Knoten besuchen.
Algorithmus DFS(G ) (∗ Tiefensuche in G = (V ,E ) ∗)(1) dfs count ← 0;
(2) for v from 1 to n do status[v]← neu ;(3) for v from 1 to n do
(4) if status[v] = neu then(5) dfs(v); (∗ starte Tiefensuche von v aus ∗)
Zu Zeilen (1)/(5): dfs count wird weitergezahlt.
Zu Zeilen (2), (4):Die status[v]-Werte werden von den dfs-Aufrufen in Zeile (5) verandert;sie haben also beim Wieder-Lesen in der zweiten Schleife nicht unbedingtimmer noch den Initialisierungs-Wert neu.
FG KTuEA, TU Ilmenau Effiziente Algorithmen – Sommersemester 2012 25
Einfache Tiefensuche
6 5 4
3211 2 3 4 5
6 7 8 9 10
4
2
1
2
3 2 2
12
2 3
1 111
1 1 2
Ist Knoten 4 neu ? Ja.
Ist Knoten 10 neu ?
Fertig.
FG KTuEA, TU Ilmenau Effiziente Algorithmen – Sommersemester 2012 26
Einfache Tiefensuche
8
7
6 5 4
3211 2 3 4 5
6 7 8 9 10
4
2
1
2
3 2 2
12
2 3
1 111
1 1 2
”Roter Weg“: leer.
Ist Knoten 10 neu ?
Fertig.
FG KTuEA, TU Ilmenau Effiziente Algorithmen – Sommersemester 2012 26
Einfache Tiefensuche
9
8
7
6 5 4
3211 2 3 4 5
6 7 8 9 10
4
2
1
2
3 2 2
12
2 3
1 111
1 1 2
”Roter Weg“: (5)
Ist Knoten 10 neu ?
Fertig.
FG KTuEA, TU Ilmenau Effiziente Algorithmen – Sommersemester 2012 26
Einfache Tiefensuche
10
9
8
7
6 5 4
3211 2 3 4 5
6 7 8 9 10
4
2
1
2
3 2 2
12
2 3
1 111
1 1 2
Ist Knoten 10 neu ?
Fertig.
FG KTuEA, TU Ilmenau Effiziente Algorithmen – Sommersemester 2012 26
Einfache Tiefensuche
DFS(G ) erzwingt, dass fur jeden Knoten v in G irgendwann einmaldfs(v) aufgerufen wird. (Hochstens einmal: wie vorher.)
Daher werden auch alle Kanten, die aus v herausfuhren, angesehen.
Gesamt-(Zeit-)Aufwand: O(1 + outdeg(v)) fur Knoten v . Insgesamt:
O(∑v∈V
(1 + outdeg(v)))
= O(|V |+ |E |) = O(n + m).
Satz 2.1.4
Der Zeitaufwand von DFS(G ) ist O(|V |+ |E |).
(Sogar: Θ(|V |+ |E |), da jeder Knoten und jede Kante betrachtet wird.)
FG KTuEA, TU Ilmenau Effiziente Algorithmen – Sommersemester 2012 27
Einfache Tiefensuche
Bemerkung: Bei DFS entstehen mehrere Baume, die zusammen den
”Tiefensuchwald“ bilden.
(Kante (w , v) entspricht dem Aufruf dfs(v) direkt aus dfs(w).)
Vorsicht: Wenn ein Baum im Tiefensuchwald Wurzel v hat, so ist nichtgesagt, dass dieser Baum alle von v aus erreichbaren Knoten enthalt.(Dies gilt nur fur den ersten der Baume.)
10
9
8
7
6 5 4
3211 2 3 4 5
6 7 8 9 10
4
2
1
2
3 2 2
12
2 3
1 111
1 1 2
Beispiel: Es gilt 5 1, aber 1 ist nicht im Baum unter 5.FG KTuEA, TU Ilmenau Effiziente Algorithmen – Sommersemester 2012 28
Einfache Tiefensuche
Satz 2.1.3, der”Satz vom weißen Weg“, gilt auch fur den Tiefensuchwald,
mit identischem Beweis.
Fur v ∈ V = {1, . . . , n}: Wv := {u ∈ V | ∃w ≤ v : w u}.
Satz 2.1.5
v wird Wurzel eines Baums im Tiefensuch-Wald ⇔ v /∈Wv−1.
10
9
8
7
6 5 4
3211 2 3 4 5
6 7 8 9 10
4
2
1
2
3 2 2
12
2 3
1 111
1 1 2
In diesem Fall gilt: Der Baum mit Wurzel v hat die KnotenmengeWv −Wv−1 (erreichbar von v aus, aber von keinem vorherigen Knoten).
FG KTuEA, TU Ilmenau Effiziente Algorithmen – Sommersemester 2012 29
Einfache Tiefensuche
Satz 2.1.5
v wird Wurzel eines Baums im Tiefensuch-Wald ⇔ v /∈Wv−1.
Beweis:
”⇐“: Sei v /∈Wv−1. Nach Satz 2.1.1 kann v von keinem Aufruf dfs(w)
mit w < v erreicht werden, also ergibt der Test in Zeile (4), dass v neuist, und der Aufruf dfs(v) erfolgt.
FG KTuEA, TU Ilmenau Effiziente Algorithmen – Sommersemester 2012 30
Einfache Tiefensuche
Satz 2.1.5
v wird Wurzel eines Baums im Tiefensuch-Wald ⇔ v /∈Wv−1.
”⇒“: Sei v ∈Wv−1, also v von einem w < v aus erreichbar.
Wahle w ∈ {1, . . . , n} minimal mit w v .
Wahle einfachen Weg w = u0, . . . , ut = v .
w minimal ⇒ keiner der Knoten u0, . . . , ut ist von einem Knoten x < waus erreichbar.
Insbesondere gilt w /∈Ww−1; in”⇐“ haben wir gezeigt, dass dfs(w) aus
DFS(G ) aufgerufen wird.
Im Moment dieses Aufrufs sind alle Knoten auf dem Wegw = u0, . . . , ut = v neu .
Satz 2.1.3. (Satz vom weißen Weg) sagt nun: v wird Nachfahr von w imTiefensuch-Wald. Also ist v keine Wurzel. �
FG KTuEA, TU Ilmenau Effiziente Algorithmen – Sommersemester 2012 31
Tiefensuche mit Kantenklassifizierung
2.2 Volle Tiefensuche in Digraphen
Wir bauen dfs(v) und DFS(G ) aus, so dass die Kanten (v ,w) von G invier Klassen T , B, F , C eingeteilt werden:
T : Baumkanten – die Kanten des Tiefensuchwaldes;Kriterium: w ist neu .
B: Ruckwartskanten – (v ,w) ist Ruckwartskante,wenn w Vorfahr von v im Tiefensuchwald ist;Kriterium: w ist aktiv .
FG KTuEA, TU Ilmenau Effiziente Algorithmen – Sommersemester 2012 32
Tiefensuche mit Kantenklassifizierung
F : Vorwartskanten – (v ,w) ist Vorwartskante,wenn w Nachfahr von v im Tiefensuchwald ist;Kriterium: w ist fertig und dfs num(v) < dfs num(w).C : Querkanten – (v ,w) ist Querkante, wenn der gesamteUnterbaum von w schon fertig abgearbeitet ist, wenn dfs(v)aufgerufen wird (d.h.: w liegt im Tiefensuchwald gemaß Praorder-und gemaß Postorder-Reihenfolge vor v);Kriterium: w ist fertig und dfs num(v) > dfs num(w).
Zudem nummerieren wir die Knoten v ∈ V in der Reihenfolge durch, inder die dfs(v)-Aufrufe beendet werden.
Diese Nummern heißen f(in)-Nummern: f num(v).Der Wertebereich der f-Nummern ist {1, 2, . . . , |V |}.
FG KTuEA, TU Ilmenau Effiziente Algorithmen – Sommersemester 2012 33
Tiefensuche mit Kantenklassifizierung
Prozedur dfs(v) (∗”volle“ Tiefensuche in v , nur fur v neu erlaubt ∗)
(1) dfs count++;(2) dfs num[v]← dfs count;(3) dfs-visit(v); (∗ Aktion an v bei Erstbesuch ∗)(4) status[v]← aktiv ;(5) fur jeden Nachfolger w von v (Adjazenzliste!) tue:(6) 1. Fall: status[w] = neu : T ← T ∪ {(v , w)}; dfs(w);
(7) 2. Fall: status[w] = aktiv : B ← B ∪ {(v , w)};(8) 3. Fall: status[w] = fertig ∧ dfs num[v] < dfs num[w]:
F ← F ∪ {(v , w)};(9) 4. Fall: status[w] = fertig ∧ dfs num[v] > dfs num[w]:
C ← C ∪ {(v , w)};(10) f count++;(11) f num[v]← f count;(12) fin-visit(v); (∗ Aktion an v bei letztem Besuch ∗)(13) status[v]← fertig .
FG KTuEA, TU Ilmenau Effiziente Algorithmen – Sommersemester 2012 34
Tiefensuche mit Kantenklassifizierung
Initialisierung: dfs count← 0; f count← 0.Alle Knoten sind
”neu“; Mengen T ,B,F ,C sind leer.
Tiefensuche von v0 aus (”dfs(v0)“) entdeckt Rv0 .
Tiefensuche fur den ganzen Graphen: DFS(G ) wie vorher, nur mit der
”voll ausgebauten“ dfs-Prozedur, und der Initialisierung von f count undT ,B,F ,C .
Algorithmus DFS(G ) (∗ Tiefensuche in G = (V ,E ), voll ausgebaut ∗)
(1) dfs count ← 0;(2) f count ← 0;(3) T ← ∅; B ← ∅; F ← ∅; C ← ∅;(3) for v from 1 to n do status[v]← neu ;(4) for v from 1 to n do(5) if status[v] = neu then(6) dfs(v); (∗ starte Tiefensuche von v aus ∗)
FG KTuEA, TU Ilmenau Effiziente Algorithmen – Sommersemester 2012 35
Tiefensuche mit Kantenklassifizierung
1
4 /
/3/2/11 2 3 4 5
6 7 8 9 10
4
2
1
2
3 2 2
12
2 3
1 111
1 1 2
dfs(8) startet, dfs-Nummer 4, (2, 8) wird Baumkante.
FG KTuEA, TU Ilmenau Effiziente Algorithmen – Sommersemester 2012 36
Tiefensuche mit Kantenklassifizierung
1
/5 4 /
/3/2/11 2 3 4 5
6 7 8 9 10
4
2
1
2
3 2 2
12
2 3
1 111
1 1 2
(7, 3) wird Querkante, weil 3 fertig ist und 5 > 3 gilt.
FG KTuEA, TU Ilmenau Effiziente Algorithmen – Sommersemester 2012 36
Tiefensuche mit Kantenklassifizierung
1
/5 4 /
/3/2/11 2 3 4 5
6 7 8 9 10
4
2
1
2
3 2 2
12
2 3
1 111
1 1 2
(7, 1) wird Ruckwartskante, weil 1 aktiv ist.
FG KTuEA, TU Ilmenau Effiziente Algorithmen – Sommersemester 2012 36
Tiefensuche mit Kantenklassifizierung
2
1
/5 4 /
/3/2/11 2 3 4 5
6 7 8 9 10
4
2
1
2
3 2 2
12
2 3
1 111
1 1 2
dfs(7) endet, f-Nummer 2.
FG KTuEA, TU Ilmenau Effiziente Algorithmen – Sommersemester 2012 36
Tiefensuche mit Kantenklassifizierung
32
1
/5 4 /
/3/2/11 2 3 4 5
6 7 8 9 10
4
2
1
2
3 2 2
12
2 3
1 111
1 1 2
(2, 7) wird Vorwartskante, weil 7 fertig ist und 2 < 5 gilt.
FG KTuEA, TU Ilmenau Effiziente Algorithmen – Sommersemester 2012 36
Tiefensuche mit Kantenklassifizierung
10
9
8
7
6
5
4
32
1
/10
9 /
8 /
7 /
6 / /5 4 /
/3/2/11 2 3 4 5
6 7 8 9 10
4
2
1
2
3 2 2
12
2 3
1 111
1 1 2
Klar: Alle Aussagen fur die einfache dfs-Prozedur bleiben gultig.
FG KTuEA, TU Ilmenau Effiziente Algorithmen – Sommersemester 2012 36
Tiefensuche mit Kantenklassifizierung
10
9
8
7
6
5
4
32
1
/10
9 /
8 /
7 /
6 / /5 4 /
/3/2/11 2 3 4 5
6 7 8 9 10
4
2
1
2
3 2 2
12
2 3
1 111
1 1 2
Beobachtung 1: Jede Kante (v ,w) wird genau einmal betrachtet unddaher genau in eine der Mengen T , B, F und C eingeordnet.
Beobachtung 2: Die dfs-Nummern entsprechen einemPraorder-Durchlauf, die f-Nummern einem Postorder-Durchlauf durchdie Baume des Tiefensuch-Waldes.
FG KTuEA, TU Ilmenau Effiziente Algorithmen – Sommersemester 2012 37
Tiefensuche mit Kantenklassifizierung
Beobachtung 3: Wenn dfs(w) nach dfs(v) beginnt und vor dfs(v) endet,also dfs(w) (indirekt) von dfs(v) aus aufgerufen wird, dann gilt:
(a) dfs num[v] < dfs num[w] und f num[v] > f num[w];
(b) v ist Vorfahr von w im Tiefensuch-Wald.
Konsequenz: Die Vorfahr-Nachfahr-Relation im Tiefensuch-Wald lasstsich in Zeit O(1) testen, wenn die dfs- und die f-Nummern bekannt sind.
FG KTuEA, TU Ilmenau Effiziente Algorithmen – Sommersemester 2012 38
Tiefensuche mit Kantenklassifizierung
Satz 2.2.1
Der Algorithmus DFS(G ) klassifiziert die Kanten korrekt.
Beweis: Sei (v ,w) eine beliebige Kante in G .
1. Fall: dfs(w) wird direkt aus dfs(v) aufgerufen. – Dann ist (v ,w)Baumkante und wird richtig als T klassifiziert.
2. Fall: Die Untersuchung der Kante (v ,w) in dfs(v) ergibt, dass w aktivist.
Dann liegt w auf dem roten Weg von der Wurzel des Tiefensuchbaums zuv , ist also Vorfahr von v (oder gleich v – Schleifen sind nicht verboten).
Daher ist (v ,w) Ruckwartskante und wird richtig als B klassifiziert.
FG KTuEA, TU Ilmenau Effiziente Algorithmen – Sommersemester 2012 39
Tiefensuche mit Kantenklassifizierung
3. Fall: Die Untersuchung der Kante (v ,w) in dfs(v) ergibt, dass wfertig und dfs num[v] < dfs num[w] ist. –
Weil dfs(v) noch aktiv ist, wird f num[v] > f num[w]. Also ist nachBeobachtung 3 w Nachfahr von v im Tiefensuchwald, also ist (v ,w)Vorwartskante und wird richtig als F klassifiziert.
4. Fall: Die Untersuchung der Kante (v ,w) in dfs(v) ergibt, dass wfertig und dfs num[v] > dfs num[w] ist. –
Dann war die Untersuchung von w und all seinen Nachfahren im Waldabgeschlossen, bevor dfs(v) begonnen wird. Daher ist (v ,w) Querkanteund wird richtig als C klassifiziert.
FG KTuEA, TU Ilmenau Effiziente Algorithmen – Sommersemester 2012 40
Kreisfreiheitstest und topologische Sortierung Finden von Kreisen
2.3. Kreisfreiheitstest und topologische Sortierung
Ob ein gerichteter Graph einen Kreis enthalt, kann man nachDurchfuhrung einer Tiefensuche daran ablesen, ob es Ruckwartskantengibt oder nicht.
Satz 2.3.1
(a) Nach Aufruf von DFS(G ) gilt:G enthalt einen Kreis ⇔ B 6= ∅.
(b) Nach Aufruf von dfs(v0) gilt: Der von v0 aus erreichbare Teil(Rv0 ,Ev0) von G enthalt einen Kreis ⇔ B 6= ∅.
FG KTuEA, TU Ilmenau Effiziente Algorithmen – Sommersemester 2012 41
Kreisfreiheitstest und topologische Sortierung Finden von Kreisen
Beweis des Satzes (a): ((b) geht genauso.)
”⇐“: Wenn DFS(G ) eine B-Kante (v ,w) findet, dann ist in diesem
Moment v der vorderste Knoten des roten Weges, und w liegt irgendwoauf dem roten Weg. Also gibt es in G einen Weg von w nach v ausBaumkanten. Zusammen mit der Kante (v ,w) ergibt sich ein Kreis.
Spezialfall: v = w , t = 0: Schleife. Wird als Kreis erkannt.
Beispiel:
1
/5 4 /
/3/2/11 2 3 4 5
6 7 8 9 10
4
2
1
2
3 2 2
12
2 3
1 111
1 1 2
Roter Weg: (1, 2, 8, 7); Ruckwartskante (7, 1) schließt den Kreis.
FG KTuEA, TU Ilmenau Effiziente Algorithmen – Sommersemester 2012 42
Kreisfreiheitstest und topologische Sortierung Finden von Kreisen
Beweis des Satzes (a):”⇒“: Nun sei B = ∅.
Fur eine Kante (v ,w) gibt es dann nur noch drei Falle:
1. Fall: (v ,w) ist Baumkante. –Dann ist f num[v] > f num[w].
2./3. Fall: (v ,w) ist Vorwartskante oder Querkante. –Dann ist w
”fertig“, wahrend an v noch gearbeitet wird, also ist wieder
f num[v] > f num[w].
Fur jede Kante (v ,w) in E ist die f-Nummer an v großer als die an w .
Wenn u0, . . . , ut ein Weg in G der Lange t ≥ 1 ist, so nehmen entlangdieses Weges die f-Nummern strikt ab.
Daher kann auf keinen Fall u0 = ut sein.
Also enthalt G keinen Kreis. �
FG KTuEA, TU Ilmenau Effiziente Algorithmen – Sommersemester 2012 43
Kreisfreiheitstest und topologische Sortierung Finden von Kreisen
Beispiel:
Ein (azyklischer) Digraph mit f-Nummern aus DFS(G ):
10
9
8
7
6
5
4
32
1
9876
54321
10
Wie im Beweis von 2.3.1 benutzt:Die f-Nummern fallen entlang jeder Kante!
FG KTuEA, TU Ilmenau Effiziente Algorithmen – Sommersemester 2012 44
Kreisfreiheitstest und topologische Sortierung Topologische Sortierung
Definition 2.3.2
Ein gerichteter Graph (Digraph) ohne Kreise heißt eingerichteter azyklischer Graph (
”directed acyclic graph“ – dag).
Wollen: Knoten in einem azyklischen Digraphen so anordnen, dass alleKanten
”von links nach rechts“ laufen.
Definition 2.3.4
Sei G = (V ,E ) ein azyklischer Digraph.Eine topologische Sortierung (oder topologische Anordnung) der Knotenin V ist eine Bijektion π : V → {1, . . . , n}, so dass fur alle Kanten(v ,w) ∈ E die Beziehung π(v) < π(w) gilt.
Man setzt Knoten v an Position π(v); dann laufen alle Kanten”von links nach
rechts“.
FG KTuEA, TU Ilmenau Effiziente Algorithmen – Sommersemester 2012 45
Kreisfreiheitstest und topologische Sortierung Topologische Sortierung
10
9
8
7
6
5
4
32
1
9876
54321
10
12310 9 8 7 6 5 4
37826194105
Derselbe Graph, linear angeordnet. – Permutation π dazu:
v 1 2 3 4 5 6 7 8 9 10π(v) 5 7 10 3 1 6 9 8 4 2
FG KTuEA, TU Ilmenau Effiziente Algorithmen – Sommersemester 2012 46
Kreisfreiheitstest und topologische Sortierung Topologische Sortierung
DFS(G ) findet unmittelbar eine topologische Sortierung!
(Naturlich nur in azyklischen Digraphen.)
Idee: Wir haben oben gesehen, dass die f-Nummern entlang jeder Kante(v ,w) strikt fallen; außerdem sind die f-Nummern eine Bijektion.
Definiere: π(v) := (n + 1)− f num(v).
Laufzeit/Kosten zur Ermittlung einer topologischen Sortierung:O(|V |+ |E |), linear.
Satz 2.3.4
DFS(G ) (in der ausfuhrlichen Version) testet Digraphen auf Azyklizitatund findet gegebenenfalls eine topologische Sortierung von G , in ZeitO(|V |+ |E |).
FG KTuEA, TU Ilmenau Effiziente Algorithmen – Sommersemester 2012 47
Kreisfreiheitstest und topologische Sortierung Anwendungen
Anwendung 1:
V : Menge von Tasks (fur einen Computer, fur eine Maschine).
E ⊆ V × V : Zeitliche Abhangigkeiten.
(v ,w) ∈ E heißt: Task v muss beendet sein, bevor Task w beginnt.
Der resultierende Graph G = (V ,E ) sollte azyklisch sein, sonst . . .Aufgabe nicht durchfuhrbar!
Topologische Sortierung: Eine mogliche Ausfuhrungsreihenfolge fur dieTasks auf der Maschine.
Bei Parallelverarbeitung:”Scheduling“ ist eine viel komplexere Aufgabe!
FG KTuEA, TU Ilmenau Effiziente Algorithmen – Sommersemester 2012 48
Kreisfreiheitstest und topologische Sortierung Anwendungen
Anwendung 2:
V : Menge von Tasks (fur einen Computer, fur eine Maschine), mitLaufzeiten c(v), fur v ∈ V .
E ⊆ V × V : Zeitliche Abhangigkeiten wie vorher.
Es stehen genugend Maschinen zur Verfugung, um beliebig viele Tasksparallel auszufuhren.
”Kritischer Pfad“: Folge v0, v1, . . . , vr von Tasks mit
(v0, v1), . . . , (vr−1, vr ) ∈ E undc(v0) + c(v1) + . . .+ c(vr ) maximal.
Man kann uberlegen:Ein “kritischer Pfad“ bestimmt die minimal moglicheGesamt-Ausfuhrungszeit.
Aufgabe: Bestimme kritischen Pfad, in Zeit O(|V |+ |E |).
FG KTuEA, TU Ilmenau Effiziente Algorithmen – Sommersemester 2012 49
Kreisfreiheitstest und topologische Sortierung Anwendungen
Losung:
Ermittle topologische Sortierung von (V ,E ).
”O.B.d.A.“ gilt (v ,w) ∈ E ⇒ v < w . (Umbenennen!)
Finde iterativ fur v = 1, . . . , n den fruhesten Beendigungszeitpunkt t(v) undVorganger pkr(v) auf einem kritischem Pfad in {1, . . . , v}.pkr(1) existiert nicht; t(1) = c(1).
I.V.: t(1), . . . , t(v − 1) schon ermittelt.
Schritt v:
t(v) :=
{c(v) + max{t(w) | (w , v) ∈ E} , falls eine Kante (w , v) existiert,c(v) , sonst.
Vorganger pkr(v): Ein w mit (w , v) ∈ E und maximalem t(w), wenn es einesolche Kante gibt, undefiniert, falls nicht.
Ausgabe: v mit maximalem t(v) und die Folge v , pkr(v), pkr(pkr(v)), . . . bis zumersten Knoten w mit undefiniertem pkr(w).
FG KTuEA, TU Ilmenau Effiziente Algorithmen – Sommersemester 2012 50
Starke Zusammenhangskomponenten Einleitung
2.4 Starke Zusammenhangskomponenten in Digraphen
Definition 2.4.1
Zwei Knoten v und w in einem Digraphen G heißen aquivalent, wennv w und w v gilt. Notation: v ! w .
Es gilt:
(a) Die so definierte Relation ist reflexiv, transitiv, und symmetrisch, alsoeine Aquivalenzrelation.
(b) Zwei Knoten v und w sind aquivalent genau dann wenn sie identischsind oder es in G einen (gerichteten) Kreis gibt, auf dem beide Knotenliegen.
FG KTuEA, TU Ilmenau Effiziente Algorithmen – Sommersemester 2012 51
Starke Zusammenhangskomponenten Einleitung
Definition 2.4.2
Die Aquivalenzklassen zur Relation ! heißen starkeZusammenhangskomponenten von G .
Beispiel: 5 starke Zusammenhangskomponenten
14 13
101112
9 8 7 6
12345
FG KTuEA, TU Ilmenau Effiziente Algorithmen – Sommersemester 2012 52
Starke Zusammenhangskomponenten Einleitung
Definition 2.4.2
Die Aquivalenzklassen zur Relation ! heißen starkeZusammenhangskomponenten von G .
Beispiel: 5 starke Zusammenhangskomponenten, 2 DFS-Baume.
14 13
101112
9 8 7 6
12345
FG KTuEA, TU Ilmenau Effiziente Algorithmen – Sommersemester 2012 52
Starke Zusammenhangskomponenten Einleitung
Lemma 2.4.3
Sei C ⊆ V eine starke Zusammenhangskomponente (s.Z.K.). Dann gilt:Wenn DFS(G ) ausgefuhrt wird, dann liegen die Knoten von C alle ineinem Tiefensuchbaum.
M.a.W.: Jeder Tiefensuchbaum ist selbst starke Z.K. oder lasst sich(disjunkt) in mehrere starke Z.K.n zerlegen.
Beweis: Es sei vC der erste Knoten v ∈ C , fur den dfs(v) aufgerufen wird.Sei v ∈ C beliebig. Dann ist v von vC aus auf einem Weg in G erreichbar.
Behauptung: Wenn vC = v0, v1, . . . , vt = v ein solcher Weg ist, dannliegen alle Knoten vi des Weges sogar in C.
(Beweis hierfur: Weil C s.Z.K. ist, gilt auch v vC . Zusammen mitvC vi und vi v ergibt sich vi ! vC , also vi ∈ C .)
FG KTuEA, TU Ilmenau Effiziente Algorithmen – Sommersemester 2012 53
Starke Zusammenhangskomponenten Einleitung
Zu dem Zeitpunkt, zu dem dfs(vC ) aufgerufen wird, sind die Knotenv0, v1, . . . , vt = v alle noch neu (nach Wahl von v0 = vC ).
⇒ (nach Satz 2.1.3, dem”Satz vom weißen Weg“)
v wird Nachfahr von vC im Tiefensuchbaum. �
NB: Es folgt: vC hat in C (die kleinste dfs-Nummer und)die großte f-Nummer.
FG KTuEA, TU Ilmenau Effiziente Algorithmen – Sommersemester 2012 54
Starke Zusammenhangskomponenten Einleitung
Um mit Tiefensuche die starken Zusammenhangskomponenten zu finden,muss man verhindern, dass in einem Baum mehrere solche Komponentensitzen (wie im Bild oben).
Trick 1: Fuhre DFS im”Umkehrgraphen“ GR durch, der durch Umkehren
aller Kanten in G entsteht.
14 13
101112
9 8 7 6
12345
G im Original.
FG KTuEA, TU Ilmenau Effiziente Algorithmen – Sommersemester 2012 55
Starke Zusammenhangskomponenten Einleitung
Um mit Tiefensuche die starken Zusammenhangskomponenten zu finden,muss man verhindern, dass in einem Baum mehrere solche Komponentensitzen (wie im Bild oben).
Trick 1: Fuhre DFS im”Umkehrgraphen“ GR durch, der durch Umkehren
aller Kanten in G entsteht.
14 13
101112
9 8 7 6
12345
Umkehrung GR von G .
FG KTuEA, TU Ilmenau Effiziente Algorithmen – Sommersemester 2012 55
Starke Zusammenhangskomponenten Einleitung
Beobachtung: GR hat dieselben starken Zusammenhangskomponentenwie G .
(Die Kreise in den beiden Graphen sind dieselben, nur mit umgekehrterDurchlaufreihenfolge.)
14 13
101112
9 8 7 6
12345
FG KTuEA, TU Ilmenau Effiziente Algorithmen – Sommersemester 2012 56
Starke Zusammenhangskomponenten Einleitung
Trick 2: Verwende f-Nummern der ersten DFS, um die Reihenfolge derKnoten in der Hauptschleife der zweiten DFS (in GR) zu bestimmen.
12
10 9
2
3
1
54147
8
6
13
11
14 13
101112
9 8 7 6
12345
Graph G mit starken Zsh.-Komponenten, Tiefensuchwald und f-Nummernaus dem ersten DFS-Aufruf.
FG KTuEA, TU Ilmenau Effiziente Algorithmen – Sommersemester 2012 57
Starke Zusammenhangskomponenten Einleitung
13
6
8
7 14 4 5
1
3
2
910
12 11
13
101112
9 8 7 6
12345
14
Graph GR mit starken Zsh.-Komponenten und f-Nummern fur G .
Fuhre DFS in GR durch, untersuche dabei Knoten gemaß fallendenf-Nummern auf Eigenschaft
”neu“.
Im Beispiel: Von 3 (14) aus wird eine s.Z.K. erreicht, von 13 (9) aus dienachste, von (1) (5) aus die nachste, von (2) (4) aus die nachste, von 7(3) aus die letzte. Keine s.Z.K. wird
”versehentlich“ betreten.
FG KTuEA, TU Ilmenau Effiziente Algorithmen – Sommersemester 2012 58
Starke Zusammenhangskomponenten Der Algorithmus
Algorithmus Strong Components(G ) (von S. R. Kosaraju)Eingabe: Digraph G = (V ,E )Ausgabe: Starke Zusammenhangskomponenten von G(1) Berechne die f-Nummern mittels DFS(G );(2) Bilde
”Umkehrgraphen“ GR durch Umkehren aller Kanten in G ;
(3) Fuhre DFS(GR) durch;Knotenreihenfolge: f-Nummern aus (1) absteigend
(4) Ausgabe: Die Knotenmengen der Tiefensuchbaume aus (3).
Satz 2.4.4
(a) Der Algorithmus Strong Components gibt die starkenZusammenhangskomponenten von G aus.(b) Die Laufzeit ist O(|V |+ |E |).
FG KTuEA, TU Ilmenau Effiziente Algorithmen – Sommersemester 2012 59
Starke Zusammenhangskomponenten Korrektheitsbeweis
Beweis von Teil (b): Die DFS-Aufrufe haben lineare Laufzeit, und auch derUmkehrgraph lasst sich in Zeit O(|V |+ |E |) berechnen (siehe Ubung).
Beweis von Teil (a): Nach Lemma 2.4.3 wissen wir, dass jeder DFS-Baumder Tiefensuche in GR Vereinigung von s.Z.K.n (von GR, also von G ) ist.
Wir zeigen im Folgenden, dass jeder solche Baum nur eine s.Z.K. enthalt.Hierfur zeigen wir, dass die Tiefensuche in GR aus jeder s.Z.K. einenKnoten als Wurzel eines DFS-Baums wahlt.
Sei dazu C ⊆ V eine beliebige s.Z.K. von G .vC ∈ C sei der Knoten mit maximaler f-Nummer in C .
(Aus Lemma 2.4.3: In der ersten Tiefensuche in G ist dies der erste Knoten von C ,der besucht wird.)
FG KTuEA, TU Ilmenau Effiziente Algorithmen – Sommersemester 2012 60
Starke Zusammenhangskomponenten Korrektheitsbeweis
Lemma 2.4.5
Aus vC G v folgt f-num(v) ≤ f-num(vC ).
Beweis: nachste Folie. – Wir folgern fur GR:
Aus v GR vC folgt f-num(v) ≤ f-num(vC ).In Worten: In GR ist vC von keinem Knoten v mit großerer f-Nummer alsvC aus erreichbar.Damit folgt aus Satz 2.1.5 (Knotenmengen der DFS-Baume) undder besonderen Durchlaufreihenfolge (fallende f-Nummern), dass imzweiten DFS-Durchlauf vC Wurzel eines DFS-Baums wird. Da C beliebigwar, enthalt also jede starke Zusammenhangskomponente in derGR-Tiefensuche eine Wurzel, also muss (nach Lemma 2.4.3 fur GR) jededieser Komponenten fur sich einen Baum bilden. Damit ist Satz 2.4.4(a)bewiesen.
FG KTuEA, TU Ilmenau Effiziente Algorithmen – Sommersemester 2012 61
Starke Zusammenhangskomponenten Korrektheitsbeweis
Lemma 2.4.5
Aus vC G v folgt f-num(v) ≤ f-num(vC ).
Beweis: O. B. d. A. gilt vC 6= v .
Sei vC = v0, v1, . . . , vt−1, vt = v︸ ︷︷ ︸=: p
einfacher Weg in G .
1. Fall: Wenn dfs(vC ) startet, sind alle Knoten auf p neu .Nach Satz 2.1.3 (
”Satz vom weißen Weg“) wird v Nachfahr von vC im
DFS-Baum, also ist f-num(v) < f-num(vC ).
FG KTuEA, TU Ilmenau Effiziente Algorithmen – Sommersemester 2012 62
Starke Zusammenhangskomponenten Korrektheitsbeweis
Lemma 2.4.5
Aus vC G v folgt f-num(v) ≤ f-num(vC ).
2. Fall: Wenn dfs(vC ) startet, ist ein Knoten vi , 0<i≤t, aktiv .Dann fuhrt ein Schluss-Stuck des roten Weges von vi zu vC .Von vC nach vi fuhrt der erste Teil des Weges p.Daraus: vC ! vi , also vi ∈ C .Andererseits ist f-num(vi ) > f-num(vC ), im Widerspruch zur Wahl vonvC . Der 2. Fall kann also gar nicht eintreten.
FG KTuEA, TU Ilmenau Effiziente Algorithmen – Sommersemester 2012 63
Starke Zusammenhangskomponenten Korrektheitsbeweis
Lemma 2.4.5
Aus vC G v folgt f-num(v) ≤ f-num(vC ).
3. Fall: Wenn dfs(vC ) startet, ist ein Knoten vi , 0<i≤t, fertig .Wegen des Vorgehens der dfs-Prozedur und weil Fall 2 nicht eintritt, giltfur i ≤ j < t, zu dem Zeitpunkt, an dem dfs(vC ) startet:Wenn vj ”
fertig“ ist, dann ist auch vj+1 ”fertig“.
(Bevor dfs(vj) endete, wurde Kante (vj , vj+1) betrachtet; also kann vj+1
nicht”neu“ sein.)
Also ist v”fertig“, wenn dfs(vC ) startet.
Daraus folgt: f-num(v) < f-num(vC ). �
FG KTuEA, TU Ilmenau Effiziente Algorithmen – Sommersemester 2012 64
Tiefensuche in ungerichteten Graphen
2.5 Tiefensuche in ungerichteten Graphen
Einfacher als Tiefensuche in gerichteten Graphen.
Zweck:
Zusammenhangskomponenten findenSpannbaum fur jede Zusammenhangskomponente findenKreisfreiheitstest
(Diese einfachen Aufgaben kann man auch mit einer Breitensucheerledigen.)
Komplexere Erweiterungen, z. B.
”Zweifach-Zusammenhangskomponenten“, erfordern DFS. (Lit.: Buch von
Sedgewick, Kap. 5.)
FG KTuEA, TU Ilmenau Effiziente Algorithmen – Sommersemester 2012 65
Tiefensuche in ungerichteten Graphen
1:
v:
w:
n:
t u v s
twr
Adjazenzlistendarstellung mit Querverweisen.
FG KTuEA, TU Ilmenau Effiziente Algorithmen – Sommersemester 2012 66
Tiefensuche in ungerichteten Graphen
Darstellung von ungerichteten Graphen:
Adjazenzlistendarstellung mit Querverweisen.
Knotenarray: nodes[1..n].
Zu Knoten v gibt es eine lineare Liste Lv mit einem Eintrag fur jede Kante(v ,w).
Von Eintrag fur Kante (v ,w) fuhrt ein Verweis auf die”Gegenkante“
(w , v) in der Adjazenzliste Lw (und naturlich auch umgekehrt).
Wir konnen an Kanten Markierungen anbringen.
Anfangs markieren wir beide Richtungen aller Kanten mit”neu“. Wir
stellen sicher, dass nach Benutzung der Kante (v ,w) in Richtung von vnach w die umgekehrte Richtung nicht mehr benutzt wird, indem wir(w , v) mit (
”gesehen“) markieren.
Klassifizierung in T -Kanten und B-Kanten.
FG KTuEA, TU Ilmenau Effiziente Algorithmen – Sommersemester 2012 67
Tiefensuche in ungerichteten Graphen
Algorithmus udfs(v) (∗ Tiefensuche von v aus, rekursiv ∗)(∗ nur fur v mit status[v] = neu aufrufen ∗)
(1) dfs count++;(2) dfs num[v]← dfs count;(3) dfs-visit(v); (∗ Aktion an v bei Erstbesuch ∗)(4) status[v]← aktiv ;(5) fur jede
”neue“ Kante (v ,w) (Adjazenzliste!) tue:
(6) setze Gegenkante (w , v) auf”
gesehen“;(7) 1. Fall: status[w] = neu: T ← T ∪ {(v ,w)}; udfs(w);(8) 2. Fall: status[w] = aktiv : B ← B ∪ {(v ,w)};(9) f count++;(10) f num[v]← f count;(11) fin-visit(v); (∗ Aktion an v bei letztem Besuch ∗)(12) status[v]← fertig.
FG KTuEA, TU Ilmenau Effiziente Algorithmen – Sommersemester 2012 68
Tiefensuche in ungerichteten Graphen
Globale Tiefensuche in (ungerichtetem) Graphen G :
Algorithmus UDFS(G ) (∗ Tiefensuche in G = (V ,E ) ∗)(1) dfs count ← 0;(2) f count ← 0;(3) for v from 1 to n do status[v]← neu;(4) T ← ∅; B ← ∅;(5) for v from 1 to n do(6) if status[v] = neu then(7) udfs(v); (∗ starte Tiefensuche von v aus ∗)
FG KTuEA, TU Ilmenau Effiziente Algorithmen – Sommersemester 2012 69
Tiefensuche in ungerichteten Graphen
9
10
8 3
13
1
2
4
5
7
6
12
11
Ungerichteter Graph.
FG KTuEA, TU Ilmenau Effiziente Algorithmen – Sommersemester 2012 70
Tiefensuche in ungerichteten Graphen
9|5| 1|2|
7| 8|3|4|
10|11|
13|
12|
6|
9
10
8 3
13
1
2
4
5
7
6
12
11
2981
346 7
12
5
11
1013
Ungerichteter Graph mit Baum- und Ruckwartskanten sowie dfs- undf-Nummern.
FG KTuEA, TU Ilmenau Effiziente Algorithmen – Sommersemester 2012 71
Tiefensuche in ungerichteten Graphen
Satz 2.5.1
udfs(v0) werde aufgerufen. Dann gilt:
(a) udfs(v0) entdeckt genau die Knoten in derZusammenhangskomponente von v0.
(b) Die Kanten (v ,w), wo udfs(w) unmittelbar aus udfs(v) aufgerufenwird, bilden einen (gerichteten) Baum mit Wurzel v0.(”
Tiefensuchbaum“: ein”
Spannbaum“)(c) (Satz vom weißen Weg) u ist im DFS-Baum ein Nachfahr von v
genau dann wenn zum Zeitpunkt des Aufrufs udfs(v) ein Weg von vnach u existiert, der nur neue (weiße) Knoten enthalt.
Laufzeit (mit Initialisierung): O(|V |+ |Ev0 |), wo Ev0 die Menge der Kanten in derZusammenhangskomponente von v0 ist.
Beweis: Ahnlich zum gerichteten Fall.
FG KTuEA, TU Ilmenau Effiziente Algorithmen – Sommersemester 2012 72
Tiefensuche in ungerichteten Graphen
Satz 2.5.2
UDFS(G ) werde aufgerufen. Dann gilt:
(a) Die T -Kanten bilden eine Reihe von Baumen (dieTiefensuch-Baume). Die Knotenmengen dieser Baume sind dieZusammenhangskomponenten von G .
(b) Die Wurzeln der Baume sind die jeweils ersten Knoten einerZusammenhangskomponente in der Reihenfolge, die in Zeile (2)
benutzt wird.
Gesamt-Laufzeit: O(|V |+ |E |): linear!
FG KTuEA, TU Ilmenau Effiziente Algorithmen – Sommersemester 2012 73
Tiefensuche in ungerichteten Graphen
9|5| 1|2|
7| 8|3|4|
10|11|
13|
12|
6|
9
10
8 3
13
1
2
4
5
7
6
12
11
2981
346 7
12
5
11
1013
Beobachtung: Jeder Knoten
wird besucht; jede Kante wird in
genau einer Richtung betrachtet
und als Baumkante (T) oder
Ruckwartskante (B) klassifiziert;
die jeweiligen Gegenkanten
werden nicht betrachtet (weil sie
auf”gesehen“ gesetzt werden).
FG KTuEA, TU Ilmenau Effiziente Algorithmen – Sommersemester 2012 74
Tiefensuche in ungerichteten Graphen
Kreisfreiheitstest in ungerichteten Graphen.
Zudem: Finden eines Kreises, wenn es einen gibt.
Satz 2.5.3
Nach UDFS(G ) gilt:B 6= ∅ ⇔ G enthalt einen Kreis.
FG KTuEA, TU Ilmenau Effiziente Algorithmen – Sommersemester 2012 75
Tiefensuche in ungerichteten Graphen
Beweis:
”⇒“: Wenn in Zeile (8) eine
”neue“ Kante (v ,w) gefunden wird, die zu
einem aktiven (roten) Knoten w fuhrt, dann bildet diese Kante mit demAbschnitt des roten Weges von w nach v zusammen einen Kreis der Lange≥ 3.(Es kann nicht sein, dass (w , v) eine Baumkante ist, da sonst (v ,w) denStatus
”gesehen“ hatte.)
In diesem Moment kann man auch leicht diesen Kreis ausgeben.
”⇐“: Wenn B = ∅ ist, dann wird jede Kante von G in einer Richtung
Baumkante.Die Kanten der UDFS-Baume bilden ungerichtete Baume und enthaltenalle Kanten von G , also kann G keinen Kreis haben.
�
FG KTuEA, TU Ilmenau Effiziente Algorithmen – Sommersemester 2012 76
Tiefensuche in ungerichteten Graphen
Bemerkung
UDFS auf einen ungerichteten Wald (Vereinigung disjunkter Baume)angewendet gibt jeder Komponente eine Wurzel und richtet die Kantenvon dieser Wurzel weg.
Dies ist eine sehr einfache und schnelle Methode (Linearzeit!), einenungerichteten Wald zu
”orientieren“.
FG KTuEA, TU Ilmenau Effiziente Algorithmen – Sommersemester 2012 77
Tiefensuche in ungerichteten Graphen
Erganzung: Zwei alternative Beweise fur die”
schwierigere“Richtung
”⇐“ im
”Satz vom weißen Weg“
Es gibt hier keinen Grund mehr, sich auf einen Baum zu beschranken, alsobetrachten wir den
”vollen“ DFS-Algorithmus (Folie 25).
Satz 2.1.3 (”Satz vom weißen Weg“)
w ist (direkter oder indirekter) Nachfahr von v im DFS-Wald ⇔ in demMoment, in dem dfs(v) aufgerufen wird, existiert in G ein Weg
v = u0, u1, u2, . . . , ut = w von v nach w aus Knoten, die alle neu(”weiß“) sind.
Definition: Rneuv ist die Menge der zum Zeitpunkt des Aufrufs dfs(v) von
v aus auf einem”weißen Weg“ erreichbaren Knoten.
Die einfache Richtung”⇒“ wird bewiesen wie ursprunglich angegeben.
FG KTuEA, TU Ilmenau Effiziente Algorithmen – Sommersemester 2012 78
Tiefensuche in ungerichteten Graphen
Beweis 2 fur”⇐“: Da durch die T-Kanten die direkte Aufrufbeziehung
reprasentiert wird, und durch Wege aus T-Kanten die indirekteAufrufbeziehung, genugt es zu zeigen, dass fur alle w ∈ Rneu
v der Aufrufdfs(w) wahrend oder mit dem Aufruf dfs(v) erfolgt. Dies zeigen wirindirekt.
Annahme: Es gibt ein w ∈ Rneuv , w 6= v , so dass wahrend des Aufrufs
dfs(v) der Aufruf dfs(w) nicht erfolgt.
Wir wahlen ein solches w und einen Weg v = v0, v1, . . . , vt = w in Rneuv ,
mit moglichst kleinem t. Das heißt, dass v = vt−1 gilt oder dfs(vt−1)wahrend der Abarbeitung von dfs(v) aufgerufen wird. Wahrend desAufrufs dfs(vt−1) wird die Kante (vt−1,w) betrachtet. Nach Annahme istw dann immer noch neu, das hat aber den Effekt, dass dfs(w) jetztaufgerufen wird, Widerspruch.
FG KTuEA, TU Ilmenau Effiziente Algorithmen – Sommersemester 2012 79
Tiefensuche in ungerichteten Graphen
Beweis 3 fur”⇐“:
Wir betrachten die Knotenmenge V neuv aller Knoten, die zum Zeitpunkt des
Aufrufs dfs(v) neu sind, mit allen Kanten zwischen diesen Knoten. (Alle anderenKnoten und Kanten werden ausgeblendet.) Diese Knoten und Kanten bilden einenTeilgraphen G neu
v = (V neuv ,E neu
v ) von G .
Nach Satz 2.1.1 gilt folgendes: Wenn man dfs(v) auf G neuv aufruft, dann wird im
Verlauf dieses Aufrufs genau fur die in diesem Graphen erreichbaren Knoten w dieProzedur dfs(w) aufgerufen, also w in den Baum mit Wurzel v eingebaut. Dassind naturlich genau die Knoten in Rneu
v .
Was im DFS-Algorithmus wahrend der Abarbeitung von dfs(v) tatsachlichablauft, sind die von dfs(v) auf G rekursiv ausgelosten Aufrufe. Hier sindeventuell Knoten x ∈ V − V neu
v uber Kanten (u, x) mit u ∈ V neuv erreichbar.
Wenn aber im Aufruf dfs(u) eine solche Kante getestet wird, hat dies (außer derKlassifizierung als C oder B) keinen Effekt, weil der Zielknoten x nicht neu ist;insbesondere wird kein Aufruf von dfs(x) ausgelost. Das heißt, dass die Strukturder Aufrufe genau die gleiche ist wie die auf G neu
v . Daher werden hier ebenfallsgenau die Knoten in Rneu
v erreicht.
FG KTuEA, TU Ilmenau Effiziente Algorithmen – Sommersemester 2012 80