Effiziente Algorithmen und Datenstrukturen I Kapitel 7 Graphen
- Slides: 81
Effiziente Algorithmen und Datenstrukturen I Kapitel 7: Graphen Christian Scheideler WS 2008 2/18/2021 Kapitel 7 1
Graphen Graph G=(V, E) besteht aus • Knotenmenge V • Kantenmenge E ungerichteter Graph 2/18/2021 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 2/18/2021 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) 2/18/2021 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 2/18/2021 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 2/18/2021 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 2/18/2021 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 2/18/2021 U |N(U)|=1 Kapitel 7 8
Lineare Liste • Grad 2 • Hoher Durchmesser (n-1 für n Knoten) • Niedrige Expansion ( (Liste) = 2/n ) 2/18/2021 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 ) 2/18/2021 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 2/18/2021 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 2/18/2021 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) 2/18/2021 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 2/18/2021 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 2/18/2021 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) 2/18/2021 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) 2/18/2021 Kapitel 7 17
Graphrepräsentationen 1. 2. 3. 4. 5. 6. Sequenz von Kanten Adjazenzfeld Adjazenzliste Adjazenzmatrix Adjazenzliste + Hashtabelle Implizite Repräsentationen 2/18/2021 Kapitel 7 18
Graphrepräsentationen 1: Sequenz von Kanten (1, 2) 2/18/2021 (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 2/18/2021 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 2/18/2021 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) 2/18/2021 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 2/18/2021 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) 2/18/2021 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 2/18/2021 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) 2/18/2021 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 2/18/2021 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) 2/18/2021 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 2/18/2021 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) 2/18/2021 Kapitel 7 30
Graphdurchlauf Zentrale Frage: Wie können wir die Knoten eines Graphen durchlaufen, so dass jeder Knoten mindestens einmal besucht wird? 2/18/2021 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 2/18/2021 Kapitel 7 32
Breitensuche • Starte von einem Knoten s • Exploriere Graph Distanz für Distanz s 2/18/2021 Kapitel 7 33
Tiefensuche • Starte von einem Knoten s • Exploriere Graph in die Tiefe ( : aktuell, : noch aktiv, : fertig) s 2/18/2021 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 2/18/2021 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 2/18/2021 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 2/18/2021 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 2/18/2021 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 2/18/2021 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 2/18/2021 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 2/18/2021 : 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. 2/18/2021 Kapitel 7 42
Tiefensuche • Starte von einem Knoten s • Exploriere Graph in die Tiefe ( : aktuell, : noch aktiv, : fertig) s 2/18/2021 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 2/18/2021 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 2/18/2021 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 ) 2/18/2021 (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. 2/18/2021 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 ) 2/18/2021 (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 ) 2/18/2021 (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 2/18/2021 Kapitel 7 50
DFS-Nummerierung Anwendung: • Erkennung eines azyklischen gerichteten Graphen (engl. DAG) Merkmal: keine gerichtete Kreise 2/18/2021 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 2/18/2021 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. 2/18/2021 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 2/18/2021 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 2/18/2021 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 2/18/2021 Kapitel 7 56
Starke ZHKs Beobachtung: Schrumpft man starke ZHKs zu einzelnen Knoten, dann ergibt sich DAG. ZHK 2/18/2021 Kapitel 7 57
Starke ZHKs - Beispiel e i h d g f c a 2/18/2021 b Kapitel 7 58
Starke ZHKs - Beispiel DAG 2/18/2021 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 2/18/2021 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 2/18/2021 Kapitel 7 61
Starke ZHKs Warum ZHKs zu einer zusammenfassbar? neue ZHK kein DAG aktueller Knoten & Kante Grund: ZHK v 2/18/2021 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? 2/18/2021 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. 2/18/2021 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. 2/18/2021 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. 2/18/2021 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 2/18/2021 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 2/18/2021 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 2/18/2021 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 2/18/2021 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 2/18/2021 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 2/18/2021 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 2/18/2021 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 2/18/2021 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 2/18/2021 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 2/18/2021 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 2/18/2021 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 2/18/2021 Kapitel 7 78
Starke SHKs - Beispiel e i h d g f c a o. Nodes: 2/18/2021 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) 2/18/2021 Kapitel 7 80
Ausblick Weiter mit kürzesten Wegen… 2/18/2021 Kapitel 7 81
- Algorithmen und datenstrukturen eth
- Datenstrukturen und algorithmen rwth
- Algorithmen und datenstrukturen tu dresden
- Tu bs algorithmen und datenstrukturen
- Algorithmen und datenstrukturen lmu
- Effizientes portfolio
- Funktionsgleichung ablesen
- Gerichteter graph
- Rekursive datenstrukturen
- Kapitel
- The australian connection zusammenfassung kapitel 7
- Im vorangegangenen kapitel
- Control kapitel
- Fliegender stern kapitel 5
- Jb kap 12
- Mirjam pressler bitterschokolade zusammenfassung
- Fabian oder der gang vor die hunde wien
- Kallocain analys
- Lena unser dorf und der krieg zusammenfassung
- Korinthisieren
- Kapitel
- Das doppelte lottchen kapitel zusammenfassung
- Markusevangelium kapitel 10
- In diesem kapitel
- Hiob kapitel 42
- 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
- Titelfigur der lindgren