1 / 11

Tarjans Algorithmus zur Bestimmung der starken Zusammenhangs- komponenten

Tarjans Algorithmus zur Bestimmung der starken Zusammenhangs- komponenten. Katja Losemann Chris Schwiegelshohn. Idee. G = <V,E> gerichteter Graph Gesucht sind alle starken Zusammenhangskomponenten (SZK) Einmalige Tiefensuche durch den Graph reicht aus

Download Presentation

Tarjans Algorithmus zur Bestimmung der starken Zusammenhangs- komponenten

An Image/Link below is provided (as is) to download presentation Download Policy: Content on the Website is provided to you AS IS for your information and personal use and may not be sold / licensed / shared on other websites without getting consent from its author. Content is provided to you AS IS for your information and personal use only. Download presentation by click this link. While downloading, if for some reason you are not able to download a presentation, the publisher may have deleted the file from their server. During download, if you can't get a presentation, the file might be deleted by the publisher.

E N D

Presentation Transcript


  1. Tarjans Algorithmus zur Bestimmung der starken Zusammenhangs- komponenten Katja Losemann Chris Schwiegelshohn

  2. Idee • G = <V,E> gerichteter Graph • Gesucht sind alle starken Zusammenhangskomponenten (SZK) • Einmalige Tiefensuche durch den Graph reicht aus • SZK werden durch Wurzeln der DFS-Teilbäume eindeutig identifiziert

  3. Idee (Forsetzung) • dfs_index(v): Reihenfolge der DFS-Aufrufe • Stack S wird in der Reihenfolge der besuchten Knoten befüllt • Bei Rückkehr Überprüfung ob aktueller Knoten v die Wurzel einer SZK • Wenn eine Wurzel gefunden wurde, bilden alle Knoten des Stacks bis zu dieser Wurzel eine SZK

  4. Lowlink • zusätzlicher Wert lowlink(v) für alle v mit • lowlink(v) =min ( {num[v]} {num[x] | v→*−x ) • v Wurzel, wenn lowlink(v) = dfs(v)

  5. Algorithmus Eingabe Graph G ( V, E ) current_dfs := 0 V‘ := V S = ∅ // S ist der Stack while ( V‘ not emtpy) tarjan ( v ) // v ∊ V‘

  6. Algorithmus (Forsetzung) Tarjan ( v ) : dfs_index( v ) := current_dfs lowlink( v ) := current_dfs S.push ( v ) current_dfs ++ V‘ = V \ { v } For ( v1 | ( v, v1 ) ∊ E ) if ( v1 ∊ V‘ ) tarjan ( v1 ) lowlink( v ) := min ( lowlink( v ), lowlink( v1 ) )

  7. Algorithmus (Forsetzung) else if (v1 ∊ S ) lowlink( v ) := min ( lowlink( v ), dfs_index( v1 ) ) If ( lowlink( v ) = dfs_index( v ) ) repeat k = S.pop( ) //Ausgabe until ( k = v )

  8. Beispiel dfs(v) lowlink(v)) lowlink(1) = 1 lowlink(5) = 2 11 0 10 12 lowlink(4) = 2 lowlink(9) = 6 lowlink(8) = 6 1 5 lowlink(7) = 6 8 9 lowlink(6) = 6 4 lowlink(3) = 0 lowlink(2) = 0 2 3 7 lowlink(10) = 3 6 lowlink(0) = 0 9 SZK 1 SZK 0,2,3,4,5 lowlink(12) = 11 8 7 SZK 6,7,8,9 SZK 11,12 lowlink(11) = 11 6 10 5 4 3 12 2 1 0 11 Stack:

  9. Beweis – Korrektheit lowlink • Fall 1: (v‘‘,v‘) Vorwärtskante • Dann dfs(v‘) > dfs(v‘‘) trägt nicht zum Min bei • Fall 2: (v‘‘,v‘) Rückwärtskante • Dann v‘ noch auf dem Stack und in gleicher SZK • Fall 3: (v‘‘,v‘) Querkante • Entweder nicht im Stack und in nächster SZK, • oder nicht im Stack und in gleicher SZK, dann aber normale Baumkante

  10. Beweis - Korrektheit • lowlink garantiert, dass es immer einen Weg zu einem Knoten höher im DFS-Baum als der aktuelle Knoten existiert • lowlink(v) = dfs(v) ⇒ Kein Knoten oberhalb von v kommt für SZK in Frage • Mit der letzten Kante kommt man nicht in eine SZK, die nicht aktuell und auf dem Stack liegt. • Wäre ein Weg nur in einer Richtung vorhanden, wäre lowlink(v) = dfs(v)

  11. Aufwand • Aber ist das effizient berechenbar? • Tarjan muss für jeden Knoten einmal aufgerufen werden • Die Berechnung von dfs und lowlink erfolgt rekursiv über alle angrenzenden Kanten • Insgesamt wird jede Kante maximal 2x betrachtet, damit: • O( |V| + |E| )

More Related