1 Algorithmen und Datenstrukturen Wintersemester 2014/15 19. Vorlesung Tiefensuche und topologische Sortierung Prof. Dr. Alexander Wolff Lehrstuhl für Informatik I 2 ADS 2014/15: Häufigkeiten der erreichten Punkte im Test 1+2 10 +13 P. 9 8 7 Anzahl 6 5 4 3 2 1 0 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 Punkte n = 165, bestanden“ = 46 (28%), ∅ = 30,6, Median = 30. ” 3 3. Test Termin: Do, 15. Januar, 8:30 Uhr, Zuse-HS Themen: – – – – – – Rot-Schwarz-Bäume: R-S-Eigenschaften und log. Höhe Augmentieren von DS, insbes. von R-S-Bäumen Amortisierte Analyse Graphen und Breitensuche Tiefensuche und top. Sortierung (heute!) Minimale Spannbäume (Do!) Viel Erfolg! Übrigens. . . Es kommen noch 2 Übungsblätter: #10 (Fr) und #11 (16.1.). Bitte denken Sie an die 50%-Marke fürs Übungsmodul bzw. die Klausurzulassung laut alter Studienordnung! 4 Tiefensuche Eingabe: u (un)gerichteter Graph G discovery finish time time π 1/– 1/8 V Ausgabe: – Besuchsintervalle ( u . d / u . f ) 4/5 4/– π – DFS-Wald x v w 2/– 2/7 9/12 9/– K R 3/– 3/6 10/11 10/– z R – Klassifizierung der Graphkanten: Farbe Zielknoten: • Baumkanten (Kanten von Gπ ) weiss y Kanten des DFS-Baums (in Gegenrichtung) • Rückwärtskanten (R) grau Nicht-Baumkanten zu einem Vorgängerknoten • Vorwärtskanten (V) Nicht-Baumkanten zu einem Nachfolgerknoten • Kreuzkanten (K) Kanten, bei denen kein Endpunkt Vorgänger des anderen ist. schwarz und start.d < ziel.d schwarz und start.d > ziel.d 5 Tiefensuche – Pseudocode u 1/8 DFS(Graph G = (V , E )) foreach u ∈ V do V R u .color = white 4/5 u .π = nil x time = 0 // globale Variable! foreach u ∈ V do if u .color == white then DFSVisit(G , u ) DFSVisit(Graph G , Vertex u ) time = time + 1 u .d = time; u .color = gray foreach v ∈ Adj[u ] do if v .color == white then v .π = u ; DFSVisit(G , v ) time = time + 1 u .f = time; u .color = black v w 2/7 9/12 K 3/6 y 10/11 z R Laufzeit von DFS? DFSVisit wird nur für weiße Knoten aufgerufen. In DFSVisit wird der neue Knoten sofort gefärbt. ⇒ DFSVisit wird für jeden Knoten genau 1× aufgerufen. DFS ohne if O(V ) Zeit (out-) DFSVisit ohne Rek. O(deg u) DFS gesamt O(V + E ) Zeit 6 Tiefensuche – Eigenschaften 3/6 4/5 y z 2/9 7/8 x 1/10 w 12/13 s 11/16 14/15 v t u s z y (x x) y w w z s t v v u u t s t B z v u V R 1 2 y w x K 5 10 15 time DFSVisit(Graph G , Vertex u ) time = time + 1 u .d = time; u .color = gray foreach v ∈ Adj[u ] do if v .color == white then v .π = u ; DFSVisit(G , v ) Tiefensuche – Sätze Satz. (Klammerntheorem) time = time + 1 u .f = time; u .color = black V 2 Nach DFS(G ) gilt für {u , v } ∈ genau eine der Bedingungen (i) Besuchsintervalle disjunkt und Baumkanten enthalten weder u -v - noch v -u -Weg. (ii) [u .d , u .f ] ⊂ [v .d , v .f ] und Baumkanten enthalten v -u -Weg. (iii) Wie (ii), nur umgekehrt. Beweis. Wir betrachten zwei Fälle. 1. Fall: u .d < v .d . A) v .d < u .f ,. d.h. v wurde entdeckt, als u noch grau war. ⇒ v ist Nachfolger von u , d.h. es gibt einen u -v -Weg. Wegen u .d < v .d gilt: v wurde später als u entdeckt. ⇒ alle Kanten, die v verlassen, sind erforscht; v wird schwarz, bevor DFS zu u zurückkehrt und u schwarz macht ⇒ [v .d , v .f ] ⊂ [u .d , u .f ] X 7-17 DFSVisit(Graph G , Vertex u ) time = time + 1 u .d = time; u .color = gray foreach v ∈ Adj[u ] do if v .color == white then v .π = u ; DFSVisit(G , v ) Tiefensuche – Sätze Satz. (Klammerntheorem) 7-35 time = time + 1 u .f = time; u .color = black V 2 Nach DFS(G ) gilt für {u , v } ∈ genau eine der Bedingungen (i) Besuchsintervalle disjunkt und Baumkanten enthalten weder u -v - noch v -u -Weg. (ii) [u .d , u .f ] ⊂ [v .d , v .f ] und Baumkanten enthalten v -u -Weg. (iii) Wie (ii), nur umgekehrt. Beweis. Wir betrachten zwei Fälle. X X B) u .f < v .d . X 1. Fall: u .d < v .d . A) v .d < u .f . 2. Fall: v .d < u .d . Symmetrisch! X (Vertausche im Beweis u ↔ v .) Laut Code gilt u .d < u .f < v .d < v .f (siehe Code). ⇒ [u .d , u .f ] ∩ [v .d , v .f ] = ∅ ⇒ Keiner der beiden Knoten wurde entdeckt, während der andere noch grau war., d.h. keiner Nachf. des anderen. 8 Einschub: Vorlesungsumfrage Nutzen Sie die Vorlesungsbefragung – zu konstruktiver Kritik! Von besseren Vorlesungen profitieren Sie (wenn Sie die nächste Veranstaltung bei mir hören) Ihre Nachfolger (im nächsten Wintersemester) ich (Gute Lehre macht Spaß! Gute Klausurergebnisse auch!) JETZT! Vielen Dank! Suchen Sie in Ihrem stud-mail-Konto nach einer Email von EvaSys! Folgen Sie dem Link und geben Sie die TAN ein. 9 Tiefensuche in ungerichteten Graphen Satz. G ungerichtet ⇒ G hat nur Baum- und Rückwärtskanten. Beweis. Sei uv (kurz für {u , v }) eine beliebige Kante von G . O.B.d.A. gilt u .d < v .d . Dann entdeckt DFS v und färbt v schwarz, bevor u schwarz gefärbt wird (da v ∈ Adj[u ]). Falls DFS uv zum ersten Mal von u nach v überschreitet, ist v zu diesem Zeitpunkt weiss. Dann ist uv Baumkante. Andernfalls ist uv R-Kante, da u schon (und immer noch) grau ist, wenn uv zum 1. Mal überschritten wird (und zwar von v nach u ). 10 Ablaufplanung Kante bedeutet: Unterhose vor Hose anziehen! 1/8 2/7 Hose 5/6 Gürtel 14/15 Schal Unterhose Socken 19/20 Schuhe 3/4 Uhr 9/10 T-Shirt 11/18 Anorak Pulli 12/17 DFS-Besuchsintervalle Idee: Sortiere Knoten nach absteigenden f -Zeiten ⇒ alle Kanten sind.. . . nach rechts gerichtet. (Beweis?) 13/16 19/20 11/18 12/17 13/16 14/15 Socken T-Shirt Pulli Anorak Schal Uhr Unterhose Hose Gürtel Schuhe 9/10 1/8 2/7 5/6 3/4 11 Topologisch sortieren Topologische Sortierung: Lineare Ordnung der Knoten, so dass aus (u , v ) ∈ E folgt: u kommt vor v . TopologicalSort(DirectedGraph G ) L = new List() Laufzeit? DFS(G ) mit folgender Änderung: Wenn ein Knoten schwarz gefärbt wird, O (V + E ) häng ihn vorne an die Liste L an. return L Def. Ein (gerichteter) Graph ist kreisfrei, wenn er keinen (gerichteten) Kreis enthält. 12 Kreisfrei ⇔ keine R-Kanten Lem. Ein gerichteter Graph G ist kreisfrei ⇔ DFS(G ) liefert keine Rückwärtskanten. Beweis. ⇒“ Sei G kreisfrei. ” Angenommen DFS(G ) liefert R-Kante (u , v ). v Dann ist u Nachfolger von v im DFS-Wald. D.h. G enthält einen gerichteten v -u -Weg W . W Aber dann ist W ⊕ (u , v ) ein gerichteter Kreis. u ⇐“ DFS(G ) liefere keine R-Kanten. ” Ang. G enthält trotzdem Kreis C = hv1 , . . . , vk i. Sei vi der 1. Knoten in C , den DFS(G ) erreicht. Es gibt einen Weg von vi nach vi −1 in G . ⇒ DFS gelangt zu vi −1 , solange vi grau ist. ⇒ (vi −1 , vi ) ist R-Kante. 13 Korrektheit von TopologicalSort Satz. Sei G ein gerichteter kreisfreier Graph. Dann liefert TopologicalSort(G ) eine topologische Sortierung von G . Beweis. Sei L = hvn , vn−1 , . . . , v1 i = TopologicalSort(G ). Dann gilt v1 .f < v2 .f < · · · < vn .f . Sei (u , v ) Kante von G . Zu zeigen: v .f < u .f Welche Farbe hat v , wenn DFS (u , v ) überschreitet? zu Lemma: v grau ⇒ (u , v ) ist R-Kante G kreisfrei! v weiß ⇒ v Nachfolger von u ⇒ v .f < u .f X v schwarz ⇒ u .f noch nicht gesetzt, v .f gesetzt ⇒ v .f < u .f X 14 Vergleich Durchlaufstrategien für Graphen Breitensuche Tiefensuche Laufzeit O (V + E ) O (V + E ) Ergebnis BFS-Baum, d.h. kürzeste Wege d - und f -Werte, z.B. für top. Sortierung Schlange Rekursion bzw. Stapel nicht-lokal lokal Datenstruktur Vorgehen