Effiziente Algorithmen und Datenstrukturen I Kapitel 7 Graphen
- Slides: 81
Effiziente Algorithmen und Datenstrukturen I Kapitel 7: Graphen Christian Scheideler WS 2008 11/3/2020 Kapitel 7 1
Graphen Graph G=(V, E) besteht aus • Knotenmenge V • Kantenmenge E ungerichteter Graph 11/3/2020 gerichteter Graph Kapitel 7 2
Graphen • Ungerichteter Graph: Kante repräsentiert durch Teilmenge {v, w} ½ V • Gerichteter Graph: Kante repräsentiert duch Paar (v, w) 2 V£ V (bedeutet v w) ungerichteter Graph 11/3/2020 Kapitel 7 gerichteter Graph 3
Graphen Anwendungen: • Ungerichtete Graphen: Symmetrische Beziehungen jeglicher Art (z. B. {v, w} 2 E genau dann, wenn Distanz zwischen v und w maximal 1 km) • Gerichtete Graphen: asymmetrische Beziehungen (z. B. (v, w) 2 E genau dann, wenn Person v Person w mag) 11/3/2020 Kapitel 7 4
Graphen Im folgenden: nur gerichtete Graphen. Modellierung eines ungerichteten Graphen als gerichteter Graph: Ungerichtete Kante ersetzt durch zwei gerichtete Kanten. • n: aktuelle Anzahl Knoten • m: aktuelle Anzahl Kanten 11/3/2020 Kapitel 7 5
Graphentheorie • (v, w): Distanz (Länge eines kürzesten gerichteten Weges) von w zu v in G • D=maxv, w (v, w): Durchmesser von G B A C E 11/3/2020 D D=4 Kapitel 7 6
Graphentheorie G heißt • (schwach) zusammenhängend: Durchmesser D endlich, wenn alle Kanten ungerichtet • stark zusammenhängend: D endlich B A C D E 11/3/2020 Kapitel 7 7
Graphentheorie • N(U)={ w 2 VU | 9 v 2 U: (v, w)2 E }: Nachbarmenge von Knotenmenge U • (U)=|N(U)| / |U| (|M|: Größe von Menge M) • (G) = min. U, |U|<|V|/2 (U): Expansion von G B C D A |U|=2 11/3/2020 U |N(U)|=1 Kapitel 7 8
Lineare Liste • Grad 2 • Hoher Durchmesser (n-1 für n Knoten) • Niedrige Expansion ( (Liste) = 2/n ) 11/3/2020 Kapitel 7 9
Vollständiger binärer Baum 0 Tiefe k k • n=2 k+1 -1 Knoten, Grad 3 • Durchmesser ist 2 k ~ 2 log 2 n • Niedrige Expansion ( (Binärbaum)=2/n ) 11/3/2020 Kapitel 7 10
2 -dimensionales Gitter 1 Seitenlänge k k • n = k 2 Knoten, maximaler Grad 4 • Durchmesser ist 2(k-1) ~ 2 n • Expansion ist ~2/ n 11/3/2020 Kapitel 7 11
Hypercube • Knoten: (x 1, …, xd) 2 {0, 1}d • Kanten: 8 i: (x 1, …, xd) ! (x 1, . . , 1 -xi, . . , xd) d=1 d=2 d=3 Grad d, Durchmesser d, Expansion 1/ d 11/3/2020 Kapitel 7 12
Expander Theorem 7. 1: Für jeden Graph G ist die Expansion (G) höchstens 1. Theorem 7. 2: Es gibt Familien von Graphen konstanten Grades mit konstanter Expansion. Diese heißen Expander. Beispiel: Gabber-Galil Graph • Knotenmenge: (x, y) 2 {0, …, n-1}2 • (x, y) ! (x, x+y), (x, x+y+1), (x+y, y), (x+y+1, y) (mod n) 11/3/2020 Kapitel 7 13
Operationen auf Graphen G=(V, E): Graph-Variable • Node: DS für Knoten, Edge: DS für Kanten Operationen: • G. insert(e: Edge): E: =E [ {e} • G. remove(i, j: Key): E: =En{e} für die Kante e=(v, w) mit Key(v)=i und Key(w)=j • G. insert(v: Node): V: =V [ {v} • G. remove(i: Key): sei v 2 V der Knoten mit Key(v)=i. V: =Vn{v}, E: =En{(x, y) | x=v Ç y=v} • G. find(i: Key): gib Knoten v aus mit Key(v)=i • G. find(i, j: Key): gib Kante (v, w) aus mit Key(v)=i und Key(w)=j 11/3/2020 Kapitel 7 14
Operationen auf Graphen Anzahl der Knoten oft fest. In diesem Fall: • V={1, …, n} (Knoten hintereinander nummeriert, identifiziert durch ihre Keys) Relevante Operationen: • G. insert(e: Edge): E: =E [ {e} • G. remove(i, j: Key): E: =En{e} für die Kante e=(i, j) • G. find(i, j: Key): gib Kante e=(i, j) aus 11/3/2020 Kapitel 7 15
Operationen auf Graphen Anzahl der Knoten variabel: • Hashing (z. B. Kuckuckshashing) kann verwendet werden, um Keys von n Knoten in Bereich {1, …, O(n)} zu hashen. • Damit kann variabler Fall auf den Fall einer statischen Knotenmenge reduziert werden. (Nur O(1)-Vergrößerung gegenüber statischer Datenstruktur) 11/3/2020 Kapitel 7 16
Operationen auf Graphen Im folgenden: Konzentration auf statische Anzahl an Knoten. Parameter für Laufzeitanalyse: • n: Anzahl Knoten • m: Anzahl Kanten • d: maximaler Knotengrad (maximale Anzahl ausgehender Kanten von Knoten) 11/3/2020 Kapitel 7 17
Graphrepräsentationen 1. 2. 3. 4. 5. 6. Sequenz von Kanten Adjazenzfeld Adjazenzliste Adjazenzmatrix Adjazenzliste + Hashtabelle Implizite Repräsentationen 11/3/2020 Kapitel 7 18
Graphrepräsentationen 1: Sequenz von Kanten (1, 2) 11/3/2020 (2, 3) 1 2 4 3 (3, 4) Kapitel 7 (4, 1) ? 19
Sequenz von Kanten (1, 2) (2, 3) (3, 4) (4, 1) ? Zeitaufwand: • G. find(i, j: Key): (m) im worst case • G. insert(e: Edge): O(1) • G. remove(i, j: Key): (m) im worst case 11/3/2020 Kapitel 7 20
Graphrepräsentationen 2: Adjazenzfeld n 1 1 4 2 V 1 3 5 6 offsets in E E 2 3 3 4 4 3 1 (1, 2), (1, 3) 1 m (3, 4) Hier: nur Zielkeys In echter DS: E: Array [1. . m] of Edge 11/3/2020 Kapitel 7 21
Adjazenzfeld 1 2 4 3 V 1 3 5 6 offsets in E E 2 3 3 4 4 1 Zeitaufwand: • G. find(i, j: Key): Zeit O(d) • G. insert(e: Edge): Zeit O(m) (worst case) • G. remove(i, j: Key): Zeit O(m) (worst case) 11/3/2020 Kapitel 7 22
Graphrepräsentationen 3: Adjazenzliste 1 1 2 n V 4 3 2 3 3 4 4 1 Hier: nur Zielkeys In echter DS: V: Array [1. . n] of List of Edge 11/3/2020 Kapitel 7 23
Adjazenzliste 1 4 V 2 3 3 4 Zeitaufwand: • G. find(i, j: Key): Zeit O(d) • G. insert(e: Edge): Zeit O(d) • G. remove(i, j: Key): Zeit O(d) 11/3/2020 Kapitel 7 4 1 Problem: d kann groß sein! 24
Graphrepräsentationen 4: Adjazenzmatrix 1 0 1 1 0 2 A= 0 0 1 1 0 0 0 1 4 3 1 0 0 0 • A[i, j] 2 {0, 1} (bzw. Zeiger auf Edge) • A[i, j]=1 genau dann, wenn (i, j)2 E 11/3/2020 Kapitel 7 25
Adjazenzmatrix 1 0 1 1 0 2 A= 0 0 1 1 0 0 0 1 4 3 1 0 0 0 Zeitaufwand: • G. find(i, j: Key): Zeit O(1) • G. insert(e: Edge): Zeit O(1) • G. remove(i, j: Key): Zeit O(1) 11/3/2020 Kapitel 7 Aber: Speicheraufwand O(n 2) 26
Graphrepräsentationen 5: Adjazenzliste + Hashtabelle 1 e 2 2 e 4 e 6 4 V e 5 e 3 3 1, 2 e 1 e 3 e 2 e 4 1, 3 2, 3 e 5 2, 4 e 6 3, 4 4, 1 z. B. Kuckuckshashing 11/3/2020 Kapitel 7 27
Adjazenzliste+Hashtabelle Zeitaufwand (Kuckucksh. ): V • G. find(i, j: Key): e O(1) (worst case) • G. insert(e: Edge): e O(1) (amortisiert) • G. remove(i, j: Key): 1, 2 1, 3 O(1) (worst case) • Speicher: O(n+m) 11/3/2020 Kapitel 7 1 e 3 2 e 4 2, 3 e 5 2, 4 e 6 3, 4 4, 1 28
Graphrepräsentationen 6: Implizite Repräsentationen (k, l)-Gitter G=(V, E): • V=[k]£[l] ([a]={0, …, a-1} für a 2 IN) • E={((v, w), (x, y)) | (v=x Æ |w-y|=1) Ç (w=y Æ |v-x|=1)} Beispiel: (5, 4)-Gitter 11/3/2020 Kapitel 7 29
Graphrepräsentationen 6: Implizite Repräsentationen (k, l)-Gitter G=(V, E): • V=[k]£[l] ([a]={0, …, a-1} für a 2 IN) • E={((v, w), (x, y)) | (v=x Æ |w-y|=1) Ç (w=y) Æ |v-x|=1)} • Speicheraufwand: O(log k + log l) (speichere Kantenregel sowie k und l) • Find-Operation: O(1) Zeit (reine Rechnung) 11/3/2020 Kapitel 7 30
Graphdurchlauf Zentrale Frage: Wie können wir die Knoten eines Graphen durchlaufen, so dass jeder Knoten mindestens einmal besucht wird? 11/3/2020 Kapitel 7 31
Graphdurchlauf Zentrale Frage: Wie können wir die Knoten eines Graphen durchlaufen, so dass jeder Knoten mindestens einmal besucht wird? Grundlegende Strategien: • Breitensuche • Tiefensuche 11/3/2020 Kapitel 7 32
Breitensuche • Starte von einem Knoten s • Exploriere Graph Distanz für Distanz s 11/3/2020 Kapitel 7 33
Tiefensuche • Starte von einem Knoten s • Exploriere Graph in die Tiefe ( : aktuell, : noch aktiv, : fertig) s 11/3/2020 Kapitel 7 34
Breitensuche • d(v): Distanz von Knoten v zu s (d(s)=0) • parent(v): Knoten, von dem v besucht Distanzen: 3 2 4 1 3 3 1 4 0 2 2 11/3/2020 Kapitel 7 35
Breitensuche • d(v): Distanz von Knoten v zu s (d(s)=0) • parent(v): Knoten, von dem v besucht Mögliche Parent-Beziehungen in rot: 3 2 4 1 3 3 1 4 0 2 2 11/3/2020 Kapitel 7 36
Breitensuche Parent-Beziehung eindeutig: wenn Knoten v zum erstenmal besucht wird, wird parent(v) gesetzt und v markiert, so dass v nicht nochmal besucht wird 3 2 4 1 3 3 1 4 0 2 2 11/3/2020 Kapitel 7 37
Breitensuche Kantentypen: • Baumkante: zum Kind • Rückwärtskante: zu einem Vorfahr • Kreuzkante: alle sonstige Kanten 3 2 4 1 3 3 1 4 s 2 2 11/3/2020 Kapitel 7 38
Breitensuche Kantentypen: • Baumkante: zum Kind • Rückwärtskante: zu einem Vorfahr • Kreuzkante: alle sonstige Kanten 3 2 4 1 3 3 1 4 0 2 2 11/3/2020 Kapitel 7 39
Breitensuche Procedure BFS(s: Node) d = <1, …, 1>: Array [1. . n] of IN parent = <? , …, ? >: Array [1. . n] of Node d[Key(s)]: =0 // s hat Distanz 0 zu sich parent[Key(s)]: =s // s ist sein eigener Vater q: =<s>: List of Node // q: Queue zu besuchender Knoten while q = <> do // solange q nicht leer u: = q. pop. Front() // nimm Knoten nach FIFO-Regel foreach (u, v)2 E do if parent(Key(v))=? then // v schon besucht? q. push. Back(v) // nein, dann in q hinten einfügen d[Key(v)]: =d[Key(u)]+1 parent[Key(v)]: =u 11/3/2020 Kapitel 7 40
BFS(b) (2, c) e (2, c) i h d (4, g) g (4, g) (3, f) f c (2, c) (d[v], parent[v])-Werte (1, b) (2, c) a b (0, b) : besucht, noch in q 11/3/2020 : besucht, nicht mehr in q Kapitel 7 41
BFS(a) e i h d g f c a (0, a) (d[v], parent[v])-Werte b Von a kein anderer Knoten erreichbar. 11/3/2020 Kapitel 7 42
Tiefensuche • Starte von einem Knoten s • Exploriere Graph in die Tiefe ( : aktuell, : noch aktiv, : fertig) s 11/3/2020 Kapitel 7 43
Tiefensuche - Schema Übergeordnete Prozedur: unmark all nodes init() foreach s 2 V do // stelle sicher, dass alle Knoten besucht werden if s is not marked then mark s root(s) DFS(s, s) // s: Startknoten Procedure DFS(u, v: Node) // u: Vater von v foreach (v, w)2 E do if w is marked then traverse. Non. Tree. Edge(v, w) else traverse. Tree. Edge(v, w) mark w DFS(v, w) backtrack(u, v) Proceduren in rot: noch zu spezifizieren 11/3/2020 Kapitel 7 44
DFS-Nummerierung Variablen: • dfs. Num: Array [1. . n] of IN • finish. Time: Array [1. . n] of IN • dfs. Pos, finishing. Time: IN // Zeitpunkt wenn Knoten // Zähler ! Proceduren: • init(): dfs. Pos: =1; finishing. Time: =1 • root(s): dfs. Num[s]: =dfs. Pos; dfs. Pos: =dfs. Pos+1 • traverse. Tree. Edge(v, w): dfs. Num[w]: =dfs. Pos; dfs. Pos: =dfs. Pos+1 • traverse. Non. Tree. Edge(v, w): • Backtrack(u, v): finish. Time[v]: =finishing. Time; finishing. Time: =finishing. Time+1 11/3/2020 Kapitel 7 45
DFS-Nummerierung • Exploriere Graph in die Tiefe ( : aktuell, : noch aktiv, : fertig) • Paare (i, j): i: dfs. Num, j: finish. Time (11, 8 ) (9, 9 ) (6, 1 ) (8, 10 ) (10, 7 ) s (2, 6 ) (7, 2 ) (1, 11 ) 11/3/2020 (5, 3 ) (3, 5 ) Kapitel 7 (4, 4 ) 46
DFS-Nummerierung Ordnung < auf den Knoten: u<v , dfs. Num[u]<dfs. Num[v] Lemma 7. 3: Die Knoten im DFS-Rekursionsstack (alle Knoten) sind sortiert bezüglich <. Beweis: dfs. Pos wird nach jeder Zuweisung von dfs. Num erhöht. Jeder neue aktive Knoten hat also immer die höchste dfs. Num. 11/3/2020 Kapitel 7 47
DFS-Nummerierung Überprüfung von Lemma 7. 3: • Rekursionsstack: roter Pfad von s • Paare (i, j): i: dfs. Num, j: finish. Time (11, 8 ) (9, 9 ) (6, 1 ) (8, 10 ) (10, 7 ) s (2, 6 ) (7, 2 ) (1, 11 ) 11/3/2020 (5, 3 ) (3, 5 ) Kapitel 7 (4, 4 ) 48
DFS-Nummerierung • • Baumkante: zum Kind Vorwärtskante: zu einem Nachkommen Rückwärtskante: zu einem Vorfahr Kreuzkante: alle sonstige Kanten (11, 8 ) (9, 9 ) (6, 1 ) (8, 10 ) (10, 7 ) s (2, 6 ) (7, 2 ) (1, 11 ) 11/3/2020 (5, 3 ) (3, 5 ) Kapitel 7 (4, 4 ) 49
DFS-Nummerierung Beobachtung für Kante (v, w): Kantentyp dfs. Num[v]< dfs. Num[w] finish. Time[v]> finish. Time[w] Baum & Vorwärts Ja Ja Rückwärts Nein Kreuz Nein Ja 11/3/2020 Kapitel 7 50
DFS-Nummerierung Anwendung: • Erkennung eines azyklischen gerichteten Graphen (engl. DAG) Merkmal: keine gerichtete Kreise 11/3/2020 Kapitel 7 51
DFS-Nummerierung Lemma 7. 4: Das Folgende ist äquivalent: 1. G ist ein DAG 2. DFS enthält keine Rückwärtskante 3. 8 (v, w)2 E: finish. Time[v]>finish. Time[w] Beweis: 2. , 3. : folgt aus Tabelle 11/3/2020 Kapitel 7 52
DFS-Nummerierung Lemma 7. 4: Das Folgende ist äquivalent: 1. G ist ein DAG 2. DFS enthält keine Rückwärtskante 3. 8 (v, w)2 E: finish. Time[v]>finish. Time[w] Beweis: : 2. ) : 1. 11/3/2020 gerichteter Kreis Kapitel 7 53
DFS-Nummerierung Lemma 7. 4: Das Folgende ist äquivalent: 1. G ist ein DAG 2. DFS enthält keine Rückwärtskante 3. 8 (v, w)2 E: finish. Time[v]>finish. Time[w] Beweis: : 1. ) : 2. Eine davon Rückwärtskante 11/3/2020 Kapitel 7 54
DFS-Nummerierung Lemma 7. 4: Das Folgende ist äquivalent: 1. G ist ein DAG 2. DFS enthält keine Rückwärtskante 3. 8 (v, w)2 E: finish. Time[v]>finish. Time[w] Beweis: : 1. ) : 2. Rückwärtskante Annahme: Erster von DFS besuchter Knoten im Kreis 11/3/2020 Kapitel 7 DFS 55
Starke ZHKs Definition: Sei G=(V, E) ein gerichteter Graph. U½V ist eine starke Zusammenhangskomponente (ZHK) von V , für alle u, v 2 U gibt es einen gerichteten Weg von u nach v in G und U maximal U 11/3/2020 Kapitel 7 56
Starke ZHKs Beobachtung: Schrumpft man starke ZHKs zu einzelnen Knoten, dann ergibt sich DAG. ZHK 11/3/2020 Kapitel 7 57
Starke ZHKs - Beispiel e i h d g f c a 11/3/2020 b Kapitel 7 58
Starke ZHKs - Beispiel DAG 11/3/2020 Kapitel 7 59
Starke ZHKs Ziel: Finde alle starken ZHKs im Graphen in O(n+m) Zeit (n: #Knoten, m: #Kanten) Strategie: Verwende DFS-Verfahren mit component: Array [1. . n] of 1. . n Am Ende: component[v]=component[w] , v und w sind in derselben starken ZHK 11/3/2020 Kapitel 7 60
Starke ZHKs • • Betrachte DFS auf G=(V, E) Sei Gc=(Vc, Ec) bereits besuchter Teilgraph von G Ziel: bewahre starke ZHKs in Gc Idee: a) neue ZHK kein DAG aktueller Knoten & Kante b) neue ZHK 11/3/2020 Kapitel 7 61
Starke ZHKs Warum ZHKs zu einer zusammenfassbar? neue ZHK kein DAG aktueller Knoten & Kante Grund: ZHK v 11/3/2020 ZHK für alle v, w: Weg von v nach w und umgekehrt ZHK Kapitel 7 w 62
Starke SHKs - Beispiel e i h d g f c a b Problem: wie fasst man ZHKs effizient zusammen? 11/3/2020 Kapitel 7 63
Starke ZHKs Definition: • : unfertiger Knoten • : fertiger Knoten • Eine ZHK in G heißt offen, falls sie noch unfertige Knoten enthält. Sonst heißt sie (und ihre Knoten) geschlossen. • Repräsentant einer ZHK: Knoten mit kleinster dfs. Num. 11/3/2020 Kapitel 7 64
Starke ZHKs Beobachtungen: 1. Alle Kanten aus geschlossenen Knoten führen zu geschlossenen Knoten. 2. Der Pfad zum aktuellen Knoten enthält die Repräsentanten aller offenen ZHKs. 3. Betrachte die Knoten in offenen ZHKs sortiert nach DFS-Nummern. Die Repräsentanten partitionieren diese Folge in die offenen ZHKs. 11/3/2020 Kapitel 7 65
Starke ZHKs Beobachtungen sind Invarianten: 1. Alle Kanten aus geschlossenen Knoten führen zu geschlossenen Knoten. 2. Der Pfad zum aktuellen Knoten enthält die Repräsentanten aller offenen ZHKs. 3. Betrachte die Knoten in offenen ZHKs sortiert nach DFS-Nummern. Die Repräsentanten partitionieren diese Folge in die offenen ZHKs. 11/3/2020 Kapitel 7 66
Starke ZHKs Beweis über vollständige Induktion. • Anfangs gelten alle Invarianten • Wir betrachten verschiedene Fälle geschlossene ZHK fertiger Knoten aktueller Knoten offene ZHK 11/3/2020 Repräsentanten noch nicht Kapitel 7 exploriert 67
Starke ZHKs Beweis über vollständige Induktion. • Anfangs gelten alle Invarianten • Fall 1: Kante zu unfertigem Knoten geschlossene ZHK fertiger Knoten aktueller Knoten offene ZHK 11/3/2020 Repräsentanten noch nicht Kapitel 7 exploriert 68
Starke ZHKs Beweis über vollständige Induktion. • Anfangs gelten alle Invarianten • Fall 2: Kante zu geschlossenem Knoten geschlossene ZHK fertiger Knoten aktueller Knoten offene ZHK 11/3/2020 Repräsentanten noch nicht Kapitel 7 exploriert 69
Starke ZHKs Beweis über vollständige Induktion. • Anfangs gelten alle Invarianten • Fall 3: Kante zu fertigem Knoten geschlossene ZHK fertiger Knoten aktueller Knoten offene ZHK 11/3/2020 Repräsentanten noch nicht Kapitel 7 exploriert 70
Starke ZHKs Beweis über vollständige Induktion. • Anfangs gelten alle Invarianten • Fall 4: Kante zu nicht exploriertem Knoten geschlossene ZHK fertiger Knoten aktueller Knoten offene ZHK 11/3/2020 Repräsentanten noch nicht Kapitel 7 exploriert 71
Starke ZHKs Beweis über vollständige Induktion. • Anfangs gelten alle Invarianten • Fall 5: Knoten exploriert geschlossene ZHK fertiger Knoten aktueller Knoten offene ZHK 11/3/2020 Repräsentanten noch nicht Kapitel 7 exploriert 72
Starke ZHKs Beweis über vollständige Induktion. • Anfangs gelten alle Invarianten • Fall 5: Knoten exploriert geschlossene ZHK geschlossener fertiger Knoten aktueller Knoten geschlossene offene ZHK 11/3/2020 Repräsentanten Kapitel 7 73
Starke ZHKs Lemma 7. 5: Eine geschlossene ZHK in Gc ist eine ZHK in G. Beweis: • v: geschlossener Knoten • S: ZHK in G, die v enthält • Sc: ZHK in Gc, die v enthält • Es gilt: Sc ½ S • Zu zeigen: S ½ Sc 11/3/2020 Kapitel 7 74
Starke ZHKs Beweis von Lemma 7. 5: v w S • w: beliebiger Knoten in S • Es gibt gerichteten Kreis C durch v und w • Invariante 1: alle Knoten in C geschlossen v w C • Da alle Kanten geschlossener Knoten exploriert worden sind, ist C in Gc und daher w 2 Sc 11/3/2020 Kapitel 7 75
Starke ZHKs Invarianten 2 und 3: einfache Methode, um offene ZHKs in Gc zu repräsentieren: • Wir verwalten Folge o. Nodes aller offenen (nicht geschl. ) Knoten in steigender DFSNummer und eine Teilfolge o. Reps aller offenen ZHK-Repräsentanten • Stack ausreichend für beide Folgen 11/3/2020 Kapitel 7 76
Starke ZHKs init: component: Array [1. . n] of Node. Id o. Reps = <>: Stack of Node. Id o. Nodes = <>: Stack of Node. Id dfs. Pos: =1 root(w) oder traverse. Tree. Edge(v, w): o. Reps. push(w) // neue ZHK o. Nodes. push(w) // neuer offener Knoten dfs. Num[w]: =dfs. Pos; dfs. Pos: =dfs. Pos+1 11/3/2020 Kapitel 7 77
Starke ZHKs traverse. Non. Tree. Edge(v, w): if w 2 o. Nodes then // kombiniere ZHKs while dfs. Num[w] < dfs. Num[o. Reps. top()] do o. Reps. pop() backtrack(u, v): if v = o. Reps. top() then // v Repräsentant? o. Reps. pop() // ja: entferne v repeat // und offene Knoten bis v w: =o. Nodes. pop() component[w]: =v until w=v 11/3/2020 Kapitel 7 78
Starke SHKs - Beispiel e i h d g f c a o. Nodes: 11/3/2020 b b c d a ef g h i Kapitel 7 o. Reps: b c a efi d h g 79
Starke ZHKs Theorem 7. 6: Der DFS-basierte Algorithmus für starke ZHKs benötigt O(n+m) Zeit. Beweis: • init, root, traverse. Tree. Edge: Zeit O(1) • Backtrack, traverse. Non. Tree. Edge: da jeder Knoten nur höchstens einmal in o. Reps und o. Nodes landet, insgesamt Zeit O(n) • DFS-Gerüst: Zeit O(n+m) 11/3/2020 Kapitel 7 80
Ausblick Weiter mit kürzesten Wegen… 11/3/2020 Kapitel 7 81
- Datenstrukturen und algorithmen rwth
- Tu dresden algorithmen und datenstrukturen
- Aud tu bs
- Algorithmen und datenstrukturen lmu
- Datenstrukturen und algorithmen eth
- Effiziente portfolios
- Funktionsgleichung ablesen
- Graph datenstruktur
- Rekursive datenstrukturen
- Korinthisieren
- Kapitel
- Markusevangelium kapitel 10
- Das doppelte lottchen kapitel zusammenfassung
- Hiob kapitel 42
- Wie viele wörter sind das
- Markus kapitel 16
- Perfekt 1 kapitel 4
- Kapitel 5 lektion a answers
- Iso 9001 kapitel 8
- Lgr 11 kap 4
- Good pizza great pizza kapitel 3
- Emil hilft köpfe waschen
- Brief an die galater kapitel 6
- Ronja die räubertochter zusammenfassung
- Arthybride
- The australian connection zusammenfassung kapitel 7
- Im vorangegangenen kapitel
- Control kapitel
- Fliegender stern kapitel 5
- Mirjam pressler bitterschokolade zusammenfassung
- Jb 12 kap
- Fabian oder der gang vor die hunde wien
- Kallocain handling
- Elischka