Sanders / van Stee: Algorithmentechnik November 27, 2007 1 9 Graphtraversierung Ausgangspunkt oder Baustein fast jedes nichtrivialen Graphenalgorithmus Sanders / van Stee: Algorithmentechnik November 27, 2007 Graphtraversierung als Kantenklassifizierung forward s tree backward cross 2 Sanders / van Stee: Algorithmentechnik November 27, 2007 9.1 Breitensuche b s 0 e g c d f 1 2 3 tree backward cross forward 3 Sanders / van Stee: Algorithmentechnik November 27, 2007 4 9.2 Tiefensuche tree backward s cross forward b d e g c f Sanders / van Stee: Algorithmentechnik November 27, 2007 Tiefensuchschema für G = (V, E) unmark all nodes; init foreach s ∈ V do if s is not marked then mark s root(s) DFS(s, s) // make s a root and grow // a new DFS-tree rooted at it. Procedure DFS(u, v : NodeId) // Explore v coming from u. foreach (v, w) ∈ E do if w is marked then traverseNonTreeEdge(v, w) else traverseTreeEdge(v, w) mark w DFS(v, w) backtrack(u, v) // return from v along the incoming edge 5 Sanders / van Stee: Algorithmentechnik November 27, 2007 DFS Nummerierung init: dfsPos=1 root(s): dfsNum[s]:= dfsPos++ traverseTreeEdge(v, w): dfsNum[w]:= dfsPos++ : 1..n u≺v ⇔ dfsNum[u] < dfsNum[v] . Beobachtung: Knoten auf dem Rekursionsstapel sind bzgl., ≺ sortiert 6 Sanders / van Stee: Algorithmentechnik November 27, 2007 Fertigstellungszeit init: finishingTime=1 backtrack(u, v): finishTime[v]:= finishingTime++ : 1..n 7 Sanders / van Stee: Algorithmentechnik November 27, 2007 8 Kantenklassifizierung bei DFS type dfsNum[v] < finishTime[w] < w is (v, w) dfsNum[w] finishTime[v] marked tree yes yes no forward yes yes yes backward no no yes cross no yes yes forward s tree backward cross Sanders / van Stee: Algorithmentechnik November 27, 2007 Topologisches Sortieren mittels DFS Satz: G ist kreisfrei (DAG) ⇔ DFS finded keine Rückwärtskante. In diesem Fall liefert t(v):= n − finishTime[v] eine topologische Sortierung, d.h. ∀(u, v) ∈ E : t(u) < t(v) 9 Sanders / van Stee: Algorithmentechnik November 27, 2007 Topologisches Sortieren mittels DFS Satz: G kreisfrei (DAG) ⇔ DFS finded keine Rückwärtskante. In diesem Fall liefert t(v):= n − finishTime[v] eine topologische Sortierung, d.h. ∀(u, v) ∈ E : t(u) < t(v). Beweis “⇒”: Annahme ∃ Rückwärtskante. Zusammen mit Baumkanten ergibt sich ein Kreis. Widerspruch. forward s tree backward cross 10 Sanders / van Stee: Algorithmentechnik November 27, 2007 Topologisches Sortieren mittels DFS Satz: G kreisfrei (DAG) ⇔ DFS finded keine Rückwärtskante. In diesem Fall liefert t(v):= n − finishTime[v] eine topologische Sortierung, d.h. ∀(u, v) ∈ E : t(u) < t(v). Beweis “⇐”: Keine Rückwärtskante Kantenklassifizierung z}|{ ⇒ ∀(v, w) ∈ E : finishTime[v] > finishTime[w] ⇒ finishTime definiert umgekehrte topologische Sortierung. 11 Sanders / van Stee: Algorithmentechnik November 27, 2007 12 Starke Zusammenhangskomponenten ∗ Betrachte die Relation ↔ mit ∗ u ↔ v falls ∃ Pfad hu, . . . , vi und ∃ Pfad hv, . . . , ui. ∗ Beobachtung: ↔ ist Äquivalenzrelation Übung ∗ Die Äquivalenzklassen von ↔ bezeichnet man als starke Zusammenhangskomponenten. e d h i e i g c, d, f , g, h f c a b a b Sanders / van Stee: Algorithmentechnik November 27, 2007 Starke Zusammenhangskomponenten – Abstrakter Algorithmus Gc := (V, 0/ = Ec ) foreach edge e ∈ E do invariant SCCs of Gc are known Ec := Ec ∪ {e} 13 Sanders / van Stee: Algorithmentechnik November 27, 2007 14 Schrumpfgraph Gsc = (V s , Ecs ) Knoten: SCCs von Gc . Kanten: (C, D) ∈ Ecs ⇔ ∃(c, d) ∈ Ec : c ∈ C ∧ d ∈ D e d h i e i g c, d, f , g, h f c a b a Beobachtung: Der Schrumpfgraph ist azyklisch b Sanders / van Stee: Algorithmentechnik November 27, 2007 15 Auswirkungen einer neuen Kante e auf Gc , Gsc SCC-intern: Nichts ändert sich zwischen zwei SCCs: Kein Kreis: Neue Kante in Gsc Kreisschluss: SCCs auf Kreis kollabieren. e d h i e i g c, d, f , g, h f c a b a b Sanders / van Stee: Algorithmentechnik November 27, 2007 Konkreter: SCCs mittels DFS Vc = markierte Knoten Ec = bisher explorierte Kanten Aktive Knoten: markiert aber nicht finished. SCCs von Gc : nicht erreicht: Unmarkierte Knoten offen: enthält aktive Knoten abgeschlossen: alle Knoten finished component[w] gibt Repräsentanten einer SCC an. Knoten von offenen (abgeschl.) Komponenten heißen offen (abgeschl.) 16 Sanders / van Stee: Algorithmentechnik November 27, 2007 17 Invarianten von Gc 1. Kanten von abgeschlossenen Knoten gehen zu abgeschlossenen Knoten 2. Offene Komponenten S1 ,. . . ,Sk bilden Pfad in Gsc . 3. Repräsentanten partitionieren die offenen Komponenten bzgl. ihrer dfsNum. S1 r1 S2 r2 open nodes ordered by dfsNum Sk rk current node Sanders / van Stee: Algorithmentechnik November 27, 2007 18 Lemma: Abgeschlossene SCCs von Gc sind SCCs von G Betrachte abgeschlossenen Knoten v und beliebigen Knoten w in der SCC von v bzgl. G. z.Z.: w ist abgeschlossen und v in der gleichen SCC von Gc wie v. Betrachte Kreis C durch v, w. Inv. 1: Knoten von C sind abgeschlossen. Abgeschl. Knoten sind finished. Kanten aus finished Knoten wurden exploriert. Also sind alle Kanten von C in Gc . C w Sanders / van Stee: Algorithmentechnik November 27, 2007 eplacements Repräsentation 19 offener Komponenten Zwei Stapel aufsteigend sortiert nach dfsNum oReps: Repräsentanten offener Komponenten oNodes: Alle offenen Knoten S1 r1 S2 r2 open nodes ordered by dfsNum Sk rk current node Sanders / van Stee: Algorithmentechnik November 27, 2007 init component : NodeArray of NodeId oReps=hi : Stack of NodeId oNodes=hi : Stack of NodeId // SCC representatives // representatives of open SCCs // all nodes in open SCCs Alle Invarianten erfüllt. (Weder offene noch geschlossene Knoten) 20 Sanders / van Stee: Algorithmentechnik November 27, 2007 21 root(s) oReps.push(s) oNodes.push(s) {s} ist die einzige offene Komponente. Alle Invarianten bleiben gültig // new open // component Sanders / van Stee: Algorithmentechnik November 27, 2007 22 traverseTreeEdge(v, w) oReps.push(w) oNodes.push(w) {w} ist neue offene Komponente. dfsNum(w) > alle anderen. Alle Invarianten bleiben gültig // new open // component Sanders / van Stee: Algorithmentechnik November 27, 2007 23 traverseNonTreeEdge(v, w) if w ∈ oNodes then while w ≺ oReps.top do oReps.pop Lemma(∗) w 6∈ oNodes w is abgeschlossen Kante uninteressant w ∈ oNodes: kollabiere offene SCCs auf Kreis Si ri Sk rk w v current node Sanders / van Stee: Algorithmentechnik November 27, 2007 24 backtrack(u, v) if v = oReps.top then // close // component oReps.pop repeat w:= oNodes.pop component[w]:= v until w = v Si ri z.Z. Invarianten bleiben erhalten. . . Sk rk current node Sanders / van Stee: Algorithmentechnik November 27, 2007 25 backtrack(u, v) if v = oReps.top then oReps.pop // close // component repeat w:= oNodes.pop component[w]:= v until w = v Inv. 1: Kanten von abgeschlossenen Knoten gehen zu abgeschlossenen Knoten. Sk Si OK ri rk nein u OK current node nein Sanders / van Stee: Algorithmentechnik November 27, 2007 26 backtrack(u, v) if v = oReps.top then oReps.pop // close // component repeat w:= oNodes.pop component[w]:= v until w = v Inv. 2: Offene Komponenten S1 ,. . . ,Sk bilden Pfad in Gsc OK. (Sk wird ggf. entfernt) Si Sk ri rk current node Sanders / van Stee: Algorithmentechnik November 27, 2007 27 backtrack(u, v) if v = oReps.top then oReps.pop // close // component repeat w:= oNodes.pop component[w]:= v until w = v Inv. 3: Repräsentanten partitionieren die offenen Komponenten bzgl. ihrer dfsNum. OK. (Sk wird ggf. entfernt) Si ri Sk rk current node Sanders / van Stee: Algorithmentechnik November 27, 2007 28 Beispiel a b c d e f g h i j k root(a) traverse(a,b) traverse(b,c) unmarked marked finished nonrepresentative node representative node nontraversed edge closed SCC traversed edge open SCC Sanders / van Stee: Algorithmentechnik November 27, 2007 a b c d e f g h 29 i j k root(a) traverse(a,b) traverse(b,c) traverse(c,a) unmarked marked finished nonrepresentative node representative node nontraversed edge closed SCC traversed edge open SCC Sanders / van Stee: Algorithmentechnik November 27, 2007 a b c d e f g h 30 i j k backtrack(b,c) backtrack(a,b) unmarked marked finished nonrepresentative node representative node nontraversed edge closed SCC traversed edge open SCC Sanders / van Stee: Algorithmentechnik November 27, 2007 a b c d e f g h 31 i j k backtrack(a,a) unmarked marked finished nonrepresentative node representative node nontraversed edge closed SCC traversed edge open SCC Sanders / van Stee: Algorithmentechnik November 27, 2007 a b c d e f g h 32 i j k root(d) traverse(d,e) traverse(e,f) traverse(f,g) unmarked marked finished nonrepresentative node representative node nontraversed edge closed SCC traversed edge open SCC Sanders / van Stee: Algorithmentechnik November 27, 2007 a b c d backtrack(f,g) e f g h 33 i j k backtrack(e,f) unmarked marked finished nonrepresentative node representative node nontraversed edge closed SCC traversed edge open SCC Sanders / van Stee: Algorithmentechnik November 27, 2007 a b c traverse(e,g) d e f g h traverse(e,h) 34 i j k traverse(h,i) unmarked marked finished nonrepresentative node representative node nontraversed edge closed SCC traversed edge open SCC Sanders / van Stee: Algorithmentechnik November 27, 2007 a b c d e f g h 35 i j k traverse(i,e) unmarked marked finished nonrepresentative node representative node nontraversed edge closed SCC traversed edge open SCC Sanders / van Stee: Algorithmentechnik November 27, 2007 a b c d e f g traverse(i,j) traverse(j,c) h 36 i j k traverse(j,k) unmarked marked finished nonrepresentative node representative node nontraversed edge closed SCC traversed edge open SCC Sanders / van Stee: Algorithmentechnik November 27, 2007 a b c d e f g h 37 i j k traverse(k,d) unmarked marked finished nonrepresentative node representative node nontraversed edge closed SCC traversed edge open SCC Sanders / van Stee: Algorithmentechnik November 27, 2007 a b c d e f g h 38 i j k backtrack(j,k) backtrack(i,j) backtrack(h,i) backtrack(e,h) backtrack(d,e) unmarked marked finished nonrepresentative node representative node nontraversed edge closed SCC traversed edge open SCC Sanders / van Stee: Algorithmentechnik November 27, 2007 a b c d e f g h 39 i j k backtrack(d,d) unmarked marked finished nonrepresentative node representative node nontraversed edge closed SCC traversed edge open SCC Sanders / van Stee: Algorithmentechnik November 27, 2007 Zusammenfassung: SCC Berechnung Einfache Instantiierung des DFS-Musters Nichttrivialer Korrektheitsbeweis Laufzeit O(m + n): (Jeweils max. n push/pop Operationen) Ein einziger Durchlauf 40 Sanders / van Stee: Algorithmentechnik November 27, 2007 2-zusammenhängende Komponenten (ungerichtet) Bei entfernen eines Knotens bleibt die Komponente zusammenhängend. (Partitionierung der Kanten) Geht in Zeit O(m + n) mit Algorithmus ähnlich zu SCC-Algorithmus 41 Sanders / van Stee: Algorithmentechnik November 27, 2007 Mehr DFS-basierte Linearzeitalgorithmen 3-zusammenhängende Komponenten Planaritätstest Einbettung planarer Graphen 42