Eberhard Karls Universität Tübingen Fakultät für Informations- und Kognitionswissenschaften Vorlesung: Ausgewählte Graphalgorithmen Wintersemester 2003/04 Ausgewählte Graphalgorithmen Isomorphieprobleme bei Bäumen und Graphen Rolf Niedermeier [email protected] T1 : T2 : LATEX-Bearbeitung von Julia Trieflinger, Stand 18. Februar 2004. Das Skript entstand unter Mitarbeit von Jiong Guo. Vorwort Dieses Skript beruht größtenteils auf folgendem Buch: Gabriel Valiente: Algorithms on Trees and Graphs Springer-Verlag Berlin Heidelberg 2002 Darin auftretende Ungenauigkeiten wurden zu korrigieren bzw. zu umgehen versucht. Darüberhinaus wird dem Buch nicht darin gefolgt, Algorithmen mit C++Code unter Benutzung der Algorithmen-Bibliothek LEDA“darzustellen. Die Be” nutzung von (prägnantem) Pseudo-Code schien uns adäquater. Die zweistündige Vorlesung im Wintersemester 2003/2004 an der Universität Tübingen wurde von einstündigen Übungen begleitet. Die Themenauswahl und -gewichtung mag sich in zukünftigen Vorlesungen ändern. Zuletzt noch der übliche Warnhinweis, dass ein Skript freilich kein Buch ersetzen kann. Im Skript sicherlich noch versteckte Fehler oder Unzugänglichkeiten werden gerne korrigiert und wir sind für alle Hinweise dankbar. Letztere bitte an Rolf Niedermeier per Email richten. Neben dem Valiente-Buch ist uns leider kein weiteres bekannt, das den behandelten Stoff (größtenteils) abdeckt. Auch hier sind Hinweise willkommen. Inhaltsverzeichnis I. Einführung, Grundlagen 5 1. Grundbegriffe 6 2. Grundlegende algorithmische Techniken 2.1. Das Tree-Edit-Distance - Problem . 2.2. Edit-(Gitter-)Graphen . . . . . . . . 2.3. Vier algorithmische Techniken . . . . 2.3.1. Backtracking . . . . . . . . . 2.3.2. Branch & Bound . . . . . . . 2.3.3. Divide & Conquer . . . . . . 2.3.4. Dynamisches Programmieren . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 15 15 17 21 22 24 25 26 II. Algorithmen auf Bäumen 28 3. Baumtraversierungen 3.1. Preorder-Traversierung . . 3.2. Postorder-Traversierung . 3.3. Top-Down-Traversierung . 3.4. Bottom-Up-Traversierung 3.5. Anwendungen . . . . . . . . . . . . 29 29 30 30 31 32 . . . . . . . . . . . . . 34 34 34 35 37 37 38 41 43 44 45 45 47 47 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 4. Isomorphieprobleme bei Bäumen 4.1. Baumisomorphie . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 4.1.1. Isomorphie bei geordneten Bäumen . . . . . . . . . . . . . . . . 4.1.2. Isomorphie bei ungeordneten Bäumen . . . . . . . . . . . . . . 4.2. Teilbaumisomorphie . . . . . . . . . . . . . . . . . . . . . . . . . . . . 4.2.1. Top-Down geordnete Teilbaumisomorphie . . . . . . . . . . . . 4.2.2. Top-Down ungeordnete Teilbaumisomorphie . . . . . . . . . . . 4.2.3. Bottom-Up geordnete Teilbaumisomorphie . . . . . . . . . . . . 4.2.4. Bottom-Up ungeordnete Teilbaumisomorphie . . . . . . . . . . 4.3. Größtmögliche gemeinsame Teilbäume . . . . . . . . . . . . . . . . . . 4.3.1. Größtmögliche gemeinsame Top-Down geordnete Teilbäume . . 4.3.2. Größtmögliche gemeinsame Top-Down ungeordnete Teilbäume 4.3.3. Größtmögliche gemeinsame Bottom-Up geordnete Teilbäume . 4.3.4. Größtmögliche gemeinsame Bottom-Up ungeordnete Teilbäume 3 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 4.4. Anwendungen . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 4.4.1. Algorithmische Biologie: Vergleich von Sekundärstrukturen von RNS . 4.4.2. Vergleich hierarchisch stukturierter Dokumente . . . . . . . . . . . . . 48 48 49 III. Algorithmen auf Graphen 51 5. Graphtraversierungen 5.1. DFS-Traversierung . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 5.2. BFS-Traversierung . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 52 52 54 6. Clique, Independent Set und Vertex Cover 6.1. Clique – maximal versus größtmöglich . . . . . 6.1.1. Maximale Cliquen . . . . . . . . . . . . 6.1.2. Größtmögliche Cliquen . . . . . . . . . . 6.2. Independent Set - maximal versus größtmöglich 6.3. Vertex Cover - minimal versus kleinstmöglich . 6.4. Anwendungen . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 56 57 57 58 58 59 60 7. Isomorphieprobleme bei Graphen 7.1. Graphisomorphie . . . . . . . . . . . . . . . . . . 7.2. Graphautomorphie . . . . . . . . . . . . . . . . . 7.3. Teilgraphisomorphie . . . . . . . . . . . . . . . . 7.4. Isomorphie maximaler gemeinsamer Teilgraphen 7.5. Anwendungen . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 62 62 65 66 66 69 4 Teil I. Einführung, Grundlagen 5 1. Grundbegriffe Definition: • Ein gerichteter Graph (englisch: digraph) G = (V, E) besteht aus einer endlichen Menge V von Knoten und einer endlichen Menge E ⊆ V × V von gerichteten Kanten. • Eine (gerichtete) Kante e = (u, v) heißt inzident zu u und v. Die Kanten (u, v) und (v, w) heißen adjazent (benachbart, verbunden). Vereinbarung: Anzahl der Knoten: n := |V |, Anzahl der Kanten: m := |E|. Beobachtung: Es gilt: m = O(n2 ), da die maximal mögliche Anzahl von Kanten n(n − 1)/2 ist. Beispiele /Anwendungen: ∧ ∧ 1. Knoten = Städten; Kanten = Verbindungsstraßen oder Eisenbahnlinien. Problemstellung z.B. vernünftige Strukturierung“ des Verbindungsnetzes. ” ∧ 2. Knoten = Spezies; Kante zwischen zwei Spezies, falls sie um gemeinsame Beute (Nahrung) konkurrieren (ungerichteter Graph: Wettbewerbsgraph). ∧ Knoten = Spezies; Kante von Spezies a zu b, falls a auf b Beute macht (gerichteter Graph: Food Web). Zu untersuchende Frage: Beziehung zwischen Wettbewerbsgraph und Food Web zum besseren Verständnis des zugrundeliegenden Ökosystems. ∧ 3. Knoten = Positionen / Orte in sicherheitskritischer Einrichtung (z.B. Krankenhaus); Kante von Position a nach Position b, falls b von a aus überblickt“ werden kann. ” Problemstellung z.B. Auswahl möglichst weniger Überwachungspositionen“. ” Definition: G = (V, E): • Eingangsgrad von v ∈ V : indeg(v) := |{(u, v) | (u, v) ∈ E}| • Ausgangsgrad von v ∈ V : outdeg(v) := |{(v, u) | (v, u) ∈ E}| • Grad: deg(v) := indeg(v) + outdeg(v) 6 Beobachtung: Sei G = (V, E) mit V = {v1 , . . . , vn }. Dann gilt: n X indeg(vi ) = i=1 n X outdeg(vi ) i=1 Klar, da jede Kante genau eins zu indeg und outdeg beiträgt. Definition: • Ein Weg (engl: walk) vom Knoten vi zum Knoten vj ist eine alternierende Sequenz von Knoten und Kanten [vi , ei+1 , vi+1 , . . . , vj−1 , ej , vj ], wobei ek = (vk−1 , vk ) v3 für k = i + 1, . . . , j. • Eine Spur (engl: trail) ist ein Weg ohne wiederholte Kanten. • Ein Pfad ist ein Weg ohne wiederholte Knoten. (Ausnahme: Zykel, gleicher Anfangs- und Endpunkt) v1 v2 v4 v6 v5 v7 Weg von v1 nach v7 Spur von v1 nach v3 Pfadvon v6 nach v1 • Die Länge eines Weges, einer Spur, eines Pfades ist die Anzahl der Kanten in der Sequenz. Bemerkung: Wege, Spuren und Pfade sind schon eindeutig bestimmt durch die Angabe von entweder Kanten oder Knoten. Definition: • Ein Weg, eine Spur oder ein Pfad [vi , . . . , vj ] heißt geschlossen, falls vi = vj . • Ein Kreis oder Zykel ist ein geschlossener Pfad der Länge ≥ 1. Definition: • Sei G = (V, E) und W ⊆ V . Ein Graph (W, S) heißt Teilgraph von G, falls S ⊆ E. • Der von W in G induzierte Teilgraph ist (W, E ∩ W × W ). Beispiel: v1 v2 v4 v3 v6 v5 v7 Teilgraph von W = {v1 , v2 , v4 , v6 , v7 } induzierter Teilgraph 7 Symmetrische“ gerichtete Graphen entsprechen ungerichteten Graphen:1 ” Definition: Ein Graph G = (V, E) ist ungerichtet, falls für alle v, w ∈ V gilt, dass aus (v, w) ∈ E folgt, dass (w, v) ∈ E. Bemerkung: In ungerichteten Graphen ersetzt man die gerichteten Kanten (v, w) und (w, v) in der Regel durch die ungerichtete Kante {v, w}. Dann: Grad von v : deg(v) := v | {v, w} ∈ E Definition: Die Gradsequenz eines ungerichteten Graphen mit n Knoten ist die Folge von n natürlichen Zahlen (einschließlich der Null), die durch Anordnung der Knotengrade in nichtabsteigender Reihenfolge erhalten wird2 . deg 3 deg 2 deg 2 deg 3 [2, 2, 3, 3] Definition: • Ein ungerichteter Graph G = (V, E) heißt zusammenhängend, falls es ∀ v, w ∈ V einen Weg zwischen v und w gibt. • Ein gerichteter Graph G = (V, E) heißt zusammenhängend, falls der zugrunde liegende ungerichtete Graph zusammenhängend ist. • Ein gerichteter Graph G = (V, E) heißt stark zusammenhängend, falls es ∀ v, w ∈ V einen Weg von v und w und von w nach v gibt. Bemerkung: Zusammenhang bildet eine Äquivalenzrelation über der Knotenmenge des Graphen. Definition: • Eine Zusammenhangskomponente eines ungerichteten Graphen G ist ein zusammenhängender Teilgraph von G, welcher nicht echt in einer anderen Zusammenhangskomponente von G enthalten ist. • Eine starke Zusammenhangskomponente eines gerichteten Graphen G ist ein stark zusammenhängender Teilgraph von G, welcher nicht echt in einer anderen starken Zusammenhangskomponente von G enthalten ist. 1 2 zu jeder gerichteten Kante (vi , vj ) gibt es auch eine gerichtete Kante (vj , vi ) dies ist z.B. ein Vergleichskriterium bei Isomorphietests 8 Beispiel: 1 2 5 3 6 4 7 8 9 gerichteter Graph mit 5 starken Zusammenhangskomponenten 10 Erinnerung: (Starke) Zusammenhangskomponenten können mit Hilfe von Tiefensuche in Graphen in Linearzeit ermittelt werden (siehe z.B. Vorlesung Algorithmen“ ). ” Definition: Ein ungerichteter Graph G = (V, E) heißt ungerichteter Baum, falls er zusammenhängend ist und keine Zyklen enthält. Beispiel: ein Wald zwei Bäume kein Baum Beispiel: Alle (bis auf Isomorphie) ungerichteten Bäume mit vier Knoten: Definition: Ein ungerichteter Graph G = (V, E) heißt vollständiger Graph, falls ∀ v, w ∈ V : {v, w} ∈ E. Der vollständige Graph mit n Knoten wird mit Kn bezeichnet (K steht für kompletter Graph). Jeder Knoten ist also mit allen anderen Knoten verbunden. Weitere spezielle Graphtypen (ungerichtet): • Pfadgraph P3 : • Zykelgraph C3 : • Wheel W4 : P2 : W2 : 9 K4 Definition: • Ein ungerichteter Graph G = (V, E) heißt bipartiter Graph, falls V in zwei Mengen U und W partitioniert werden kann, sodass ∀ {u, w} ∈ E : u ∈ U ∧ w ∈ W • Der Graph G heißt vollständiger bipartiter Graph, falls zusätzlich gilt, dass ∀ u ∈ U, ∀ w ∈ W : {u, w} ∈ E Der vollständige bipartite Graph mit p + q Knoten (|U | =: p, |W | =: q) wird mit Kp,q bezeichnet. Beispiel: K2,2 K4,3 K1,6 Hinweis: Bipartite Graphen sind genau diejenigen Graphen, die zweigefärbt“ werden können. ” Dabei müssen adjazente Knoten unterschiedlich gefärbt sein. Dies ist nur bei Kreisen gerader Länge oder bei Ketten möglich, sprich ein Graph ist genau dann bipartit, wenn er keine Zyklen ungerader Länge enthält (Satz von König). ist nicht bipartit, da man den Graphen ansonsten mit zwei Farben färben könnte Die Erkennung k-partiter Graphen ist für k > 2 nicht mehr trivial: Das Graphfärbungsproblem bezüglich k Farben ist für k ≥ 3 NP-vollständig. Ein planarer Graph3 ist immer 4-färbbar (Vierfarbensatz); die Frage, ob er 3-färbbar ist, ist jedoch NP-vollständig. Definition: Ein ungerichteter Graph G = (V, E) heißt regulär, falls ∀ v, w ∈ V : deg(v) = deg(w) Beispiel: Zwei reguläre Graphen mit gleicher Gradsequenz Gradsequenz [2, 2, 2, 2, 2, 2] 2 C3 3 C6 Ein planarer Graph ist ein Graph, der in der Ebene ohne Kantenüberkreuzungen gezeichnet werden kann. 10 Begriffe: • Beschriftete (labeled) Graphen: Sei G = (V, E) mit v, w ∈ V und (v, w) ∈ E. Knotenbeschriftung: G[v] Kantenbeschriftung: G[v, w] • Ein (an)geordneter (ordered) Graph ist ein Graph, bei welchem für jeden Knoten seine adjazenten Knoten in einer festen Reihenfolge angeordnet sind. Dies spielt z.B. eine Rolle, wenn Graphen in der Ebene gezeichnet bzw. eingebettet“ werden. ” Definition: • Ein zusammenhängender gerichteter Graph T = (V, E) heißt (gerichteter gewurzelter) Baum, falls der zugrundeliegende ungerichtete Graph keine Zyklen enthält und es einen ausgezeichneten Knoten r ∈ V (die Wurzel) gibt, sodass ∀ v ∈ V : ∃ einen Pfad in T von r nach v. kein Baum • Die Tiefe eines Knotens v ∈ V (depth[v]) ist die Länge des eindeutig bestimmten Pfades von der Wurzel r nach v. Tiefe von T := Maximum über alle Knotentiefen. • Ein Knoten w heißt Elternknoten (parent[v]) von v, falls (w, v) ∈ E; v heißt dann Kind von w (d.h. w ∈ children[v]). Ein kinderloser Knoten heißt Blatt. • Die Höhe des Knotens v ∈ V (height[v]) ist die Länge des längsten Pfades von v zu irgendeinem Blattknoten des in v gewurzelten Teilbaums. Satz: Ein Baum hat n − 1 Kanten bei n Knoten. Beweis: Induktion über die Knotenanzahl: IA: n = 1: Ein Knoten ⇒ keine Kante ⇒ wahr! IV: Behauptung sei wahr bei Graph mit n Knoten und n − 1 Kanten. IS: n → n + 1: Hinzufügen eines Blattes: n + 1 Knoten und n Kanten. Lemma: Sei T = (V, E) ein Baum und sei V = {v1 , . . . , vn }. Dann gilt: n X i=1 |children[vi ]| = n − 1 Beweis: Mit obigem Satz und der Beobachtung, dass jede Kante von genau einem Knoten ausgeht zu einem Kindknoten (jeder Knoten außer der Wurzel ist einmal Kind) folgt die Behauptung. 11 Definition: Sei G = (V, E) ein gerichteter Graph. Ein Teilgraph (W, S) mit S ⊆ E von G heißt aufspannender Baum (Spannbaum) von G, falls W = V und (W, S) ein Baum ist. Verallgemeinerung: Aufspannende Wälder. Bei n Knoten und m Kanten ist die obere Schranke für Spannbäume m n−1 . Beispiel: Sechs verschiedene aufspannende Bäume des links gegebenen Graphen. Beispiel: Zwölf verschiedene aufspannende Wälder des links gegebenen Graphen. Abschließende Bemerkung: Bei geordneten Bäumen erhält man in kanonischer Weise Begriffe wie • first[v]: erstes Kind“, ” • last[v]: letztes Kind“, ” • next[v]: nächster Geschwisterknoten“, ” • previous[v]: vorhergehender Geschwisterknoten“. ” 12 Darstellung von Graphen: Adjazenzmatrizen Definition: Sei G = (V, E) mit V = {v1 . . . , vn } ein gerichteter Graph mit n Knoten. Dann kann G in Form einer binären n × n Matrix, der Adjazenzmatrix repräsentiert werden, wobei jeder Eintrag in der Matrix für die Existenz (1) bzw. Nichtexistenz (0) einer Kante zischen den entsprechenden Knoten steht. Die Adjazenzmatrix A ist also eine n × n Matrix mit 1, falls (vi , vj ) ∈ E für 1 ≤ i, j ≤ n aij = 0, sonst Hauptvorteil: Schneller Adjazenztest, der in konstanter Zeit läuft. Probleme mit dieser Repräsentation: • Benötigt viel Speicherplatz (vor allem bei dünnen Graphen); Platzbedarf beträgt Θ(n2 ). • Das Hinzufügen neuer Knoten zu dem Graphen erfordert Restrukturierung / Vergrößerung der Matrix. • Im Allgemeinen ist es nicht möglich, einen Algorithmus mit O(n) Laufzeit anzugeben, da die Matrix schon Größe O(n2 ) hat. Beispiel: 1 2 3 4 0 0 A= 0 0 0 0 1 0 1 1 0 0 0 0 1 0 Adjazenzlisten Definition: Sei G = (V, E) ein gerichteter Graph mit n Knoten. Dann ist die Adjazenzlistenrepräsentation von G ein Array von n verlinkten Listen. Die zum Knoten v gehörende Liste enthält alle Knoten w mit (v, w) ∈ E. Hauptvorteil: wenig Speicherplatz, O(n + m). Probleme mit dieser Repräsentation: • Das Hinzufügen neuer Knoten erfordert Array-Vergrößerung. • Aufwändigere Bestimmung des Eingangsgrads eines Knotens. • Aufwändigerer Adjanzenztest. Beispiel: 1 3 1 2 - 3 - 3 3 4 - 2 4 2 - 4 13 Bäume Nachfolgend die zwei häufigsten Repräsentationen speziell für Bäume: Definition: Sei T = (V, E) ein Baum mit n Knoten. Die Array - von - Eltern - Repräsentation von T ist ein Array P von n Knoten (indiziert durch die Baumknoten), wobei ∀ v ∈ V : parent[v], falls v 6= root[T ] P [v] = nil, sonst Nachteile: Operationen wie bestimmte Wurzel“ oder Anzahl der Kinder eines Knotens“ ” ” benötigen im Allgemeinen O(n) Zeit. Alternativ: Definition: Sei T = (V, E) ein Baum mit n Knoten. Die Erstes-Kind / Nächster Geschwisterknoten - Repräsentation von T ist ein Paar (F, N ) von Arrays von n Knoten (indiziert durch die Baumknoten), wobei ∀ v ∈ V : first[v], falls v kein Blatt ist F [v] = nil, sonst und N [v] = next[v], falls v nicht der letzte Kindknoten ist nil, sonst Nachteile: Operationen wie z.B. parent[v], T.root(), etc. benötigen O(n) Zeit. 14 2. Grundlegende algorithmische Techniken 2.1. Das Tree-Edit-Distance - Problem Hier: Gewurzelte geordnete Bäume. Nachfolgend ist das Ziel, einen Baum T1 mittels elementarer Editoperationen in einen Baum T2 zu transformieren. Definition: 1. Seien T1 = (V1 , E1 ) und T2 = (V2 , E2 ) geordnete Bäume. Eine elementare EditOperation auf T1 und T2 ist entweder • (v, λ): das Löschen eines Blattes v ∈ V1 ; oder (Kosten z.B. 1) • (λ, w): das Hinzufügen eines (neuen) Blattes w ∈ V2 (Kosten z.B. 1) • (v, w): die Substitution eines Knotens v ∈ V1 durch w ∈ V2 ; oder (Kosten z.B. 0) 2. Eine Transformation von T1 nach T2 ist eine geordnete Relation (d.h. eine Sequenz von geordneten Paaren) E ⊆ (V1 ∪ {λ}) × (V2 ∪ {λ}), sodass: • {v ∈ V1 | (v, w) ∈ E, • {w ∈ V2 | (v, w) ∈ E, w ∈ V2 ∪ {λ}} = V1 v ∈ V1 ∪ {λ}} = V2 • ∀ v1 , v2 ∈ V1 ∪ {λ}, w ∈ V2 : (v1 , w) ∈ E, (v2 , w) ∈ E • ∀ v ∈ V1 , w1 , w2 ∈ V2 ∪ {λ} : (v, w1 ) ∈ E, (v, w2 ) ∈ E ⇔ ⇔ v1 = v2 w1 = w2 Fortlaufendes Beispiel: T1 : T2 : v1 v2 v3 w1 v5 w2 w3 v4 w4 w5 w7 w6 E = [(v1 , w1 ), (v2 , w2 ), (v3 , λ), (v4 , λ), (v5 , w3 ), (λ, w4 ), (λ, w5 ), (λ, w6 ), (λ, w7 )] ist eine von mehreren möglichen Transformationen von T1 nach T2 . 15 Achtung: Nicht jede Sequenz von elementaren Editoperationen ist zulässig“, da z.B. nur ” immer an den Blättern eingefügt und gelöscht werden darf ( ; bottom-up“). ” Ebenso zu beachten: Erhaltung der Ordnung! Definition: Seien T1 = (V1 , E1 ), T2 = (V2 , E2 ) geordnete Bäume und sei W1 ⊆ V1 und W2 ⊆ V2 . Eine Mapping von T1 auf T2 ist eine Bijektion M ⊆ W1 × W2 , sodass: • M 6= ∅ ⇒ (root[T1 ], root[T2 ]) ∈ M • ∀ Nichtwurzelknoten“ v ∈ W1 , w ∈ W2 : ” (v, w) ∈ M ⇒ (parent[v],parent[w])∈ M • ∀ (v1 , w1 ), (v2 , w2 ) ∈ M : v1 ist linker Geschwisterknoten von v2 genau dann, wenn w1 linker Geschwisterknoten von w2 ist. Fortlaufendes Beispiel: Eine Mapping für obiges Beispiel: M = {(v1 , w1 ), (v2 , w2 ), (v5 , w3 )} mit W1 = {v1 , v2 , v5 } und W2 = {w1 , w2 , w3 }. Lemma: M Mapping von T1 auf T2 Beweisidee: ⇒ ∀ (v, w) ∈ M : depth[v] = depth[w]. Induktion über die Tiefe. Definition: Seien T1 = (V1 , E1 ), T2 = (V2 , E2 ) geordnete Bäume. Eine Transformation E ⊆ (V1 ∪ {λ}) × (V2 ∪ {λ}) von T1 auf T2 heißt gültig, falls: • ∀ vi , vj : vj ist Nachfolger von vi in T1 ⇔ aus (vi , λ), (vj , λ) ∈ E ∩ (V1 × {λ}) folgt, dass (vj , λ) vor (vi , λ) in E erscheint; und • ∀ wi , wj : wj ist Nachfolger von wi in T2 ⇔ aus (λ, wi ), (λ, wj ) ∈ E ∩ ({λ} × V2 ) folgt, dass (λ, wi ) vor (λ, wj ) in E erscheint; und • E ∩ (V1 × V2 ) ist eine Mapping von T1 auf T2 . Lemma: Zwischen zwei beliebig geordneten Bäumen gibt es immer mindestens eine gültige Transformation. Beweis: Man kann immer den ganzen Baum T1 löschen und dann T2 neu aufbauen. Anmerkung: Substitution wäre also nicht nötig, ist aber interessant in Bezug auf Minimierung der Edit-Kosten. 16 Definition: Seien T1 = (V1 , E1 ), T2 = (V2 , E2 ) geordnete Bäume. Eine Kostenfunktion (γ : V1 ∪ V2 ∪ {λ}) × (V1 ∪ V2 ∪ {λ}) → R erfüllt folgende Bedingungen: γ(v, w) ≥ 0 Nichtnegative Definitheit γ(v, w) = γ(w, v) Symmetrie γ(v, w) ≤ γ(v, z) + γ(z, w) Dreiecksungleichung ; metrischer Raum1 Definition: • Die Kosten einer Transformation E von T1 auf T2 sind X γ(E) := γ(v, w). (v,w)∈E • Die Editdistanz zwischen zwei geordneten Bäumen T1 und T2 ist δ(T1 , T2 ) := min{γ(E) | E gültige Transformation von T1 nach T2 }. Fortlaufendes Beispiel: Definiere γ(λ, w) = γ(v, λ) = 1 und γ(v, w) = 0 sonst. Dann hat Transformation E = [(v1 , w1 ), (v2 , w2 ), (v3 , λ), (v4 , λ), (v5 , w3 ), (λ, w4 ), (λ, w5 ), (λ, w6 ), (λ, w7 )] die Kosten 6. Eine Transformation mit minimalen Kosten δ(T1 , T2 ) = 4 ist: E = [(v1 , w1 ), (λ, w2 ), (v2 , w3 ), (v3 , w4 ), (λ, w5 ), (λ, w6 ), (v4 , w7 ), (v5 , λ)]. Eine alternative Formulierung des Tree Edit Distance - Problems ergibt sich mittels Edit” (Gitter-)Graphen“: 2.2. Edit-(Gitter-)Graphen Definition: Seien T1 = (V1 , E1 ) und T2 = (V2 , E2 ) geordnete Bäume, wobei V1 = {v1 , . . . , vn1 } und V2 = {w1 , . . . , wn2 }. Die Knoten von T1 auf T2 seien gemäß Durchlaufreihenfolge à la Tiefensuche (Preorder) geordnet. Der Editgraph G = (V, E) von T1 und T2 hat Knoten der Form vw“ ” ∀ v ∈ V1 ∪ {v0 }, ∀ w ∈ V2 ∪ {w0 } (wobei v0 ∈ / V1 , w0 ∈ / V2 ), wobei 1. (vi wj , vi+1 wj ) ∈ E ⇔ depth[vi+1 ] ≥ depth[wj+1 ] ( vi+1 löschen“); ” 2. (vi wj , vi+1 wj+1 ) ∈ E ⇔ depth[vi+1 ] = depth[wj+1 ] tuieren“); 1 ( vi+1 → wj+1 substi” In metrischen Räumen gilt eigentlich noch die Bedingung γ(v, w) = 0 ⇔ v = w“. Wir lassen diese weg, ” um der Substitution Kosten 0 zuordnen zu können. 17 3. (vi wj , vi wj+1 ) ∈ E ⇔ depth[vi+1 ] ≤ depth[wj+1 ] ( wj+1 hinzufügen“). ” Zusätzlich: (vi w0 , vi+1 w0 ), (vi wn2 , vi+1 wn2 ), (v0 wj , v0 wj+1 ), (vn1 wj , vn1 wj+1 ) ∈ E, wobei 0 ≤ i ≤ n1 − 1 und 0 ≤ j ≤ n2 − 1. Editgraph für die zwei Bäume aus dem fortlaufendem Beispiel: Gemäß obiger Definition ergibt sich konkret folgender Editgraph: Start w w1 v0 0 w2 w3 w4 w5 w6 w7 v1 v2 v3 v4 v5 Ziel In diesem Edit-Graphen finden sich verschiedene Pfade vom Start zum Ziel, welche allesamt Transformationen von T1 zu T2 repräsentieren. Start erst T1 löschen, dann T2 aufbauen erst T2 aufbauen, dann T1 löschen kostengünstigste Möglichkeit Ziel Erklärung: Wichtig: Umbau findet gemäß Preorder-Ordnung statt unter Berücksichtigung der Baumordnungen . . . Zur Definition: 1. depth[vi+1 ] ≥ depth[wj+1 ] : Drückt aus, dass falls an wj ein Unterbaum hängt, dieser noch aufgebaut werden kann . . . Beispiel: w1 w2 w3 v3 v2 Situation: Teilpfad im Editgraph v5 v4 v0 w0 → v1 w1 → v1 w2 → v1 w3 Jetzt kann v2 nicht gelöscht werden, da gemäß Preorder-Ordnung zunächst Unterbaum von w3 aufgebaut werden muss. 18 2. depth[vi+1 ] = depth[wj+1 ] : Klar“, da aufeinander abzubildende Knoten ” gleiche Tiefe haben müssen . . . 3. depth[vi+1 ] ≤ depth[wj+1 ] : Drückt aus, dass falls an vi+1 noch ein Unterbaum hängt, dieser zuerst gelöscht werden muss (bevor wj+1 eingefügt werden kann) . . . Intuitiv: Mapping entspricht den Diagonalkanten in einem Pfad vom Start zum Ziel. Lemma: Sei P ein Pfad von der linken oberen zur rechten unteren Ecke im Edit-Graph der geordneten Bäume T1 = (V1 , E1 ) und T2 = (V2 , E2 ). Dann gilt: 1. M := {(vi+1 , wi+1 ) ∈ V1 × V2 | (vi wj , vi+1 wj+1 ) ∈ P } ist eine Mapping von T1 nach T2 . 2. Falls M ⊆ V1 × V2 eine Mapping von T1 nach T2 ist, so existiert ein Pfad P von links oben nach rechts unten im Edit-Graph von T1 und T2 , sodass {(vi+1 , wj+1 ) ∈ V1 × V2 | (vi wj , vi+1 wj+1 ) ∈ P } = M. Beweis: 1. Def. Edit-Graph a) (v1 , w1 ) ∈ / M ⇒ (v0 w0 , v1 w1 ) ∈ /P ⇒ P hat keine diagonalen Kanten ⇒ M = ∅ ist triviale Mapping von T1 auf T2 . b) (v1 , w1 ) ∈ M ⇒ root[T1 ] = v1 , root[T2 ] = w1 ⇒ (root[T1 ], root[T2 ]) ∈ M Desweiteren: i. Betrachte (vi+1 , wj+1 ) ∈ M, i, j > 0 mit vk+1 := parent[vi+1 ] und wl+1 := parent[wj+1 ]. Es gilt: depth[vi+1 ] = depth[wj+1 ] und depth[vk+1 ] = depth[wl+1 ] (*) Zu zeigen: (vk+1 , wl+1 ) ∈ M , sprich die entsprechende Diagonalkante liegt auf dem gleichen Pfad wie (vi wj , vi+1 wj+1 ) Situationsbild: w j j+1 l l+1 v k k+1 k′ i i+1 Wir zeigen: Nur die Kante (vk wl , vk+1 wl+1 ) durchdringt den schraffierten Bereich und keine andere Kante (waagrecht, senkrecht oder diagonal) durchdringt ihn. Daraus folgt dann unmittelbar, dass (vk wl , vk+1 wl+1 ) ∈ P und damit obige Behauptung. A. Angenommen es gibt (vk′ wl , vk′ wl+1 ) ∈ E, wobei k < k ′ ≤ i (∗) Def. Edit-Graph ⇒ depth[vk′ +1 ] ≤ depth[wl+1 ] ⇒ depth[vk′ +1 ] ≤ depth[vk+1 ]. Widerspruch, da depth[vk′ +1 ] > depth[vk+1 ]! (Beachte, dass i + 1 ≥ k ′ + 1 > k + 1 und Preorder!) 19 B. Angenommen es gibt (vk′ wl , vk′ +1 wl+1 ) ∈ E, wobei k < k ′ ≤ i (∗) Def. Edit-Graph ⇒ depth[vk′ +1 ] = depth[wl+1 ] ⇒ depth[vk′ +1 ] = depth[vk+1 ]. Widerspruch analog zu A. C),D) analog ii. Seien (vi+1 , wj+1 ), (vk+1 , wl+1 ) ∈ M . Dann gilt: vi+1 linker Geschwisterknoten von vk+1 ⇔ wj+1 linker Geschwisterknoten von wl+1 . Begründung: Preorder (DFS-Ordnung) der Bäume und Fakt, dass im EditGraph Kanten zu gleich bzw. höher nummerierten Knoten gehen. 2. (Idee: Falls M 6= ∅ konstruieren wir einen Pfad im Edit-Graph von links oben nach rechts unten, der nur solche diagonalen Kanten benutzt, die den Mappings von M entsprechen.) 1. Fall: M = ∅: Wegen der Konstruktion des Edit-Graphen gibt es immer zwei Pfade, die (v0 w0 , v1 w1 ) nicht benutzen und damit auch keine anderen diagonalen Kanten. w w v0 0 1 v1 2. Fall: M = {(v1 , w1 )}. Jeder Edit-Graph hat auch zwei Pfade, die von v1 w1 nach rechts unten gehen und dabei keine anderen diagonalen Kanten außer (v0 w0 , v1 w1 ) benutzen. 3. Fall: |M | ≥ 2: Aus der Definition der Mapping folgt (v1 , w1 ) ∈ M und wir nehmen die Kante (v0 w0 , v1 w1 ) in unseren Pfad. Wir haben schon früher gezeigt: ∀(vi wj ) ∈ M : depth[vi ] = depth[wj ] ⇔ Es gibt eine diagonale Kante im Edit-Graph, die von vi−1 wj−1 nach vi wj führt. Satz: Sei G der Edit-Graph für die geordneten Bäume T1 = (V1 , E1 ) und T2 = (V2 , E2 ) mit Kantengewichten γ(vi+1 , λ) für (vi wj , vi+1 wj ), γ(vi+1 , wj+1 ) für (vi wj , vi+1 wj+1 ) und γ(λ, wj+1 ) für (vi wj , vi wj+1 ). Sei P ein billigster Pfad in G von der linken oberen zur unteren rechten Ecke. Dann gilt: X δ(T1 , T2 ) = γ(x, y). (x,y)∈P Beweis: Sei E die Menge der Kanten in P . Gemäß vorigem Lemma ist E ∩ (V1 × V2 ) eine Mapping von T1 auf T2 . Man sieht leicht, dass E zu einer gültigen Transformation (an)geordnet werden kann. P Damit gilt δ(T1 , T2 ) = γ(x, y) gemäß der Definition der Editdistanz. (x,y)∈P Satz: Mit Hilfe von Editgraphen kann die Editdistanz zweier geordneter Bäume mit n1 bzw. n2 Knoten in Laufzeit O(n1 · n2 ) (und Speicherplatz O(n1 · n2 )) berechnet werden. 20 Beweis: Die Konstruktion des Editgraphen gemäß Definition benötigt O(n1 · n2 ) Zeit. Er besitzt (n1 + 1) · (n2 + 1) Knoten und höchstens 3n1 n2 + n1 + n2 Kanten. Die Berechnung billigster Wege in azyklischen, gerichteten Graphen benötigt O(n1 · n2 ) Laufzeit (siehe Vorlesung Algorithmen). Die Aussage folgt mit vorigem Satz. Rückerinnerung (billigste Wege in azyklischen, gerichteten Graphen): 1. Topologisch sortieren ( konsistent durchnummerieren“) in in Linearzeit machbar (siehe ” z.B. Vorlesung Algorithmen) 0 1 0 2 4 2 1 4 3 3 Idee: Suche jeweils Knoten mit indeg = 0, nimm ihn als nächsten“ in der topologischen ” Reihenfolge und streiche ihn. 2. Starte mit dem ersten Knoten s in topologischer Sortierung: d(s) = 0 for all v ∈ V \{s} do d(v) ← ∞ for v = s + 1 to n do top. Sort. d(v) ← min d(u) + c(u, v) | (u, v) ∈ E, u < v od Linearzeit! 2.3. Vier algorithmische Techniken • Backtracking: Systematisches Absuchen des Raumes aller möglichen Lösungen.“ ” • Branch & Bound: Hinzunahme von Kostenfunktionen erspart Durchsuchen mancher ” Teile des Lösungsraumes.“ • Divide & Conquer: Probleme in Teile zerlegen, einzeln lösen, Teillösungen etwaig ” zusammenfügen.“ • Dynamisches Programmieren: (besser: dynamisches Tabellieren) Kombiniere Lös” ungen kleinerer Probleme zu Lösungen größerer Probleme“. Vorteil: Vermeidung der mehrmaligen Wiederberechnung der Lösung ein und desselben Teilproblems. 21 2.3.1. Backtracking = Erschöpfende Suche im Raum aller möglichen Lösungen. Wichtig: Weder Verpassen noch wiederholtes Auffinden von Konfigurationen“ des Such” raums. ∧ Hier: Konfigurationen (potenzielle Lösungen) = Vektoren, wobei jede Komponente Werte aus einer geordneten Kanditatenmenge annimmt – und diese hat jeweils endliche Größe. Methode: Systematisches, schrittweites Aufbauen von Lösungen: Partielle Lösung: (a1 , a2 , . . . , ak ) ; (a1 , a2 , . . . , ak , ak+1 ). Backtracking, falls keine legale“ Ausweitung einer partiellen Lösung mehr möglich. ” Voraussetzung: Domino-Prinzip“ gilt, d.h. falls eine partielle Lösung eine Lösungsbedingung ” nicht erfüllt, so tut es auch keine Erweiterung von ihr. Backtracking beim Tree-Edit-Distance-Problem Gesucht: Transformation von geordnetem Baum T1 = (V1 , E1 ) nach T2 = (V2 , E2 ). Potenzielle Lösung: Bijektion M ⊆ W1 × W2 , W1 ⊆ V1 , W2 ⊆ V2 führt zu Zuordnung V1 → V2 ∪ {λ}: Jeder Knoten aus V1 wird entweder substituiert oder gelöscht. Implizit: Alle in obiger Zuordnung nicht auftretenden Knoten aus V2 werden hinzugefügt. Aber: Nicht jede potenzielle Lösung entspricht einer gültigen Tranformation! Denn M muss eine Mapping sein! ; Nur Knoten gleicher Tiefe einander zuordnen. ; Eltern - Kind - Relation erhalten. ; Geschwisterordnung erhalten. Allgemein: Es gibt (|V2 | + 1)|V1 | viele potenzielle Lösungen, aber nur ein Bruchteil davon führen zu einer gültigen Transformation. (In unserem durchlaufenden Beispiel gibt es 32768 potenzielle Lösungen, aber nur 12 davon sind gültig.) Konfiguration hier: Vektor (a1 , a2 , . . . , am ), wobei m := |V1 | und ai ∈ V2 ∪ {λ}, 1 ≤ i ≤ m. D.h. ai repräsentiert eine Zuordnung vi ∈ V1 zu einem Element aus V2 ∪ {λ} (Substituition oder Löschen). 22 Schema für Backtracking-Suchbaum im durchlaufenden Beispiel: T1 : T2 : v1 w1 v2 v3 v5 w2 w3 v4 w4 w7 w5 w6 ∧ Baum mit Verzweigungsgrad 8 und Tiefe 5 (85 = 32768 Transformationsmöglichkeiten) (λ) ( ) = leere Zuordnung“ ” (w1 ) (w2 ) (w3 ) (λ, λ) (w4 ) (w5 ) (w6 ) (w7 ) ··· (λ, w1 ) ··· ··· (λ, w7 ) ··· Dank des Domino-Prinzips kann viel weggeschnitten“ werden. Damit sieht der ” tatsächliche Backtracking-Suchbaum folgendermaßen aus: () w1 λ (w1 , λ) (λ, λ) (w1 , w3 ) (w1 , w2 ) (λ, λ, λ) (w1 , λ, λ) (w1 , w2 , λ) (λ, λ, λ, λ) (w1 , λ, λ, λ) (w1 , w2 , λ, λ) (λ, λ, λ, λ, λ) +λ +w2 +w3 +λ (w1 , w3 , λ) +w3 +w4 +w7 +λ +λ +λ +λ (w1 , w3 , w4 ) +λ +λ +w7 +λ (w1 , w3 , w7 ) (w1 , w3 , w7 , λ) (w1 , w3 , w7 , λ, λ) Zur Vermeidung des Hinschreibens langer Vektoren benutzen wir in obigem Bild verkürzt die Schreibweise +x“, was die Hinzufügung des Symbols x am rechten Ende des Vektors des ” Elternknoten bezeichnet. Schematische Beschreibung von Backtracking: Sei Si die geordnete Menge von Kandidatenelementen für die i-ten Elemente der Konfigurationen, d.h. für eine (partielle) Lösung (a1 , . . . , ak ) gilt, dass (a1 , . . . , ak ) ∈ S1 × . . . × Sk . 23 Prozedur Backtrack: Berechne S1 i := 1 while i > 0 do while Si 6= ∅ do ai := nächstes Element aus Si Si := Si \{ai } if (a1 , a2 , . . . , ai ) ist Lösung then Ausgabe Lösung (a1 , a2 , . . . , ai )“ ” i := i + 1 berechne Si od i := i − 1 \\ ; Backtracking! od Beachte: Beim Tree-Edit-Distance-Problem sind alle Lösungsvektoren gleich lang, d.h., dass dann das entsprechende Si+1 auf jeden Fall leer ist! Bemerkung: Backtracking wird aus Speicherplatzgründen üblicherweise mit Hilfe von Tiefensuche (und nicht Breitensuche) implementiert. 2.3.2. Branch & Bound Backtracking: Finden aller Lösungen durch systematisches Aufzählen aller Möglichkeiten“. ” Jetzt: Finden einer billigsten“ Lösung. ” Voraussetzung: Zuordnung von Kosten zu partiellen Lösungen möglich. Dazu: Erweiterung des Domino-Prinzips um die Forderung, dass jede Erweiterung einer partiellen Lösung nicht billiger ist als die ursprüngliche partielle Lösung ( Monotonie“). ” Idee: Sobald eine partielle Lösung zu keiner billigsten (bisher gefundenen) Lösung mehr ausgebaut werden kann, so erweitere diese partielle Lösung nicht mehr und brich die Suche an dieser Stelle ab; Backtrack! Anwendung beim Tree-Edit-Distance-Problem Definiere Kosten einer partiellen Lösung M ⊆ V1 × (V2 ∪ {λ}) vermöge cost[M ] := |{(v, w) ∈ M | w = λ}| 24 (Anzahl der Löschoperationen) Beispiel: () w1 λ (w1 , λ) (λ, λ) (w1 , w3 ) (w1 , w2 ) (λ, λ, λ) (w1 , λ, λ) (w1 , w2 , λ) (λ, λ, λ, λ) (w1 , λ, λ, λ) (w1 , w2 , λ, λ) (λ, λ, λ, λ, λ) +λ +w2 +w3 +λ (w1 , w3 , λ) +w3 +λ +λ +w4 +w7 +λ +λ (w1 , w3 , w4 ) +λ +λ +w7 +λ (w1 , w3 , w7 ) (w1 , w3 , w7 , λ) (w1 , w3 , w7 , λ, λ) Mit Hilfe von Branch & Bound kann man hier z.B. das erste und das letzte Blatt im Unterbaum mit Wurzel (w1 , w3 ) wegschneiden“. (Mit einer anderen Abarbeitungsreihenfolge ” (welcher?) lässt sich sogar noch viel mehr sparen.) Fazit: Mittels Branch & Bound kann der Suchbaum oft wesentlich verkleinert werden. Ein weiteres wichtiges Hilfsmittel kann die Ausnutzung von Symmetrien sein (d.h. Vermeidung der mehrfachen Erzeugung symmetrischer Lösungen). 2.3.3. Divide & Conquer Anwendungen: • Alte militärische Strategie: Eine Armee von 100.000 Mann ist schwerer zu besiegen als hintereinander zwei solche mit je 50.000 Mann. • Standardbeispiele: Quicksort, Mergesort. • Binäre Suche: ; Kinderspiel: 20 Fragen zum Erraten eines Begriffes in einem Lexikon. n 2 für gerade n. • Schnelle Exponentiation an = a 2 • Fast-Fourier-Transformation. Grundidee: Zerteile gegebenes Problem in zwei kleinere (ungefähr gleich große) Teilprobleme, löse rekursiv beide und kombiniere die gewonnen Teillösungen zur Gesamtlösung. Effizient, falls die Kombination billiger als das Lösen der Teilprobleme . . . Voraussetzung: Unabhängigkeitsprinzip“ gilt, d.h. das Problem kann in voneinander unab” hängige Teilprobleme zerlegt werden. 25 Divide & Conquer beim Tree-Edit-Distance Problem Idee: Zerteile gegebene Bäume T1 und T2 in Teilbäume, finde die billigste Transformation zwischen den Teilbäumen und kombiniere diese . . . Zum Zerteilen: Zerteile T1 vermöge v ∈ V1 in A1 und B1 und T2 vermöge w ∈ V2 in A2 und ! B2 , wobei depth[v] = depth[w] und v und w jeweils auf dem rechtesten“ Pfad ” ausgehend von der Wurzel (zum rechtesten Blatt“ hin) stehen. ” Drei Möglichkeiten: v gelöscht ⇒ A1 zu T2 transformieren w eingefügt ⇒ T1 zu A2 transformieren v durch w substituiert ⇒ A1 zu A2 und B1 zu B2 transformieren Hinweis: Bei Preorder-Ordnung kann der Teilbaum allein durch den ersten und letzten in ihm vorkommenden Knoten spezifiziert werden. Hierbei: Wahl von v und w unter gegebenen Bedingungen offen. Wünschenswert: A1 und B1 bzw. A2 und B2 möglichst gleich groß. 2.3.4. Dynamisches Programmieren Grundidee: Kleinere Lösungen zu größeren kombinieren (bottom-up); alle Zwischenergebnisse speichern (→ Mehrfachverwendung, also Wiederberechnung vermeiden). Beispiel: Rekursive Berechnung der Fibonacci-Zahlen: fib(n) = fib(n − 1) + fib(n − 2), wobei fib(n − 1) = fib(n − 2) + fib(n − 3). Damit zweifacher Aufruf. Besser iterativ von unten (bottom-up) mit fib(0), fib(1), . . . Im Gegensatz zu Divide & Conquer werden in der Regel Zwischenergebnisse mehrfach verwendet. Schematisch: Rekursiver Aufrufbaum versus Aufrufgeflecht“. ” Divide & Conquer Dynamisches Programmieren Top-Down dynamisches Programmieren: Sieh’ nach, ob kleineres Teilproblem schon gelöst ist (in Tabelle), falls nein, löse es à la Divide & Conquer. Bottom-up dynamisches Programmieren: Baue optimale Lösung kleinerer Probleme zu solchen größerer Probleme zusammen, speichere letztere. 26 Anwendung beim Tree-Edit-Distance-Problem Top-Down: Rekursive Prozedur genau wie bei Divide & Conquer, nur dass bei einem rekursiven Aufruf zunächst in einer Tabelle (einem Wörterbuch, z.B. mit HashingTabellen realisiert) nachgesehen wird, ob diese Teillösung vielleicht schon früher einmal berechnet wurde; jede gefunde Teillösung (für zwei Teilbäume) wird in der Tabelle abgespeichert. Bottom-up: Finde jeweils die günstigste Transformation vom Teilgraph von T1 mit Knoten vi , . . . , vj zu Teilgraph von T2 mit Knoten wk , . . . , wl . Dabei 1 ≤ i ≤ j ≤ n1 , n1 := |V1 | und 1 ≤ k ≤ l ≤ n2 , n2 := |V2 | für wachsende Werte von j − i und l − k, beginnend mit i = j = n1 und k = l = n2 . Beachte: Nur Lösungen mit depth[vi ] = depth[wk ] müssen betrachtet werden. Beim Finden der billigsten Transformation eines Knotens v ∈ T1 zu einem Knoten w ∈ T2 (beide in derselben Tiefe) wird zurückgegriffen auf schon berechnete billigste Transformationen zwischen den jeweiligen Unterbäumen von v bzw. w (und dabei alle möglichen Kombinationen überprüft). Bemerkung: Auch mit dynamischem Programmieren lässt sich zur Lösung des Tree-Edit-DistanceProblems eine Laufzeit quadratisch in Baumgrößen erreichen: O(n1 · n2 ). 27 Teil II. Algorithmen auf Bäumen 28 3. Baumtraversierungen 3.1. Preorder-Traversierung Prinzip: Erst Elternknoten, dann rekursiv die Kinder in der Reihenfolge von links nach rechts. Definition: Sei T = (V, E) ein Baum mit Wurzel r und n Knoten. Eine Bijektion order: V → {1, . . . , n} ist eine Preorder-Traversierung, falls gilt: • order[r] = 1, • order[first[v]] = 1 + order[v] und • order [next[v]] = size[v] + order[v]. Hierbei: ∧ • first[v] = 1. Kind von v, ∧ • next[v] = nächster (rechter) Geschwisterknoten von v, • size[v] = Anzahl der Knoten im Teilbaum mit Wurzel v. Beispiel: 1 2 3 6 4 14 7 8 5 9 15 13 16 17 18 10 11 Mitteilung: 12 Die Preorder-Traversierung ist in linearer Laufzeit durchführbar. 29 3.2. Postorder-Traversierung Prinzip: Kinder vor Eltern, Geschwister von links nach rechts. Definition: Sei T = (V, E) ein Baum mit Wurzel r und n Knoten. Eine Bijektion order: V → {1, . . . , n} ist eine Postorder-Traversierung, falls gilt: • order[r] = n, • order[last[v]] = order[v] − 1 falls v kein Blatt und • order[next[v]] = order[v] + size[next[v]] falls v nicht letztes Kind. Beispiel: 18 4 1 12 3 17 5 11 2 9 13 14 10 16 15 8 6 Mitteilung: 7 Die Postorder-Traversierung ist in linearer Laufzeit durchführbar. 3.3. Top-Down-Traversierung Prinzip: Knoten gemäß monoton wachsender Tiefe besucht. Auch Schichtenordnung oder BFS-Ordnung (Breadth First Search) genannt. Sei rank[v] := Preorder-Nummer von v. Definition: Sei T = (V, E) ein Baum mit Wurzel r und n Knoten. Eine Bijektion order: V → {1, . . . , n} ist eine Top-Down-Traversierung, falls ∀v, w ∈ V gilt: • order[v] < order[w] ⇒ depth[v] ≤ depth[w] und • (depth[v] = depth[w] und rank[v] < rank[w]) ⇒ order[v] < order[w]. Folgerung: order[r] = 1 für die Wurzel r. Widerspruchsbeweis: Annahme: order[r] > 1 ⇒ ∃ v 6= r mit order[v] = 1, dann depth[r] < depth[v]; aber es gilt order[v] < order[r] ⇒ depth[v] ≤ depth[r]. Widerspruch zu der ersten Bedingung! 30 Beispiel: 5 2 0 4 2 1 5 0 6 0 1 2 3 3 7 2 12 1 0 17 13 0 8 0 9 0 4 10 1 0 14 11 15 16 0 18 Die kleinen Zahlen geben die Höhe des jeweiligen Knotens an. Mitteilung: Die Top-Down-Traversierung ist in linearer Laufzeit durchführbar. 3.4. Bottom-Up-Traversierung Prinzip: Knoten gemäß monoton wachsender Höhe besucht. Definition: Sei T = (V, E) ein Baum mit Wurzel r und n Knoten. Eine Bijektion order: V → {1, · · · , n} ist eine Bottom-Up-Traversierung, falls ∀v, w ∈ V gilt: • order[v] < order[w] ⇒ height[v] ≤ height[w], • (height[v] = height[w] und depth[v] < depth[w]) ⇒ order[v] < order[w] und • (height[v] = height[w] und depth[v] = depth[w] und rank[v] < rank[w]) ⇒ order[v] < order[w]. Folgerung: order[r] = n für die Wurzel r. Widerspruchsbeweis: Annahme: order[r] < n ⇒ ∃v 6= r : order[v] = n. Es gilt: height[r] > height[v], aber es gilt order[r] < order[v] ⇒ height[r] ≤ height[v]. Widerspruch! Beispiel: 0 1 2 1 1 13 2 3 10 2 18 1 17 2 2 3 5 4 5 8 15 2 16 3 2 4 2 3 6 11 7 Tiefe 12 5 3 14 Höhe Höhe Höhe Höhe Höhe Höhe 9 31 5 4 3 2 1 0 Mitteilung: Die Bottom-Up-Traversierung ist in linearer Laufzeit durchführbar. 3.5. Anwendungen z.B. Tiefenbestimmung → Preorder-Traversierung Höhenbestimmung → Bottom-Up-Traversierung, Postorder-Traversierung Zeichnen von Bäumen Straight-line, layered Layout“, d.h. Kanten als Geradensegmente zeichnen und ” Knoten in Schichten gemäß ihrer Tiefe platzieren. Ästhetische Kriterien des Baumzeichnens: • Kein Knoten sollte näher an der Wurzel sein als einer seiner Vorfahren. • Knoten in gleicher Tiefe sollten auf einer horizontalen Linie liegen, Linien verschiedener Tiefen sollten parallel zueinander sein. • Relative Ordnung bei Zeichnung der Knoten einer Tiefe gemäß der TopDown-Traversierung. • In einem Binärbaum sollte ein linkes Kind links unterhalb seines Elternknotens sein und das rechte Kind rechts unterhalb. • Elternknoten sollte zentriert über den Kindern liegen. • Ein Teilbaum eines Baumes sollte immer gleich gezeichnet werden, egal wo er im Baum vorkommt. (D.h. isomorphe Unterbäume werden gleich gezeichnet, sind visuell also leichter zu erkennen.) Nun ist ein Linearzeit- und Linearplatz- Algorithmus zum Zeichnen eines Baumes in Erfüllung obiger Kriterien gesucht. Definition: Für einen gewurzelten Baum T = (V, E) und v ∈ V ist die Breite breadth[v] wie folgt definiert: 1, falls v Blatt ist P breadth[v] := breadth[v], sonst v ∈ children[v] i Die Breite eines Baumes ist dann die Breite seiner Wurzel. Folgender Algorithmus zeichnet einen Baum in einem x−y− Koordinatenfeld mit ganzzahligen Koordinaten x ≥ 0 und y ≤ 0. Algorithmus: 1. Bestimme die Tiefen aller Knoten mittels Preorder-Traversierung (oder Top-Down-Traversierung) und die Breiten mittels Postorder-Traversierung (oder Bottom-Up-Traversierung). 32 2. Setze die (x, y)−Koordinaten der Wurzel auf (0, 0). Sei v ein beliebiger Knoten: y − Koordinate :=−depth[v] x − Koordinate von parent[v], falls v erstes Kind. x−Koordinate := x − Koordinate von previous[v] + breadth[previous[v]], sonst. 3. Zentriere (jeweils mittig) im Zuge einer Postorder- oder Bottom-UpTraversierung die Elternknoten über ihren Kinderknoten. Beispiel: 9 2 1 4 1 3 1 1 1 3 2 1 Unästhetischer Baum“ ” mit Breitenangabe 1 1 1 2 1 1 Nach Phase 2: 0 1 2 3 Nach Phase 3: 4 5 6 7 8 x 0 -1 -1 -2 -2 -3 -3 -4 -4 -5 -5 y y 33 1 2 3 4 5 6 7 8 x 4. Isomorphieprobleme bei Bäumen 4.1. Baumisomorphie Im Gegensatz zu allgemeinen Graphen sind Isomorphieprobleme bei Bäumen in der Regel effizient lösbar. 4.1.1. Isomorphie bei geordneten Bäumen Definition: Zwei geordnete Bäume T1 = (V1 , E1 ) und T2 = (V2 , E2 ) heißen isomorph, falls es eine bijektive Abbildung M ⊆ V1 × V2 gibt, sodass gilt: • (root[T1 ],root[T2 ]) ∈ M , • (first[v],first[w]) ∈ M ∀ Nichtblattknoten v ∈ V1 , w ∈ V2 mit (v, w) ∈ M und • (next[v] = next[w]) ∈ M ∀ nichtletzte“ Kinder v ∈ V1 und w ∈ V2 mit ” (v, w) ∈ M . Beispiel: v1 T1 : v2 v3 v4 v6 v9 w1 w5 w6 v7 w2 w4 v8 v5 w3 T2 : w9 w7 T1 und T2 sind isomorph! w8 Algorithmus: Voraussetzung: T1 und T2 haben beide je n Knoten. 1. Nummeriere die Knoten beider Bäume (z.B.) gemäß Preorder-Traversierung. 2. M ordnet die Knoten aus T1 und T2 mit selben Nummern einander zu. 3. Überprüfe, ob die obige Definition erfüllt ist (d.h. (i, j) ∈ E1 ⇔ (i, j) ∈ E2 ). 34 Laufzeit: O(|T1 | + |T2 |) = O(n). Alle drei Schritte benötigen jeweils Linearzeit. Schritt 1. und 2.: klar. Schritt 3: Jeder Baumknoten ist höchstens zweimal Gegenstand einer der drei Vergleichsoperationen der Isomorphiedefinition. Satz: Die Isomorphie zweier geordneter Bäume lässt sich in Linearzeit testen und gegebenenfalls zugleich die Isomorphieabbildung konstruieren. 4.1.2. Isomorphie bei ungeordneten Bäumen Definition: Zwei ungeordnete Bäume T1 = (V1 , E1 ) und T2 = (V2 , E2 ) heißen isomorph, falls es eine bijektive Abbildung M ⊆ V1 × V2 gibt, sodass gilt: • (root[T1 ],root[T2 ]) ∈ M und • (parent[v],parent[w]) ∈ M ∀ Nichtwurzelknoten v ∈ V1 , w ∈ V2 mit (v, w) ∈ M . Informell: Gleichheit bis auf etwaige Permutation von Unterbäumen, die an einem Knoten hängen. Beispiel: T1 : T2 : T1 und T2 sind isomorph. Algorithmus: schichtenweise, induktiv; Voraussetzung: T1 und T2 haben je n Knoten 1. Bestimme für jeden Knoten seine Tiefe (z.B. mittels Preorder-Traversierung). 2. Ordne allen Blättern die Zahl 0 zu. 3. Induktiv: Annahme: Alle Knoten in der Tiefenschicht i haben Zahlen zugeordnet bekommen. Sortiere alle Knoten in der Tiefenschicht i von T1 bzw. T2 gemäß ihren zugeordneten Zahlen ; Listen L1 und L2 . 35 a) Ordne allen Nichtblättern von T1 in Tiefenschicht i − 1 Zahlentupel wie folgt zu: Gehe L1 gemäß der Ordnung von links nach rechts durch und füge jedem Elternknotentupel die Zahl seines jeweiligen Kindes bei. Sei S1 die derart erzeugte Sequenz von Tupeln für die Knoten von T1 in Schicht i − 1. 4. b) Analog für T2 . Erzeugt S2 . 5. Sortiere S1 und S2 zu S1′ und S2′ . 6. Falls S1′ 6= S2′ , so halte mit "T1 und T2 sind nicht isomorph“. Sonst: a) Ordne dem ersten Tupel in S1′ die Zahl 1 zu, dem zweiten verschiedenen Tupel die Zahl 2 usw. ; neue Liste L1 . Füge vorne in L1 die Blattknoten von T1 in Schicht i − 1 an. b) Analog für T2 . Gehe zu Schritt 3, falls die Wurzel noch nicht erreicht wurde. 7. Falls root[T1 ] und root[T2 ] die gleiche Zahl zugeordnet bekommen haben, so sind T1 und T2 isomorph (sonst nicht). Beispiel: (1,2) (1,2) T1 : T2 : 1 { z }| (0, 0, 0) 0 0 2 { z }| (0, 1, 1) 1 { z }| (0, 0) 0 0 0 0 2 { z }| (0, 1, 1) 1 { z }| (0, 0) 0 0 0 1 { z }| (0, 0) 1 { z }| (0, 0) 0 0 0 0 1 { z }| (0, 0, 0) 0 0 0 Satz: Die Isomorphie zweier ungeordneter Bäume lässt sich in Linearzeit testen und gegebenenfalls zugleich die Isomorphieabbildung konstruieren. Beweisskizze: Korrektheit offensichtlich“. ” Laufzeit: Der Arbeitsaufwand“ der Zuordnung von Zahlen zu Knoten in Schicht i − 1 ist ” direkt proportional zur Anzahl der Knoten in Schicht i, also Aufwand über alle Schichten O(n). Beachte: Vermöge Bucketsort (siehe Vorlesung Algorithmen) lassen sich die auftretenden Sortieroperationen in Linarzeit bewältigen. Aufwand für Blätter: O(n), Gesamtaufwand ist also O(n). 36 4.2. Teilbaumisomorphie Definition: 1. Sei T = (V, E) ein ungeordneter Baum und W ⊆ V . Ein ungeordneter Baum (W, S) heißt Teilbaum von T falls S ⊆ E. Er heißt: a) Top-Down Teilbaum, falls ∀v ∈ W , v nicht Wurzel: parent[v] ∈ W , b) Bottom-Up Teilbaum, falls ∀v ∈ W , v nicht Blatt: children[v] ⊆ W . 2. Sei T = (V, E) ein geordneter Baum und W ⊆ V . Ein geordneter Baum (W, S) heißt geordneter Teilbaum von T falls S ⊆ E und previous[v] ∈ W für alle nichtersten Kindknoten v ∈ W . Er heißt: a) Top-Down geordneter Teilbaum, falls ∀ v ∈ W , v nicht Wurzel: parent[v] ∈ W , b) Bottom-Up geordneter Teilbaum, falls ∀ v ∈ W , v nicht Blatt: children[v] ⊆ W . Beispiel: 1. : 1.a: 1.b: 2. : 2.a: 2.b: Bemerkung: Bottom-Up Teilbäume und Bottom-Up geordnete Teilbäume sind gleich (da immer alle Kinder eines Knotens im Teilbaum sind). 4.2.1. Top-Down geordnete Teilbaumisomorphie Frage: Ist T1 isomorph zu einem Top-Down geordneten Teilbaum von T2 ? Definition: Ein geordneter Baum T1 = (V1 , E1 ) heißt isomorph zu einem Top-Down Teilbaum eines geordneten Baums T2 = (V2 , E2 ), falls es eine injektive Abbildung M ⊆ V1 × V2 gibt, sodass gilt: 37 • (root[T1 ],root[T2 ])∈ M , • (first[v],first[w])∈ M für alle innere Knoten v, w mit (v, w) ∈ M und • (next[v],next[w])∈ M für alle nicht-letzten Kindknoten v, w mit (v, w) ∈ M . Beispiel: T1 : T2 : Algorithmusidee: Völlig analog zu geordneter Baumisomorphie, d.h. paralleler“ Durchlauf gemäß ” Preorder-Traversierung und Vergleich . . . Lineare Laufzeit. 4.2.2. Top-Down ungeordnete Teilbaumisomorphie Frage: Ist T1 isomorph zu einem Top-Down ungeordneten Teilbaum von T2 ? Definition: Ein ungeordneter Baum T1 = (V1 , E1 ) heißt isomorph zu einem Top-Down Teilbaum eines ungeordneten Baums T2 = (V2 , E2 ), falls es eine injektive Abbildung M ⊆ V1 × V2 gibt, sodass gilt: • (root[T1 ],root[T2 ])∈ M und • (parent[v],parent[w])∈ M für alle Nichtwurzelknoten v ∈ V1 und w ∈ V2 mit (v, w) ∈ M . Beispiel: T1 : T2 : 38 T2 : andere Möglichkeit Algorithmus: Idee: Divide & Conquer bezüglich Kinder eines Knotens. Rekursiv! Zentrale Beobachtung: Blätter können immer“ aufeinander abgebildet werden. Innere Knoten ” können aufeinander abgebildet werden, falls es Isomorphien zwischen den zugehörigen Unterbäumen gibt . . . Ohne Einschränkung betrachten wir nur das Entscheidungsproblem“. Leicht lässt ” sich nachfolgender Algorithmus verallgemeinern zur Berechnung einer etwaigen Isomorphieabbildung. Einfache rekursive Prozedur: Voraussetzung: Sei T1 [v] := Teilbaum von T1 mit Wurzel v und T2 [v] := Teilbaum von T2 mit Wurzel w. Iso(T1 , T2 ) // Entscheidet, ob T1 top-down isomorph zu einem Teilbaum // von T2 ist if T1 besteht nur aus einem Knoten und T2 besteht aus mindestens einem Knoten then YES else v ← root[T1 ] w ← root[T2 ] // children[v] = {v1 , . . . , vp } children[w] = {w1 , . . . , wq } G = (V, E) ← ({v1 , . . . , vp , w1 , . . . , wq }, ∅) for all vi ∈ children[v] do for all wj ∈ children[w] do if Iso(T1 [vi ], T2 [wj ]) then E ← E ∪ {{vi , wj }} fi od od Berechne Matching maximaler Kardinalität X des bipartiten Graphen G // (*) if |X| = p then YES else NO fi fi 39 Matching: Ein Matching maximaler Kardinalität eines bipartiten Graphen ist eine größtmögliche Teilmenge der Kantenmenge des Graphen, sodass keine zwei Kanten dieser Teilmenge einen gemeinsamen Endpunkt haben. Beispiel: w1 v1 w2 v2 w3 v3 w4 Größtmögliches Matching der Kardinalität 3 ist hier also die Kantenmenge {{v1 , w1 }, {v2 , w3 }, {v3 , w4 }} w5 Mitteilung: Matching maximaler Kardinalität eines bipartiten Graphen mit n Knoten und m √ Kanten kann in Zeit O(m n) gefunden werden. Zur Erklärung von (*) im Algorithmus: Jeder Knoten in T1 muss einem Knoten in T2 (injektiv) zugeordnet werden können. Der Graph G repräsentiert nach dem Durchlauf der beiden for-Schleifen alle Zuordnungsmöglichkeiten zwischen den Kindern zweier Kanten; falls es ein Matching mit p Kanten gibt, so kann jedem Teilbaum T1 [vi ] ein isomorpher Teilbaum in T2 [w] (top-down) zugeordnet werden. Bemerkung: Folgende Kriterien können zur (offensichtlichen) Beschleunigung der Prozedur Iso eingesetzt werden. Für alle (v, w) ∈ M (M ist die injektive Abbildung, falls T1 isomorph zu einem Top-Down-Teilbaum von T2 ist) muss gelten: • |children[v]| ≤ |children[w]|, • height[v] ≤ height[w] und • size[v] ≤ size[w]. Satz: Das Problem der Top-Down Teilbaumisomorphie zweier ungeordneter Bäume kann √ in Laufzeit O(n1 · n2 · n2 ) gelöst werden, wobei n1 die Anzahl der Knoten von T1 und n2 die Anzahl der Knoten von T2 ist. Beweisskizze: Korrektheit des obigen Algorithmus ist klar“! ” Laufzeit: Ohne Einschränkung: n1 ≤ n2 . Klar: Aufwand pro Blattknoten von T1 ist jeweils O(1). Aufwand für innere Knoten v von T1 = (V1 , E1 ) und w ∈ T2 = (V2 , E2 ): Zentral: Matching-Berechnung in einem Graphen mit |children[v]| + |children[w]| 40 = O(|children[w]|) Knoten (sonst Abbruch).pEine solche Matching-Berechnung ist in Zeit O( |children[v]| · |children[w]| · |children[w]|) möglich! {z } | max. # Kanten des bipartiten Graphen Amortisiert ergibt das folgenden Gesamtaufwand bei der Betrachtung aller (inneren) Knoten von T1 bzw. T2 : X X p O |children[v]| · |children[w]| · |children[w]| v∈V w∈V | {z }1 | {z }2 n1 n2 X X |children[w]|3/2 |children[v]| · ≤ O w∈V2 v∈V1 3/2 X X ≤ O |children[v]| · |children[w]| v∈V1 = O (n1 · n2 · w∈V2 √ n2 ) Die erwähnten Ergänzungen zum Algorithmus zur konstruktiven Ermittlung der Teilisomorphieabbildung M können leicht zusätzlich in dieser Zeit geschehen. 4.2.3. Bottom-Up geordnete Teilbaumisomorphie Frage: Ist T1 isomorph zu einem Bottom-Up geordneten Teilbaum von T2 ? Definition: Ein geordneter Baum T1 = (V1 , E1 ) heißt isomorph zu einem Bottom-Up Teilbaum eines geordneten Baums T2 = (V2 , E2 ), falls es eine injektive Abbildung M ⊆ V1 × V2 gibt, sodass gilt: • (first[v],first[w]) ∈ M für alle Nichtblattknoten v ∈ V1 und w ∈ V2 mit (v, w) ∈ M , • (next[v],next[w]) ∈ M für alle nichtletzten Kinder v ∈ V1 und w ∈ V2 mit (v, w) ∈ M und • für alle Blätter v ∈ V1 und Knoten w ∈ V2 mit (v, w) ∈ M gilt, dass w ein Blatt in T2 ist. Beispiel: T1 : T2 : 41 Algorithmusidee: Wiederholter Aufruf des Algorithmus für Isomorphieproblem auf geordnete Bäumen, jeweils mit T1 und allen in T2 auftretenden Teilbäumen, die an einer Wurzel“ ” w ∈ V2 hängen. Einfache Verbesserung der Laufzeit des obigen Algorithmus vermöge folgendes Lemmas: Lemma: Damit zwei Bottom-Up Teilbäume X1 = (W1 , S1 ) und X2 = (W2 , S2 ) von T2 isomorph zu T1 sind, muss gelten a) height[X1 ] ≤ height[X2 ] = height[T1 ], b) size[X1 ] ≤ size[X2 ] = |V1 | und c) X1 6= X2 ⇒ W1 ∩ W2 = ∅. Beweis: a) Einfacher Widerspruchsbeweis. b) Trivial, da Isomorphie. c) Widerspruchsbeweis: Sei W1 ∩ W2 6= ∅. Sei v ∈ W1 ∩ W2 mit maximaler Höhe. 1. Fall: v = root[X1 ]: Dann auch v = root[X2 ] wegen a) und X1 = X2 wegen BottomUp Eigenschaft, also Widerspruch! 2. Fall: v 6= root[X1 ]: Dann ∃ u ∈ W1 , w ∈ W2 mit (u, v) ∈ S1 und (w, v) ∈ S2 . Dann parent[v] nicht wohldefiniert, also Widerspruch! Aus obigem Lemma, Teile a) und b), folgt, dass nur Teilbäume von T2 mit entsprechender Höhe bzw. Größe als Isomorphiekandidaten“ in Frage kommen. ” Mit Hilfe der genannten Verbesserungen erhalten wir: Satz: Bottom-Up geordnete Teilbaumisomorphie kann in linearer Laufzeit gelöst werden. Beweis: Sei k die Anzahl (verschiedener) Bottom-Up geordneter Teilbäume des Baumes T2 = (V2 , E2 ), die Größe |V1 | und Höhe height[T1 ] besitzen. Obiger Algorithmus macht k Aufrufe des Algorithmus für Isomorphieproblem für geordnete Bäume, hat also Laufzeit O(k · |V1 |). Da im Beweis obigen Lemmas Punkt c) nicht benutzt wurde, dass X1 und X2 isomorph zu T1 sind, wissen wir also darüberhinaus, dass alle k Teilbäume paarweise knotendisjunkt sind. Damit folgt k · |V1 | ≤ |V2 | und damit die Behauptung. 42 4.2.4. Bottom-Up ungeordnete Teilbaumisomorphie Frage: Ist T1 isomorph zu einem Bottom-Up ungeordneten Teilbaum von T2 ? Definition: Ein ungeordneter Baum T1 = (V1 , E1 ) heißt isomorph zu einem Bottom-Up Teilbaum eines ungeordneten Baums T2 = (V2 , E2 ), falls es eine injektive Abbildung M ⊆ V1 × V2 gibt, sodass gilt: • für alle Nichtwurzelknoten v ∈ V1 und y ∈ V2 mit (parent[v],parent[y])∈ M gilt, dass (v, w) ∈ M für einen Nichtwurzelknoten w ∈ V2 mit parent[w]=parent[y] und • für alle Blätter v ∈ V1 und Knoten w ∈ V2 mit (v, w) ∈ M gilt, dass w ein Blatt in T2 ist. Beispiel: T1 : 1 6 3 2 1 9 T2 : 4 1 1 8 7 5 1 4 1 3 1 1 1 5 1 2 1 1 Im Bild sind die Äquivalenzklassen aus nachfolgendem Algorithmus mit Zahlen bezeichet. Blätter sind alle in der Äquivalenzklasse 1“. Die mit 4“ bezeichneten Knoten haben unge” ” ordnete isomorphe (Teil-)Bäume. Algorithmusidee: Zerlege V1 ∪ V2 in Äquivalenzklassen derart, dass zwei Knoten genau dann in der selben Klasse sind, wenn die an diesen Knoten hängenden Teilbäume isomorph zueinander sind. Die Lösung ergibt sich damit aus der Betrachtung der Äquivalenzklasse, die root[T1 ] enthält . . . Wie partitioniert man also V1 ∪ V2 in die beschriebenen Äquivalenzklassen? Wir benutzen ein Dictionary“ (Wörterbuch), welches gewissen Schlüsseln Äqui” valenzklassen 2,3,. . . zuordnet: Alle Blätter sind in der Äquivalenzklasse 1“. Betrachte einen Nichtblattknoten v, ” all dessen Kinder schon Äquivalenzklassen zugeordnet sind, er selbst aber noch nicht: Betrachte die sortierte Sequenz der Äquivalenzklassennummern seiner Kinder. Diese Sequenz ist der Schlüssel für das Dictionary. Schlage im Dictionary nach, ob es zu diesem Schlüssel schon einen Eintrag gibt. Falls ja, so gehört v nun in die Äquivalenzklasse, die der Eintrag bezeichnet. Falls nein, so gehört v in eine neue Äquivalenzklasse, die mit der nächstgrößeren freien“ Zahl bezeichnet wird; ” außerdem wird der entsprechende Eintrag in das Dictionary getätigt. 43 Beispiel: Dictionary nach Eintrag aller Äquivalenzklassen im obigen Beispiel. Schlüssel Äquivalenzklassennummer [1,1] 2 2 3 [1,3] 4 1 5 [1,5] 6 [1,4] 7 [1,1,5] 8 [6,7,8] 9 Bemerkung: Die Abarbeitungsreihenfolge der Baumknoten in obigem Partitionierungsprozess kann z.B. gemäß Postorder-Traversierung festgelegt werden. Basierend auf obiger algorithmischer Idee erhält man folgendes Ergebnis. Dabei kann das Dictionary z.B. durch Hashing realisiert werden. Mitteilung: Bottom-Up ungeordnete Teilbaumisomorphie kann in quadratischer Laufzeit gelöst werden. Betrachtet man das Problem eingeschränkt auf Bäume, in welchen alle Knoten nur konstant viele Kinder haben können, so ist sogar eine Lösung in erwarteter linearer Laufzeit möglich. 4.3. Größtmögliche gemeinsame Teilbäume Definition: Seien T1 = (V1 , E1 ) und T2 = (V2 , E2 ) zwei Bäume und seien X1 = (W1 , S1 ) und X2 = (W2 , S2 ) Teilbäume von T1 bzw. T2 , sodass es eine Isomorphieabbildung M ⊆ W1 × W2 zwischen beiden Teilbäumen gibt. • Der von X1 bzw. X2 bezeichnete gemeinsame Teilbaum heißt maximal, falls es keine X1′ = (W1′ , S1′ ) und X2′ = (W2′ , S2′ ) gibt, sodass W1 ( W1′ , S1 ( S1′ , W2 ( W2′ , S2 ( S2′ und es eine Isomorphieabbildung M ′ ⊆ W1′ × W2′ zwischen X1′ und X2′ gibt. • Der gemeinsame Teilbaum heißt größtmöglich, falls es keine isomorphen X1′ und X2′ gibt, sodass size[X1 ] < size[X2 ]. Beispiel: T1 : T2 : Top-Down, ungeordnete Bäume 44 maximal größtmöglich 4.3.1. Größtmögliche gemeinsame Top-Down geordnete Teilbäume Definition: Ein gemeinsamer Top-Down geordneter Teilbaum zweier geordneter Bäume T1 = (V1 , E1 ) und T2 = (V2 , E2 ) ist ein geordneter Baum T , der sowohl zu einem Top-Down geordneten Teilbaum von T1 als auch von T2 isomorph ist. Beispiel: T1 : T2 : Mitteilung: Maximale gemeinsame Top-Down geordnete Teilbäume sind zugleich auch größtmögliche und umgekehrt. Beweisidee: Rückrichtung: trivial Hinrichtung: Widerspruchsbeweis (zur Maximalität) unter zentraler Ausnutzung, dass bei geordneter Baumisomorphie vorhergehende Geschwisterknoten auch aufeinander abgebildet werden müssen. Algorithmusidee: Simultane Preorder-Traversierung beider Bäume T1 und T2 in Analogie zu TopDown geordneter (Teil-)Baumisomorphie (Abschnitte 4.1.1 und 4.2.1). Lineare Laufzeit! 4.3.2. Größtmögliche gemeinsame Top-Down ungeordnete Teilbäume Definition: Ein gemeinsamer Top-Down ungeordneter Teilbaum zweier ungeordneter Bäume T1 = (V1 , E1 ) und T2 = (V2 , E2 ) ist ein ungeordneter Baum T , der sowohl zu einem Top-Down ungeordneten Teilbaum von T1 als auch von T2 isomorph ist. Beispiel: T1 : T2 : 45 Mitteilung: Nicht alle maximalen gemeinsamen Top-Down ungeordnete Teilbäume sind größtmöglich, aber natürlich umgekehrt. Beweis durch Gegenbeispiel, siehe Beispiel S. 44. Algorithmus: Nachfolgende Prozedur bestimmt nur die Größe des größtmöglichen Teilbaums – leicht lässt sie sich derart ergänzen, dass sie den gesuchten Teilbaum auch explizit ausgibt (unter Angabe seiner Einbettung“ in T1 bzw. T2 ). Wieder bezeichnen ” T1 [v] bzw. T2 [w] die Teilbäume von T1 bzw. T2 mit Wurzel v bzw. w. Iso Größe(T1 , T2 ): if (|V1 | = 1 und |V2 | ≥ 1) oder (|V1 | ≥ 1 und |V2 | = 1) then return 1 else v ← root[T1 ]; w ← root[T2 ]; ! ! /* children[v] = {v1 , . . . , vp }, children[w] = {w1 , . . . , wq } */ G = (V, E) ← ({v1 , . . . , vp , w1 , . . . , wq }, ∅) for all vi ∈ children[v] do for all wj ∈ children[w] do E ← E ∪ {({vi , wj }, Iso Größe (T [vi ], T [wj ]))} /* Die zweite Komponente ergibt das Gewicht der Kante {vi , wj } */ od od Berechne Matching X größtmöglichen Gewichts des kantengewichteten bipartiten Graphen G. return Gewicht von X fi Obiger Algorithmus funktioniert analog zum Algorithmus für Top-Down ungeordnete Teilbaumisomorphie (s. Abschnitt 4.2.2), bloß dass es sich jetzt um ein gewichtetes Matching Problem handelt. . . Satz: Das Problem der Bestimmung eines größtmöglichen gemeinsamen Top-Down ungeordneten Teilbaums zweier ungeordneter Bäume mit n1 bzw. n2 Knoten kann in Laufzeit O ((n1 + n2 ) · (n1 n2 + (n1 + n2 ) log(n1 + n2 ))) gelöst werden. Beweisidee: Analog zum korrespondierenden Ergebnis (S. 40) für Top-Down geordnete Teilbaumisomorphie unter Benutzung eines Laufzeit O(n(m + n log n))-Algorithmus zum Auffinden eines Matchings größtmöglichen Gewichts in bipartiten, kantengewichteten Graphen mit Kantengewichten im Bereich {0, 1, . . . , max{n1 , n2 }} 46 4.3.3. Größtmögliche gemeinsame Bottom-Up geordnete Teilbäume Definition: Ein gemeinsamer Bottom-Up geordneter Teilbaum zweier geordneter Bäume T1 = (V1 , E1 ) und T2 = (V2 , E2 ) ist ein geordneter Baum T , der sowohl zu einem Bottom-Up geordneten Teilbaum von T1 als auch von T2 isomorph ist. Beispiel: 7 T1 : 5 6 4 1 1 3 3 9 1 1 1 11 10 8 2 2 1 12 T2 : 1 6 1 3 1 1 1 1 8 1 2 1 1 1 Die Zahlenbeschriftungen bezeichnen die Äquivalenzklassen gemäß nachfolgend vorgestelltem Algorithmus. Algorithmusidee: Analog wie bei Bottom-Up ungeordneter Teilbaumisomorphie (Abschnitt 4.2.4) zerlegen wir V1 ∪ V2 in Äquivalenzklassen. Anders als dort spielt hier aber die Reihenfolge der Kinder eine Rolle, bei der Bestimmung der Äquivalenzklassennummern bzw. Schlüssel wird also nicht sortiert. . . Postorder-Traversierung zur Bestimmung der Äquivalenzklassen! Der größtmögliche gemeinsame Bottom-Up geordnete Teilbaum ergibt sich dann aus äquivalenten Knoten v und w, sodass T [v] bzw. T [w] größtmöglich sind. Im obigen Beispiel: Äquivalenzklasse 6“. ” Mitteilung: Das Problem der Bestimmung eines größtmöglichen gemeinsamen Bottom-Up geordneten Teilbaums zweier geordneter Bäume mit n1 bzw. n2 Knoten kann in O(n2 · log n2 ) Laufzeit gelöst werden (wobei n1 ≤ n2 gelte). 4.3.4. Größtmögliche gemeinsame Bottom-Up ungeordnete Teilbäume Definition: Ein gemeinsamer Bottom-Up ungeordneter Teilbaum zweier ungeordneter Bäume T1 = (V1 , E1 ) und T2 = (V2 , E2 ) ist ein ungeordneter Baum T , der sowohl zu einem Bottom-Up ungeordneten Teilbaum von T1 als auch von T2 isomorph ist. 47 Beispiel: 6 T1 : 5 4 4 1 1 3 3 8 1 1 1 9 5 7 2 2 1 10 T2 : 1 4 1 3 1 1 1 1 7 1 2 1 1 1 Algorithmusidee: Wiederum Zerlegung von V1 ∪V2 in Äquivalenzklassen (vgl. Abschnitt 4.3.3), dieses Mal werden Kinder aber wieder sortiert betrachtet. . ., siehe Beispiel. Analog zum entsprechenden Ergebnis für Bottom-Up ungeordnete Teilbaumisomorphie (siehe Abschnitt 4.2.4) erhält man: Mitteilung: Das Problem der Bestimmung eines größtmöglichen gemeinsamen Bottom-Up ungeordneten Teilbaums kann in quadratischer Laufzeit gelöst werden. Eingeschränkt auf Bäume, in welchen die Kinderzahl je Knoten immer nur konstant groß ist, ist sogar eine Lösung in erwarteter linearer Laufzeit möglich. 4.4. Anwendungen 4.4.1. Algorithmische Biologie: Vergleich von Sekundärstrukturen von RNS RNS (Ribonukleinsäure) ist ein Molekül, das aus vier Typen von Nukleotiden (Basen) zusammengesetzt ist: A (Adenin), C (Cytosin), G (Guanin), U (Uracil). Die Basen A und U bzw. C und G sind jeweils komplementär zueinander, d.h. sie gehen jeweils stabile chemische Verbindungen miteinander ein. Primärstruktur von RNS: Sekundärstruktur von RNS: Zeichenkette (lineare Sequenz) über dem Alphabet {A, C, G, U } Vereinfachte, zweidimensionale Darstellung der dreidimensionalen Struktur des Moleküls, wobei manche zueinander komplementäre Basen Verbindungen eingehen (und dadurch eine Faltung im dreidimensionalen Raum (mit-)verursachen). Die Sekundärstruktur lässt sich nun wiederum ausdrücken als eine kantenannotierte“ Zei” chenkette über {A, C, G, U }, wobei die Kantenstruktur verschachtelt1 sein muss (also nicht überkreuzend sein darf). Die Kanten drücken Bindungen aus. 1 Vgl. Dyck-Sprachen (Wohlklammerung) in den formalen Sprachen. 48 Beispiel: A G C U G G C C G U verschachtelt bzw. wohlgeklammert A G C U G G C C G U nicht zulässig, da Klammerstruktur überkreuzend Nun lässt sich die verschachtelte Kantenstruktur auch als knotenbeschrifteter, geordneter Baum interpretieren. Im Beispiel: AU GC GG G GC U Somit können nun Isomorphiealgorithmen auf (geordneten) Bäumen benutzt werden um Sekundärstrukturen von RNS-Molekülen zu vergleichen. 4.4.2. Vergleich hierarchisch stukturierter Dokumente (Z.B. Source Code, Objektklassenhierachien, HTML, XML, SGML, . . .) Hierarchische Daten kann man in natürlicher Weise als (geordnete) Bäume modellieren. Z.B. bietet XML die Möglichkeit der Definition von Dokumenttypen (DTDs2 ) zur Beschreibung der Struktur von Dokumenten. Ein XML-Dokument, das die Struktur einer DTD erfüllt, heißt gültig. Wichtiges Problem: Abgleich von gegebenen Dokumentmengen gegen (eine Menge von) DTDs und Feststellung der Ähnlichkeit“ zwischen jeweiliger DTD und Dokument. ” ; Benutzung zur Dokumentklassifikation bzw. Clustering. Beispiel: Ein XML-Dokument: <product> <name> Bavaria </name> <urls> <homepage> http://.../index.html </homepage> <download> http://.../bavaria.tgz </download> </urls> <description> Mountain Bike </description> <producer> <company> Offroad Heros </company> <location> Tübingen </location> </producer> </product> 2 Document Type Definitions. 49 Zugehöriger beschrifteter, gewurzelter Baum (prinzipiell sowohl geordnet als auch ungeordnet möglich): product name Bavaria“ ” producer urls description homepage download http:. . .“ ” http:. . .“ ” company location Offroad Heros“ ” Tübingen“ ” Mountain Bike“ ” Frage: Passt“ dieses XML-Dokument zu folgender DTD? (Bzw. erfüllt“ sie diese?) ” ” ; Führt zu (Top-Down) Teilbaumisomorphieproblem. DTD: <! <! <! <! <! <! <! <! <! <! <! <! ]> DOCTYPE ELEMENT ELEMENT ELEMENT ELEMENT ELEMENT ELEMENT ELEMENT ELEMENT ELEMENT ELEMENT ELEMENT product [ product (name, urls, description, price, producer, version)> name (#PCDATA)> urls (homepage,download)> description ANY> price (#PCDATA)> producer (company, location)> version (#PCDATA)> homepage (#PCDATA)> download (#PCDATA)> company (#PCDATA)> location (#PCDATA)> Zugehöriger Baum: product name #PCDATA description urls homepage #PCDATA download price producer company ANY #PCDATA #PCDATA #PCDATA version location #PCDATA #PCDATA Obiges XML-Dokument erfüllt“ diese DTD (da Top-Down-Teilbaumisomorphie). ” 50 Teil III. Algorithmen auf Graphen 51 5. Graphtraversierungen Klar: Jeder Graphtraversierungsalgorithmus müsste aus einem Irrgarten herausfinden können. . . Effizienz: ; Systematisches Absuchen, keine Kante mehr als zweimal durchlaufen. Korrektheit: Nichts auslassen / vergessen . . . Die zwei grundlegenden Traversierungsmethoden – Tiefensuche und Breitensuche – sind Verallgemeinerungen entsprechender Verfahren auf Bäumen und wurden bereits in der Grundstudiumsvorlesung Algorithmen detailliert besprochen. Wir werden hier beide nur kurz diskutieren. Grundidee der Algorithmen: Knoten markieren, wenn sie zum ersten Mal besucht werden und wissen, was noch unterforscht blieb . . . 5.1. DFS-Traversierung Depth First Search“. Die Traversierung per Tiefensuche korrespondiert zur Preorder-Traver” sierung von Bäumen. Definition: Sei G = (V, E) ein Graph mit n Knoten, wobei G nicht zusammenhängend sein muss. Ein aufspannender Wald F von G heißt aufspannend gemäß Tiefensuche falls • ∀ T = (W, S) in F, ∀ (v, w) ∈ S ∄ (x, y) ∈ E ∩ (W × W ), sodass order[v] <order[x] <order[w] ≤order[y] und • ∀ Ti = (Wi , Si ), Tj = (Wj , Sj ) in F, i < j ∄ (v, w) ∈ E, sodass v ∈ Wi und w ∈ Wj . Hierbei ist order: W → {1, . . . , k} die Preorder-Traversierung eines gewurzelten Baumes T mit k ≤ n Knoten. Beispiel: G: DFS-Bäume (nicht Wälder) für den Graph G ausgehend von Knoten v1 : v1 v2 v3 v4 52 DFS-Bäume: v1 v1 v2 v3 v3 v4 v1 v2 v4 v1 v2 v2 v3 v4 v1 v3 v4 v3 v2 v4 Kein DFS-Baum: v1 Verletzt erstes Kriterium in obiger Definition sowohl mit (v, w) := (v1 , v3 ) und (x, y) := (v2 , v3 ) als auch mit (v, w) := (v1 , v3 ) und (x, y) := (v2 , v4 ). v2 v3 v4 Damit: Definition: Sei G = (V, E) ein Graph mit n Knoten und sei F ein G gemäß Tiefensuche aufspannender Wald. Dann heißt eine bijektive Abbildung order: V → {1, . . . , n} DFS-Traversierung von G falls für alle Bäume T = (W, S) in F die Restriktion von order auf W eine Preorder-Traversierung von T ist. Mit Hilfe eines rekursiven Algorithmus oder eines iterativen Algorithmus unter Benutzung der Datenstruktur Keller“ (→ LIFO-Prinzip) lässt sich leicht zeigen (siehe z.B. Vorlesung ” Algorithmen): Mitteilung: Eine DFS-Traversierung eines Graphen (gerichtet oder ungerichtet) kann in linearer Laufzeit bestimmt werden. Anwendungen von DFS-Traversierung unter anderem bei: • Ermittlung (starker) Zusammenhangskomponenten eines Graphen; • Überprüfung, ob ein Graph ein Baum ist oder Kreise beinhaltet; • topologisches Sortieren von gerichteten Graphen; • Zweifärben von Graphen (falls möglich); • ... 53 5.2. BFS-Traversierung Breadth First Search“. Die Traversierung per Tiefensuche korrespondiert zur Top-Down” Traversierung von Bäumen. Definition: Sei G = (V, E) ein Graph mit n Knoten, wobei G nicht zusammenhängend sein muss. Ein aufspannender Wald F von G heißt aufspannend gemäß Breitensuche falls • ∀ T = (W, S) in F, ∀ (v, w) ∈ S ∄ (x, y) ∈ E ∩ (W × W ), sodass order[x] <order[v] <order[w] ≤order[y] und • ∀ Ti = (Wi , Si ), Tj = (Wj , Sj ) in F, i < j ∄ (v, w) ∈ E, sodass v ∈ Wi und w ∈ Wj . Hierbei ist order: W → {1, . . . , k} die Top-Down-Traversierung eines gewurzelten Baumes T mit k ≤ n Knoten. Beispiel: G: BFS-Bäume (nicht Wälder) für den Graph G ausgehend von Knoten v1 : ” v1 v2 v3 v4 BFS-Bäume: v1 v2 v1 v3 v4 v3 v2 v4 v1 Kein BFS-Baum: Verletzt erstes Kriterium in obiger Definition mit (v, w) := (v3 , v4 ) und (x, y) := (v2 , v4 ). v2 v3 v4 Damit (analog zu DFS-Traversierung): Definition: Sei G = (V, E) ein Graph mit n Knoten und sei F ein G gemäß Breitensuche aufspannender Wald. Dann heißt eine bijektive Abbildung order: V → {1, . . . , n} BFS-Traversierung von G falls für alle Bäume T = (W, S) in F die Restriktion von order auf W eine Top-Down-Traversierung von T ist. Mit Hilfe eines iterativen Algorithmus unter Benutzung der Datenstruktur Schlange“ (→ ” FIFO-Prinzip) lässt sich leicht zeigen: Mitteilung: Eine BFS-Traversierung eines Graphen (gerichtet oder ungerichtet) kann in linearer Laufzeit bestimmt werden. 54 Anwendungen von DFS-Traversierung unter anderem bei: • zum Teil ähnlich wie bei DFS-Traversierung; • Ermittlung kürzester / billigster Wege; • ... Hinweis: Dijkstras Single Source billigste Wege Algorithmus und Prims Algorithmus für aufspannende Bäume kleinsten Gewichts (MSTs) benutzen der Breitensuche verwandte Ideen. Weitere Anwendung von Graphtraversierung Isomorphie geordneter, ungerichteter Graphen: Erinnerung: Ein Graph heißt geordnet, falls für jeden seiner Knoten gilt, dass seine Nachbarknoten in einer festen Reihenfolge angeordnet sind. Zwei geordnete, ungerichtete Graphen G1 = (V1 , E1 ) und G2 = (V2 , E2 ) heißen isomorph, falls es eine bijektive Abbildung M zwischen den Knotenmengen V1 und V2 gibt, sodass aus (v, w) ∈ M für v ∈ V1 und w ∈ V2 folgt, dass die geordneten Sequenzen der Nachbarn von v bzw. w bis auf etwaige zyklische Rotation übereinstimmen. Beispiel: G1 : G2 : v1 v2 v3 v4 v8 v7 v6 v5 w3 Isomorph vermöge w4 w6 w5 w7 w8 M = {(v1 , w1 ), (v2 , w2 ), . . . , (v8 , w8 )}. w2 w1 Einfacher Isomorphietest in O((n + m)m) Laufzeit, wobei n := Knotenanzahl und m := Kantenanzahl: Algorithmusidee: Für jede Kante e aus G1 als "Startkante\ und eine feste Kante ẽ aus G2 : Überprüfe, ob die "ordnungserhaltenden“ DFS-Traversierungen von G1 bzw. G2 , ausgehend von den ersten "expandierten Kanten“e bzw. ẽ, eine Knotenzuordung ergeben, die eine Isomorphieabbildung ist. Dabei: ∧ ordnungserhaltend“ = besuche (expandiere) Nachbarknoten eines ” Knoten gemäß der gegebenen Ordnung. Im Beispiel entsprachen e = {v1 , v2 } und ẽ = {w1 , w2 }. 55 6. Clique, Independent Set und Vertex Cover Alle drei hier betrachteten Probleme sind klassische NP-vollständige Probleme. Darüber hinaus sind Clique und Independent Set zugleich wohlbekannte Teilgraphisomorphieprobleme. Nachfolgend werden ausschließlich ungerichtete Graphen betrachtet. Clique: Finde eine größtmögliche Menge von Knoten in einem Graphen, sodass sie einen vollständigen Teilgraphen induzieren. Independent Set (auch Stable Set1 ): Finde eine größtmögliche ( unabhängige“) Menge von Knoten in einem Graphen, ” sodass der von ihnen induzierte Teilgraph keine Kante besitzt. Vertex Cover (auch Node Cover2 ): Finde eine kleinstmögliche ( überdeckende“) Menge von Knoten in einem Gra” phen, sodass jede Kante des Graphen mindestens einen ihrer beiden Endpunkte in dieser Menge hat. Beispiel: Graph mit Clique der Größe 4 Komplementgraph mit Independent Set der Größe 4 Vertex Cover der Größe 5 1 2 vor allem bei Mathematikern Knotenüberdeckung 56 Clique und Independent Set sind Maximierungsprobleme, Vertex Cover ist ein Minimierungsproblem. Es besteht ein enger Zusammenhang zwischen diesen drei Problemen: Ein größtmöglicher vollständiger Teilgraph in einem Graphen entspricht einer größtmöglichen unabhängigen Knotenmenge in dem Komplementgraph“ 3 . Und ein Graph mit n Knoten besitzt eine unabhängi” ge Knotenmenge der Größe k genau dann wenn er eine überdeckende Menge der Größe n − k besitzt. Da alle drei Probleme NP-vollständig sind, sind keine effizienten, exakten4 Algorithmen für sie bekannt. Darüber hinaus sind Clique und Independent Set auch schwer in Polynomialzeit zu approximieren, d.h. es gibt keine Approximationsschranken mit konstantem Approximationsfaktor für sie. Für Vertex Cover ist hingegen eine einfache Faktor-2-Approximation mit einem GreedyAlgorithmus bekannt: Solange nicht alle Graphkanten abgedeckt sind, wähle eine beliebige unabgedeckte Kante und nimm beide ihre Endknoten in die Überdeckungsmenge auf. . . Zur Lösung aller drei Probleme in der Praxis muss man sich oft mit erschöpfender Suche bzw. heuristischen Verfahren behelfen5 . 6.1. Clique – maximal versus größtmöglich Maximale Clique: Größtmögliche Clique: nicht echt in einer größeren Clique enthalten. es gibt keine (bzgl. Knotenanzahl) größere Clique! Klar: Jede größtmögliche Clique ist maximal (aber nicht notwendig umgekehrt). Beispiel: 3 1 4 2 5 7 6 Maximale Cliquen: {1, 2}, {2, 3, 7}, {4, 5, 6}, {3, 4, 6, 7}. Größtmögliche Clique: {3, 4, 6, 7}. 6.1.1. Maximale Cliquen Im Gegensatz zur Bestimmung größtmöglicher Cliquen lässt sich eine maximale Clique leicht mithilfe eines Greedy-Algorithmus finden: Starte mit beliebigen zwei mit einer Kante verbundenen Knoten und betrachte all ihre Nachbarn und nehme den ersten Knoten hinzu, der mit beiden verbunden ist. Danach suche einen Knoten, der mit allen drei schon gefundenen Knoten verbunden ist. Analog fortsetzten bis keine "Erweiterung“ mehr möglich ist. . . 3 Der Komplementgraph eines Graphen besteht aus der gleichen Knotenmenge und hat eine Kante zwischen einem Knotenpaar genau dann, wenn es im ursprünglichen Graphen keine Kante gab. 4 Unter einem exakten Algorithmus verstehen wir einen solchen, der eine optimale Lösung liefert. 5 Für Vertex Cover können auch parametrisierte Algorithmen“ helfen, siehe die gleichlautende Vorlesung. ” 57 Allerdings kann es exponentiell viele verschiedene maximale Cliquen in einem Graphen geben (; NP-hart). Mit Hilfe von Backtracking lassen sich alle maximalen Cliquen eines Graphen aufzählen. Um jede maximale Clique nur genau einmal aufzuzählen ist es hilfreich, von einer vorgegebenen Ordnung der Knoten des Graphen auszugehen . . . Übung! (Dabei lassen sich einige nützliche Beobachtungen zur Verkleinerung der Suchbaumgröße machen!) 6.1.2. Größtmögliche Cliquen Spricht man vom Clique-Problem, bezieht man sich normaler Weise immer auf die größtmöglichen Cliquen. Zu enscheiden, ob ein gegebener Graph eine Clique der Größe k für ein ebenso gegebenes k hat, ist NP-vollständig. Klar: Durch Aufzählen (in Exponenzialzeit) aller maximalen Cliquen ließen sich auch die größtmöglichen Cliquen finden! Der oben erwähnte Backtracking-Algorithmus zum Auffinden aller maximalen Cliquen lässt sich vermöge Branch & Bound in einen für praktische Zwecke oft brauchbaren (Heuristik!) Algorithmus zum Finden einer größtmöglichen Clique umfunktionieren. Dafür hilft folgende einfache Beobachtung (unmittelbar aus der Clique-Definition folgend) für G = (V, E) : |C| ≤ max{deg(v) + 1 | v ∈ V } für eine größtmögliche Clique C Bei Branch & Bound gibt dies eine Schranke für Erweiterungsmöglichkeiten an. Übung! 6.2. Independent Set - maximal versus größtmöglich Beispiel: 2 3 1 4 7 6 5 Maximale Independent Sets: Größtmögliche Independent Sets: {4, 5}, {3, 6}, {4, 6, 7}, {2, 3, 5}, {1, 2, 7}. {4, 6, 7}, {2, 3, 5}, {1, 2, 7}. Aufgrund der sehr engen Verknüpfung zwischen dem Clique- und dem Independent Set-Problem über die anfangs diskutierte Komplementgraphenbildung“ lassen sich die entsprechen” den Clique-Algorithmen auf Independent Set übertragen. 58 (Natürlich hat dieser Dualismus“ auch Grenzen, insbesondere bei speziellen Graphklassen; ” z.B. ist Clique auf planaren Graphen trivial (wie?) in Polynomialzeit lösbar aber Independent Set hingegen NP-vollständig.) Allerdings macht die Komplementgraphenbildung aus einem dünnen Graphen“ (wenige Kan” ten) einen dichten“ (viele Kanten), weshalb doch oft direkte Ansätze zum Finden größtmög” licher bzw. maximaler Independent Sets vorzuziehen sind. In Bäumen sind größtmögliche Independent Sets jedenfalls leicht zu finden: Eine größtmögliche Independent Set J eines ohne Einschränkung gewurzelten Baumes lässt sich wie folgt finden: • Alle Blätter sind in J; • Ist ein Knoten in J, so ist sein Großelternknoten v genau dann in J, falls keines dessen Kinder in J ist. Beispiel: 18 4 12 1 3 17 5 11 2 9 13 10 14 16 15 8 6 7 Eine größtmögliche Independent Set: {1, 2, 5, 6, 7, 9, 10, 13, 14, 15, 18} (in der Reihenfolge ihrer Ermittlung!). Mittels Postorder-Traversierung kann also diese Independent Set ermittelt werden. Dies ist in Linearzeit möglich, falls die Knoten nur mit einem entsprechenden booleschen Prädikat gekennzeichnet werden. 6.3. Vertex Cover - minimal versus kleinstmöglich Beispiel: 2 3 1 4 7 6 5 Minimale Vertex Covers: {1, 2, 3, 6, 7}, {1, 2, 4, 5, 7}, {1, 2, 3, 5}, {1, 4, 6, 7}, {3, 4, 5, 6}. Kleinstmögliche Vertex Covers: {1, 2, 3, 5}, {1, 4, 6, 7}, {3, 4, 5, 6}. 59 Da sich jeweils ein Vertex Cover und eine Independent Set komplementär ergänzen“ zur ” Gesamtknotenmenge des Graphen, lassen sich die Algorithmen für Independent Set auf Vertex Cover bzw. auch umgekehrt anwenden. 6.4. Anwendungen Im nachfolgenden Kapitel wird eine wichtige Anwendung des Clique-Problems auf das Finden maximaler und größtmöglicher Teilgraphen zweier ungeordneter, ungerichteter Graphen beschrieben. Hier wird eine (heuristische) Anwendung beim Sequenzalignment“ vorgestellt: ” Zunächst zum Alignment ( gegeneinander ausrichten“ ) zweier Sequenzen: ” Edit-Distance zweier Sequenzen6 (über endlichem Alphabet): ∧ = billigster“ Transformation einer Sequenz in die andere mittels elementarer ” Edit-Operationen (welchen Kosten zugeordnet sind) wie z.B. Buchstaben einfügen, Buchstaben löschen oder einen Buchstaben durch einen anderen ersetzen (Substitution). Ein Alignment zweier Sequenzen stellt eine alternative Sichtweise der Transformation einer Sequenz in eine andere dar. Beispiel: 1 E H 2 − A 3 − G 4 E E 5 V Y 6 G G 7 P G 8 K − 9 V − Miniausschnitt z.B. aus Proteinsequenzen Dieses Alignment bedeutet, dass das erste E durch H substituiert wird, A und G eingefügt werden, V durch Y , P durch G ersetzt wird und K und V gelöscht werden. Alignment zweier Sequenzen geschieht typischerweise mit Hilfe von dynamischem Programmieren in quadratischer Laufzeit O(n2 ) (n ist die Sequenzlänge). Die Verallgemeinerung des Problems auf das gleichzeitige Alignment von k Sequenzen kann dann analog in O(k · nk ) Zeit gelöst werden. Diese Laufzeit ist aber schon für recht kleine k untragbar. (Im allgemeinen führt dies sogenannte multiple Alignment“ zu einem NP-vollständigen Problem. . .) ” Deshalb alternativer (heuristischer) Ansatz: Berechne paarweise Alignments aller k2 = k(k − 1)/2 Paare von Sequenzen. Dies kostet nur“ O(k 2 · n2 ) Zeit! ” Anschließend stelle den Alignment-Graph“ wie folgt auf: ” Jede Position pro Sequenz mit einem Buchstaben (keiner Lücke) entspricht einem Knoten – dieser Knoten ist mit allen anderen zu ihm alignierten“ Knoten mit einer Kante verbunden. ” Somit erhält man einen k-partiten Graphen mit n · k Knoten und höchstens n · k · (k − 1)/2 Kanten. 6 Wir passen uns hier dem biologischen Jargon an und sprechen wider besseres Wissen von Sequenzen statt Zeichenketten (Strings). 60 Beispiel: a) b) c) 3 Sequenzen: E G E V E E G Y V P G G K G K Paarweise Alignments z.B.: a), b): − G − E E Y V G G G P − K − a), c): − E − E E V V G G − P − K K b), c): G E E E Y − − − − V G G G K ; Alignment-Graph: a) E V G P K b) G E Y G G c) E E V G K Ein multiples Alignment wird nun (z.B.) durch größtmögliche Cliquen (in einem k-partiten Graphen haben diese die Größe ≤ k) fixiert“ . . . Da es sich hier um dünne Graphen handelt, ” besteht die Hoffnung, diese Cliquen schnell zu finden. In obigem Beispiel gibt es zwei Cliquen der Größe 3. Dies führt zu dem multiplen Alignment wie folgt: − G E E E E V Y V G G G P K G − − K Bemerkung: Für die Räume zwischen den Cliquen“ (die hoffentlich klein sind) wird dann ein ” beliebiges“ Programm für multiples Alignment benutzt. Immerhin hat man dann ” das Ursprungsproblem in hoffentlich kleine Teilprobleme zerschlagen. 61 7. Isomorphieprobleme bei Graphen Isomorphiefragen treten fast überall auf, wo mit Hilfe von Graphen beschriebene Stukturen miteinander verglichen werden müssen. 7.1. Graphisomorphie Definition: Zwei (gerichtete) Graphen G1 = (V1 , E1 ) und G2 = (V2 , E2 ) heißen isomorph (i.Z. G1 ∼ = G2 ), falls es eine bijektive Abbildung M ⊆ V1 × V2 gibt, sodass ∀ vi , vj ∈ V1 ∀ wi , wj ∈ V2 : ((vi , wi ) ∈ M ∧ (vj , wj ) ∈ M ) ⇒ ((vi , vj ) ∈ E1 ⇔ (wi , wj ) ∈ E2 ) Beispiel: 5 G1 : 4 G2 : 2 2 1 5 1 3 3 4 Sind isomorph vermöge Zuordnung gleich nummerierter Knoten. Nichtisomorphie zweier Graphen wird meistens schnell entdeckt, da für isomorphe Graphen viele Bedingungen gelten müssen, so z.B. gleiche Knoten- und Kantenanzahl; gleiche Gradsequenzen; (vgl. Einführung S.8); gleiche kürzeste Wege“ Matrizen; ” gleiche Anzahl gleich großer Zyklen; gleiche Anzahl von Pfaden der Länge k, k ≥ 1; Isomorphie der Komplementgraphen und Teilgraphen. Allerdings sind obige Bedingungen nur notwendig, nicht hinreichend! Aus komplexitätstheoretischer Sicht spielt Graphisomorphie eine besondere Rolle, da für das entsprechende Entscheidungsproblem weder bekannt ist, ob es in deterministischer Polynomialzeit gelöst werden kann (also in der Komplexitätsklasse P liegt) noch ob es NP-vollständig ist. Es ist eines der wenigen bekannten natürlichen Probleme, das quasi zwischen P und NP“ liegt. Graphisomorphie und ” 62 verwandte Probleme werden mangels beweisbarer effizienter Algorithmen üblicherweise mit Backtracking-Algorithmen gelöst. Backtracking-Algorithmus für Graphisomorphie: Idee: Aufzählen aller möglichen Isomorphien durch schrittweises Ausweiten einer anfangs leeren Abbildung“ M . ” Folgende, sich direkt aus der Isomorphiedefinition ergebende Beobachtung ist hierbei hilfreich: Sei M ⊆ V × W eine Isomorphieabbildung zwischen den von V bzw. W induzierten Teilgraphen G1 [V ] von G1 bzw. G2 [W ] von G2 . Dann: ∀ v ∈ V1 \W, ∀ w ∈ V2 \W : (M ∪ {(v, w)} ist eine Isomorphieabbildung zwischen G1 [V ∪ {v}] und G2 [W ∪ {w}]) ⇐⇒ (∀ x ∈ V, y ∈ W, (x, y) ∈ M : ((x, v) ∈ E1 ⇔ (y, w) ∈ E2 ) und ((v, x) ∈ E1 ⇔ (w, y) ∈ E2 )) Klar: Die neu hinzugenommenen isomorphen Knoten“ müssen zu den bisherigen ” isomorphen Teilgraphen jeweils genau die gleiche Verbindungsstruktur haben . . . Entscheidend für einen effizienten Isomorphietest ist aber immer die Unterteilung der jeweiligen Knotenmengen beider Graphen in Äquivalenzklassen“, sodass Knoten in verschiedenen ” Klassen auf keinen Fall bei einer Isomophie aufeinander abgebildet werden dürfen. Diese Unterteilung, die in einem Vorverarbeitungsschritt geschehen kann, beruht auf den zuvor erwähnten (und weiteren) notwendigen Bedingungen für Graphisomorphie. Durch Ausnutzung dieser (in der Regel starken) Einengung der Kandidaten lässt sich so beim Backtracking viel Zeit sparen, da viele Paarungen von vornherein verworfen werden können. Backtracking am Beispiel von zuvor: v3 G1 : v4 G2 : w5 v5 v1 w2 w1 w3 v2 w4 Vereinfachte Vorverarbeitung bzgl. Knotengraden ⇒ nur v1 und w1 können aufeinander abgebildet werden! ; Backtracking-Suchbaum (schrittweise Erweiterung von M ), dank Vorverarbeitung gleich Start mit M = {(v1 , w1 )}! In der ersten Schicht des Suchbaums werden somit die Zuordnungsmöglichkeiten zu v2 , in der zweiten Schicht die zu v3 (basierend auf der jeweils festgelegten Zuordung zu v2 ) usw. untersucht, bis alle fünf Knoten von G1 abgearbeitet sind: 63 Suchbaum (Ausschnitt): w1 v1 w2 v2 w3 v3 w4 (*) w4 v4 w3 v5 w5 w3 w4 w4 w4 w5 w5 ... w4 OK (1) (2) (1) Isomorphieabbildung M = {(v1 , w1 ), (v2 , w2 ), (v3 , w3 ), (v4 , w5 ), (v5 , w4 )} (2) Isomorphieabbildung M = {(v1 , w1 ), (v2 , w2 ), (v3 , w5 ), (v4 , w3 ), (v5 , w4 )} (*) D.h. M = {(v1 , w1 ), (v2 , w2 ), (v3 , w4 )} führt zu keiner Isomorphieabbildung, da v3 eine andere Verbindungsstruktur zu v1 und v2 hat als sie w4 zu w1 und w2 hat! Hinweis: Es gibt hier insgesamt acht verschiedene Isomorphieabbildungen M , die alle mit obigem Backtracking gefunden werden können! Satz: Obiger Backtracking-Algorithmus hat O((n + 1)!) Worst-Case-Laufzeit auf zwei jeweils zusammenhängenden Graphen mit n Knoten. Beweisidee: Es gibt n! verschiedene, potenzielle Isomorphieabbildungen (→ Baumgröße). In jedem Suchbaumknoten kann die Überprüfung der Erweiterungsmöglichkeit in O(n) Zeit geschehen. Hinweis: Im Falle zweier vollständiger Graphen (Cliquen) gibt es tatsächlich n! verschiedene Isomorphieabbildungen (die der beschriebene Backtracking-Algorithmus auch findet und deshalb ist auch keine Worst-Case-Beschleunigung“ seiner Laufzeit zu ” erwarten). Nachbemerkung: Das wohl zur Zeit beste Graphisomorphietestprogramm heißt Nauty (No AUTomophismus, Yes?) und stammt von Brendan McKay. Auch dieser Algorithmus arbeitet mit Backtracking, nutzt aber noch stark gruppentheoretische Bezüge aus. 64 7.2. Graphautomorphie Definition: Ein Automorphismus eines Graphen G ist ein Graphisomorphismus zwischen G und sich selbst. Betrachtet man alle Automorphismen eines Graphen zusammen mit der Verknüpfung Hinter” einanderausführung von Abbildungen“, so erhält man die Automorphismengruppe eines Graphen. Sie gibt Auskunft über Struktur und Symmetrien eines Graphen. (Leicht ist zu überprüfen, dass die Gruppenaxiome erfüllt sind - das neutrale Element ist die identische Abbildung, die Umkehrfunktion eines Automorphismus ist auch ein Automorphismus, die Hintereinanderausführung zweier Automorphismen ergibt wieder einen Automorphismus und natürlich gilt auch das Assoziativgesetz.) Beispiele: 1. Die Automorphismengruppe des vollständigen Graphen Kn entspricht der symmetrischen Gruppe Sn und hat die Ordnung (Mächtigkeit) n!. 2. Die Automorphismengruppe des Kreisgraphen Cn , n ≥ 3, hat Ordnung 2n und besteht aus n Rotationen und n Spiegelungen. Konkret: C3 (= K3 ) 1 2 3 Automorphismen: {(1, 1), (2, 2), (3, 3)} {(1, 2), (2, 3), (3, 1)} {(1, 3), (2, 1), (3, 2)} Spiegelungen: {(1, 1), (2, 3), (3, 2)} {(1, 2), (2, 2), (3, 1)} {(1, 2), (2, 1), (3, 3)} Rotationen: Mit Hilfe der Automorphismengruppe hat man eine direkte Verbindung zur Gruppentheorie; viele neuere Ansätze für Graphisomorphietests beruhen auch auf gruppentheoretischen Algorithmen. Hierbei ist noch beachtenswert, dass beispielsweise der Test auf Isomorphie zweier Graphen im komplexitätstheoretischen Sinne polynomiell äquivalent“ ist zu dem Problem, die Ord” nung der Automorphismengruppe eines Graphen zu bestimmen. Polynomiell äquivalent heißt hierbei, dass ein Problem in deterministischer Polynomialzeit lösbar ist genau dann, wenn es das andere ist. Leider ist die Ordnungsbestimmung in deterministischer Polynomialzeit ein lange offenes Problem. 65 7.3. Teilgraphisomorphie Definition: Eine Teilgraphisomorphie eines Graphen G1 = (V1 , E1 ) in einen Graphen G2 = (V2 , E2 ) ist eine injektive Abbildung M ⊆ V1 × V2 , sodass: ∀ vi , vj ∈ V1 , ∀ wi , wj ∈ V2 : ((vi , wi ) ∈ M ∧ (vj , wj ) ∈ M ) ⇒ ((vi , vj ) ∈ E1 ⇒ (wi , wj ) ∈ E2 ) Das Teilgraphisomorphieproblem ist NP-vollständig, da es z.B. die Probleme Clique und Independent Set als Spezialfälle enthält (und freilich auch leicht mit einem nichtdeterministischen Algorithmus in Polynomialzeit entschieden werden kann). Beispiel: Für p ≤ q gibt es q!/(q − p)! viele verschiedene Teilgraphisomorphien von Kp in Kq . Ersetzt man in obiger Definition das zweite Implikationssymbol ⇒“ durch das Äquivalenz” symbol ⇔“, so spricht man von induzierter Teilgraphisomorphie. Induzierte Teilgraphi” somophieprobleme tendieren dazu, algorithmisch noch schwieriger zu sein als Teilgraphisomorphieprobleme. Beispiele: 1. Clique ist sowohl ein Teilgraphisomorphieproblem als auch ein induziertes Teilgraphisomorphieproblem. 2. Hamilton Cycle (also die Frage, ob es durch einen Graph einen einfachen Kreis gibt, der jeden Knoten genau einmal besucht) ist kein induziertes Teilgraphisomorphieproblem. Folgende einfache Beobachtung ist hilfreich für einen Backtracking-Algorithmus für Teilgraphisomorphie: Falls es eine Teilgraphisomorphie M von G1 in G2 gibt, so muss gelten: ∀ (v, w) ∈ M : deg(v) ≤ deg(w). Die Grundidee des Algorithmus ist völlig analog zu dem Fall für Graphisomorphie und besteht wiederum in der schrittweisen Ausweitung einer anfangs leeren Abbildung M mittels Backtracking. 7.4. Isomorphie maximaler gemeinsamer Teilgraphen Definition: Eine Isomorphie maximaler gemeinsamer (induzierter) Teilgraphen zweier Graphen G1 und G2 ist eine Struktur (S1 , S2 , M ), sodass 66 • S1 ein (induzierter) Teilgraph von G1 ist, • S2 ein (induzierter) Teilgraph von G2 ist, • M eine Graphisomorphie von S1 und S2 ist, • es keine S1′ ,S2′ gibt, sodass S1 ein echter (induzierter) Teilgraph von S1′ ist und S2 ein echter (induzierter) Teilgraph von S2′ ist. Man erhält eine Isomorphie größtmöglicher gemeinsamer (induzierter) Teilgraphen, wenn man in obiger Definition M als Menge auffasst und nur solche M mit maximaler Größe betrachtet. Beispiel: 1. Isomorphie größtmöglicher gemeinsamer induzierter Teilgraphen: 2. Isomorphie größtmöglicher gemeinsamer Teilgraphen: Um alle maximalen gemeinsamen induzierten Teilgraphen zweier Graphen aufzuzählen, kann man auch ihr direktes Produkt (auch Kronecker-Produkt oder Kartesisches Produkt genannt) bilden und darin nach allen maximalen Cliquen suchen. Definition: Seien G1 = (V1 , E1 ) und G2 = (V2 , E2 ) zwei Graphen. Das direkte Produkt von G1 und G2 (i.Z. G1 × G2 ) ist ein Graph G = (V, E), sodass gilt: • • V E := := Beispiel: V 1 × V2 und ((vi , wi ), (vj , wj )) ∈ V × V vi 6= vj , wi 6= wj , (vi , vj ) ∈ E1 , (wi , wj ) ∈ E2 } ∪ ((vi , wi ), (vj , wj )) ∈ V × V vi 6= vj , wi 6= wj , (vi , vj ) ∈ / E1 , (wi , wj ) ∈ / E2 } G2 : G1 : w1 w2 w3 v1 G = G1 × G2 v2 67 Definition: Sei C = (V, E) ein vollständiger Teilgraph von G1 × G2 . Dann ist die Projektion von C auf G1 derjenige Teilgraph von G1 , der durch diejenigen Knoten v von G1 induziert wird, sodass (v, w) ∈ V für einen Knoten w von G2 . Analog für Projektion auf G2 . Satz: Seien G1 = (V1 , E1 ) und G2 = (V2 , E2 ) zwei Graphen. 1. Sei (S1 , S2 , M ) eine Isomorphie maximaler gemeinsamer induzierter Teilgraphen von G1 und G2 . Dann existiert eine maximale Clique in G1 × G2 deren Projektion auf G1 bzw. G2 die Teilgraphen S1 und S2 ergibt. 2. Sei C eine maximale Clique von G1 × G2 und seien S1 bzw. S2 die Projektionen von C auf G1 bzw. G2 . Dann gibt es eine Isomorphie maximaler gemeinsamer induzierter Teilgraphen von G1 und G2 von der Form (S1 , S2 , M ). Beweis: ad 1. Sei C = (X, E) der Teilgraph von S1 × S2 , der durch X := {(v, w) ∈ V1 × V2 | (v, w) ∈ M } induziert wird. Wir zeigen zunächst, dass C eine Clique ist. Da M eine bijektive Abbildung ist, gilt für alle Knoten (vi , wi ), (vj , wj ) ∈ X mit (vi , wi ) 6= (vj , wj ) auch vi 6= vj und wi 6= wj . Weiterhin folgt aus der Isomorphie von S1 und S2 auch, dass (vi , vj ) eine Kante in S1 ist, genau dann wenn (wi , wj ) eine Kante in S2 ist, vorausgesetzt dass (vi , wi ), (vj , wj ) ∈ M . Gemäß Definition des direkten Produktes gibt es damit für alle Knotenpaare (vi , wi ), (vj , wj ) ∈ X eine Kante in C. Also ist C eine Clique. Da (S1 , S2 , M ) eine Isomorphie maximaler gemeinsamer induzierter Teilgraphen ist, folgt auch unmittelbar, dass die Projektion von C auf G1 den induzierten Teilgraph S1 und die Projektion von C auf G2 den induzierten Teilgraph S2 ergibt. Aus der Tatsache, dass M eine maximale Teilgraphisomorphie beschreibt, lässt sich nun noch leicht (per Widerspruchsbeweis) die Maximalität von C folgern. ad 2. Sei C = (X, E) eine maximale Clique von G1 ×G2 und seien S1 bzw. S2 die Projektionen von C auf G1 und G2 . Für alle (vi , wi ), (vj , wj ) ∈ X mit (vi , wi ) 6= (vj , wj ) folgt nun wieder nach Definition der Kantenbildung beim direkten Produkt, dass vi 6= vj und wi 6= wj , und ebenso dass (vi , vj ) ∈ E1 genau dann wenn (wi , wj ) ∈ E2 . Damit ist M := {(v, w) ∈ V1 × V2 | (v, w) ∈ X} eine Isomorphieabbildung zwischen S1 und S2 und damit auch (S1 , S2 , M ) eine Isomorphie gemeinsamer induzierter Teilgraphen. Die Maximalität der Isomorphie ergibt sich nun wieder leicht per Widerspruchsargument aus der Maximalität der Clique. 68 Beispiel: für ungerichtete Graphen G2 : G1 : w1 w2 v1 w3 w4 G = G1 × G2 v2 v3 v4 eine maximale Clique (eine von vielen Möglichkeiten) Beachte: Obiger Satz gilt nur für induzierte Teilgraphen! Für den Fall Isomorphie maxi” maler gemeinsamer Teilgraphen“ gibt es eine ähnliche Charakterisierung mittels maximaler Cliquen, dann muss aber das direkte Produkt der jeweiligen sogenannten Liniengraphen“ (line graphs) betrachtet werden. ” Mittels obigen Satzes kann nun ein Algorithmus zum Aufzählen maximaler Cliquen benutzt werden, um alle maximalen gemeinsamen induzierten Teilgraphen zweier Graphen aufzuzählen. 7.5. Anwendungen Die betrachteten Problemstellungen rund um Isomorphie bei Graphen können quasi als Form von Pattern Matching“ (Mustersuche) bzw. Information Retrieval auf der Ebene gra” phisch repräsentierter Strukturen gesehen werden. Wir besprechen kurz eine Anwendung zur Informationsgewinnung aus Datenbanken molekularer Graphen. 69 Beispiel: Die chemische Struktur von Koffein mit der chemischen Formel C8 H10 N4 O2 als molekularer Graph: H H O H H H C H C C N N C C C C N O H N C H H H Doppelkanten bezeichnen hierbei Doppelbindungen. Eine vereinfachte Darstellung ergibt sich durch Weglassen der Kohlenstoffatome und das vollständige Weglassen von Methylgruppen (CH3 ) bis auf die zu ihnen führenden Kanten wie folgt: O N N N O N Mit Hilfe solcher (annotierter) Graphen eröffnet sich nun die Möglichkeit zur (Teil-)Struktursuche in chemischen Datenbanken. Beachte hierbei auch, dass die chemische Formel allein nicht notwendig eindeutig das zugehörige Molekül beschreibt (→ Isomere), da sich verschiedene Strukturen (→ Graphen) bilden können. Mit Hilfe von (Teil-)Isomorphiefragestellungen können nun wieder Ähnlichkeiten etc. zwischen gegebenen Molekülen festgestellt werden. Ein wichtiges Anwendungsgebiet ist somit die kombinatorische Chemie. Weitere Anwendungen z.B.: • Algorithmische Biologie: Vergleich von zwei- bzw. dreidimensionalen Proteinstrukturen oder Suche nach Strukturmotiven“; ” • Bildanalyse und -verarbeitung, Musterkennung; • automatische Verifikation ; Detektion von Symmetrien; • Graphgrammatiken, Graphtransformationen. 70