Stefan Edelkamp Web-Suche 1 Überblick Suffixtries Suffixbäume Algorithmus von McCreight Generalisierten Suffixbäume Suffix-Arrays Überblick 1 2 Suffixbäume Suffixtrie: alle Worte werden um ein $ erweitert und die Suffixe von W in eine Mehrwegsuchbaum eingefügt Komplexität: W besitzt |W | unterschiedliche Endstücke und String | 2 ) unterschiedlichen Zeichen insgesamt |W ∈ Ω(|W | 2 Suffixbäume 2 Ein Suffixtrie für den String 11010$ 0 1 $ 1 0 $ $ 0 $ 1 0 1 0 1 $ 0 $ Suffixbäume 3 Definierende Eigenschaft Theorem Jeder Knoten im Suffixtrie für W entspricht genau einem der unterschiedlichen Teilstrings von W . Beweis Sicherlich entspricht jeder Knoten im Suffixtrie mindestens einem Teilstring von W , da er durch ein Anfangsstück eines Suffixes von W erreicht werden kann. Unterschiedliche Zeichenketten führen in einem Mehrwegsuchbaum aber auch zu unterschiedlichen Knoten. Leider gibt es für den Suffixtrie für W noch immer Beispiele mit Ω(|W |2) vielen Knoten. Beispiel Zeichenketten der Form 1k 0k $ haben die Länge 2k + 1 und k2 + 4k + 2 voneinander unterschiedliche Teilstrings. Suffixbäume 4 Suffixbäume Suffixbaum: kompakte Darstellungsform eines Suffixtries, in dem jeder Knoten mit nur einem Nachfolger mit seinem Elternteil verschmolzen ist. Patricia-Baum: die durch die Elimination von Knoten mit Grad 2 gewonnene Struktur Patricia = (Morrison) practical algorithm to retrieve information coded in alphanumeric. Weiner: erster, der einen expliziten Index für alle unterschiedlichen Teilstrings eines gegebenen Strings angab Suffixbäume 5 Ein Suffixbaum für den String 11010$ 0 1 $ α aα (3,3) (6,6) 10$ $ (4,6) 0 (6,6) (1,1) $ Suffixlink (6,6) 1010$ (3,3) 10$ (4,6) (2,6) Jeder Knoten im Suffixbaum für W hat mehr als einen Nachfolger und W viele Blätter. Komplexität: Kantenbeschriftungen werden als Intervall des zugrundeliegenden Strings an den Knoten verwaltet, auf dem die Kante einläuft ⇒ O(|W |) Platz Suffixbäume 6 Definitionen Partieller Weg: zusammenhängende, bei der Wurzel beginnende Folge von Kanten Weg: partieller Weg, der bei einem Blatt endet Ort einer Zeichenkette α: Knoten im Suffixbaum am Ende des mit α bezeichneten Weges (falls existiert) Erweiterung einer Zeichenkette α: jede Zeichenkette mit Präfix α Erweiterter Ort von α: Ort der kürzesten Erweiterung von α, deren Ort definiert ist Kontraktierter Ort von α: Ort des längsten Präfixes von α, dessen Ort definiert ist Suffixbäume 7 Notation sufi: an Position i beginnendes Suffix von W , also z.B. suf = W . headi: längste Präfix von sufi, der auch Präfix von sufj für ein j < i ist und String taili festgelegt als sufi − headi, d.h. also sufi = headitaili. Beispiel Sei W = ababc, dann suf = abc, head3 = ab, und tail3 = c. T0 = T1 = T2 = ababc ababc Suffixbäume babc 8 Definierende Eigenschaft Theorem Jeder innere Knoten t im Suffixbaum für W entspricht dem größten gemeinsamen Präfix zweier Suffixe von W Die diese Suffixe beschreibenden Blätter finden sich in zwei unterschiedlichen Zweigen des Teilbaumes zu t Suffixbäume 9 Beweis Der größte gemeinsame Präfix p von sufi und sufj von W ist Teilstring von sufi und sufj und bildet einen Knoten t im Suffixtrie Präfixeigenschaft von p ⇒ Blätter für sufi und sufj im Teilbaum von t, Annahme: t wird durch die Kontraktion gelöscht ⇒ t hat nur einen Nachfolger t0, der eine Erweiterung p0 von p repräsentiert p0 ist jedoch Präfix von sufi und sufj - Widerspruch zu p größte gemeinsame Präfix Analog: sufi und sufj in unterschiedlichen Zweigen zu t Suffixbäume 10 Konstruktion von Suffix-Bäumen Slisenko et al. und Chen et al.: Erweitern Indexgedanken Weiners McCreight: Speicherplatzfreundliche Konstruktion des Suffixbaumes Suffixlink: Ort einer Zeichenkette aα, a ∈ Σ, α ∈ Σ∗ zeigt auf den Ort von α und wird als als Abkürzung bei der Baumkonstruktion verwendet Ukkonen: Linearzeitalgorithmus für Aufbau kürzesten zu längsten Suffixbäume 11 Naives Verfahren beginnt mit leeren Baum T0. Ti+1 entsteht aus Ti durch Einfügen von sufi+. Algorithmus Suffixbaum Input: Eine Zeichenkette W; Output: Der Suffixbaum T von W; begin n := |W |; T0 := ∅; for i := 0 to n − 1 füge sufi+ in Ti ein Theorem Es ist headi der längste Präfix von sufi, dessen erweiterter Ort in Ti−1 existiert Suffixbäume 12 Beweis In Ti haben alle Suffixe sufj , j < i bereits einen Ort. Zur Einfügung von sufi kann Ti+1 kann aus Ti wie folgt konstruiert werden: 1. Man bestimme den erweiterten Ort von headi+1 in Ti und teile die letzte zu diesem Ort führende Kante in zwei neue Kanten auf durch Einfügen eines neuen Knotens. 2. Man schaffe ein neues Blatt als Ort für sufi+. Offenbar sichert das eindeutige Endesymbol $, dass stets taili 6= ε ist. Suffixbäume 13 Visualisierung headi+1 v x = erweiterter Ort von headi+1 taili+1 x Beispiel T3 T2 ababc head3 = ab tail3 = c ab babc abc babc c Es gibt Beispiele, für die der oben beschriebene Algorithmus Ω(n2) viele Schritte benötigt, um einen Suffixbaum zu konstruieren. Suffixbäume 14 3 Algorithmus von McCreight Der von McCreight zur Konstruktion eines Suffixbaumes benötigt nur linear viele Schritte Wenn der erweiterte Ort von headi+1 in Ti gefunden ist, kann das Erzeugen eines neuen Knotens und das Aufspalten einer Kante in konstanter amortisierter Zeit geschehen. 2 Phasen: 1. Bestimme headi+1 in konstanter amortisierter Zeit in Ti 2. Füge zusätzliche Suffixlinks ein Algorithmus von McCreight 15 Zentrale Eigenschaft Lemma 1 Wenn headi = aγ für ein Symbol a und eine (evtl. leere) Zeichenkette γ ist, dann ist γ ein Präfix von headi+1. Beweis: Sei headi = aγ, dann existiert ein j < i, so dass aγ Präfix von sufi und sufj ist nach der Definition von headi. Also ist γ ein Präfix sowohl von sufi+ als auch von sufj+. Beachte: Ort von γ kann nie im Teilbaum mit Wurzel beim Ort von aγ liegen, da in diesem Teilbaum nur Erweiterungen von aγ liegen Algorithmus von McCreight 16 Invarianten des Algorithmus’ (I1) Alle inneren Knoten von Ti−1 haben einen korrekten Suffix-Zeiger in Ti. (I2) Bei der Konstruktion von Ti wird der kontraktierte Ort von headi in Ti−1 besucht. Offensichtlich gelten beide Bedingungen für i = 1. Ist i > 1, so folgt aus (I2), dass man die Konstruktion von Ti+1 aus Ti beim kontraktierten Ort von headi in Ti−1 beginnen kann. Algorithmus von McCreight 17 Nomenklatur headi 6= ε ⇒ αi die Konkatenation der Kantenbeschriftungen des Weges zum kontraktierten Ort von headi ohne den ersten Buchstaben ai. βi = headi − aiαi, d.h. headi = aiαiβi. headi 6= ε: Ti: headi αi ai αi v0 u βi w γi+1 x y βi v sufi v 0 = kontraktierter Ort von headi in Ti−1 v = Ort von headi in Ti einzufügender Suffix-Zeiger für headi Obiges Lemmas ⇒ headi+1 = αiβiγi+1. Algorithmus von McCreight 18 Schritt 1: Einfügen des Ortes von headi+1 1. Folge dem Suffix-Zeiger vm kontr. Ort v 0 von headi zu dem Knoten u. 2. βi 6= ε ⇒ rescan βi in Ti, d.h. folge einem βi - Weg in Ti ausgehend von u 1. Ort w von αiβi in Ti existiert ⇒ Scan γi+1 ausgehend von w, bis man aus dem Baum bei der Kante (x, y) herausfällt. 2. Ort w von αiβi in Ti existiert nicht: Sei x der kontr. Ort von αiβi und y der erw. Ort von αiβi. Es ist headi+1 = αiβi (s.u.). 3. Schaffe bei (x, y) einen inneren Knoten z für den Ort von headi+1 und ein Blatt für den Ort von sufi+. Algorithmus von McCreight 19 2: Einfügen Suffix-Zeigers für Ort v von headi 1. Folge Suffix-Zeiger vom kontr. Ort v 0 von headi zu u. 2. βi 6= ε ⇒ rescan βi in Ti bis zum Ort w von αiβi. Setze den Suffix-Zeiger des Ortes v von headi auf w. Implementation: verflechte Schritt 1 und 2 headi : headi+1 : ai αi βi αi βi u γi+1 w Phase II Phase III Rescanning“ ” Scanning“ ” Lemma: Ort von αiβi in Ti existiert nicht ⇒ headi+1 = αiβi, d.h. γ[i + 1] = ε Algorithmus von McCreight 20 Beweis v: kontr.; w: erw. Ort von αiβi. γ Beschriftung der Kanten des Weges zu v δ1δ2 mit δ1, δ2 6= ε und γδ1 = αiβi: Beschriftung von (v, w) 1. alle Suffixe mit Präfix αiβi sind in dem Teilbaum von T mit Wurzel w enthalten und 2. alle Suffixe in T haben das Präfix αiβiδ2. ⇒ j < i + 1 und sufj hat das Präfix αiβi Somit hat sufj den Präfix αiβiδ2. Wir zeigen: sufj = αiβia · · · und sufi+ = αiβib · · · mit a 6= b. Algorithmus von McCreight 21 Beweis (ctd.) Sei sufj 0 ein Suffix mit Präfix headi = aiαiβi. ⇒ sufj 0+ hat Präfix αiβiδ2 hat Präfix aiαiβiδ2 ⇒ sufj 0 Da headi = aiαiβi, ist der erste Buchstabe a von δ2 von dem ersten Buchstaben b, der aiαiβi in sufi folgt, verschieden. ⇒ Präfix von sufi+: αiβib ⇒ Präfix von sufj : αiβia. ⇒ Längstes gemeinsames Präfix: αiβi. Algorithmus von McCreight 22 Beispiel W = b5abab3a2b5c. Konstruktion von T14 aus T13 durch Einfügen von suf = bbbbbc in T13. a u b a... b a 0 b v a b bb w a... head13 v a bbc x b a ba... a y head13 = a|b|bb head14 = b|bb|.?. suf = bbbbbc b w x z b a Ort von head14 c a... y suf Algorithmus von McCreight 23 Analyse: Algorithmus von McCreight Theorem Algo liefert in Zeit O(|W |) einen Suffixbaum für W Beweis In jeden Schritt wird ein Suffix von W gescannt und regescannt. Algorithmus von McCreight 24 Analyse Rescannen Da αiβi Präfix von headi+1, muss nur festgestellt werden, um wieviele Zeichen wir in βi vorrücken müssen ⇒ konstante Zeit pro besuchte Kante ⇒ # Schritte beim Rescannen ist proportional zur # besuchten Kanten. Zeichen, die regescannt werden können: resi = βi−1γitaili Bei jeder Kante e, um die während des Rescannens von βi−1 vorgerückt wird, wird αi um die Beschriftung δ der Kante e länger, d.h. δ ist in resi, aber nicht in resi+1. Da |δ| ≥ 1: |resi+1| ≤ |resi| − ki mit ki = # regesannte Kanten in Schritt i ⇒ n X ki ≤ i=1 Algorithmus von McCreight n X |resi| − |resi+1| = |res1| − |resn+1| ≤ n. i=1 25 Analyse Scannen # gescannter Zeichen in Schritt i gleich |γi+1|, wobei |γi+1| = |headi+1| − |αiβi| = |headi+1| − (|headi| − 1) . ⇒ Gesamtanzahl gescannter Zeichen: n−1 X i=0 |γi+1| = n−1 X |headi+1| − |headi| + 1 = n + |headn| − |head0| = n. i=0 Algorithmus von McCreight 26 Beispiel Suffixbaum für bbabaabc: T0 T1 suf 1 T2 b bbabaabc bbabaabc abaabc babaabc suf 2 babaabc head 2 b suf 3 abaabc head 3 ε T3 abaabc abaabc T4 abaabc b babaabc Algorithmus von McCreight babaabc a abc suf 4 baabc head 4 ba a4 b α4 ε β4 b baabc Ort von head 4 a suf 5 aabc head 5 a a5 a α5 ε β5 ε 27 T5 T6 b babaabc a abc baabc abc a c babaabc a b baabc abc b a aabc abc baabc Ort von head 5 suf 6 abc head 6 ab a6 a α6 ε β6 b T7 abc suf 8 a c b c c T8 babaabc b a suf 7 bc head 7 b a7 b α7 aabc abc baabc a abc Ort von head 6 ε c b babaabc b a c b c β7 aabc abc baabc Verwendung von Suffix-Bäumen 1. Suche nach Zeichenkette α: Folge dem Weg mit Kantenbeschriftung α in T in Zeit O(|α|). c Vorkommen von α Blätter des Teilbaumes = 2. Suche Teilstring: Folge Weg und Suffixzeiger bis akzeptierendes Blatt erreicht. 3. Suche längstes, doppelt auftretendes Wort: Finde Ort eines Wortes mit größter gewichteter Tiefe, der innerer Knoten ist. 4. Suche nach Präfix: Alle Vorkommen von Zeichenketten mit Präfix α finden sich in dem Teilbaum unterhalb des Ortes“ von α in T . ” 5. Bereichssuche nach [α, β ] Algorithmus von McCreight 28 Generalisierte Suffix-Bäume Idee: Erweitere McCreights Algorithmus zur Konstruktion eines Suffixbaumes auf mehrere Strings Vorteil: Suffixbaum S 0 und damit die Indizes aller unterschiedlichen Teilstrings von W1$1, . . . , Wk $k für die im Wörterbuch zu speichernden Strings W1, . . . , Wk nach McCreights Ansatz aufgebaut werden. Nachteil: Struktur dann ein für allemal festgelegt und müßte für jede Einfüge- und Löschoperation immer wieder neu berechnet werden. Algorithmus von McCreight 29 Beispiel Der generalisierte Suffixbaum für 1100110$, 1011001$, 10101$. 0 1 $ $ 10 (1100110$,7,7) (1011001$,7,7) (10101$,5,5) ... 1 $ 01 0 $ $ $ $ 01 01 1 01$ 01$ $ 10 10$ 1 01$ $ $ $ 10$ 10$ 0 1001$ Algorithmus von McCreight 30 Kontributionen Amir et al.: S und S 0 isomorph, Kantenbeschriftungen bis auf die an den Blättern einlaufenden Kanten stimmen überein Dies ermöglicht, einen String W in einen schon bestehenden Suffixbaum einzufügen. Beschränktes Alphabet: beschreibe mit $ jedes der $i, lasse jedoch den Vergleich von $ mit sich selbst scheitern # Knoten in S ≤ D Einfügen eines Strings im generaliserten Suffixbaum mit Laufzeit O(|W |): erweitere McCreights’ Algorithmus Algorithmus von McCreight 31 Löschen von Strings Deshalb bauen wir parallel einen assozierten, invertierten Trie auf. Theorem M = die Menge der gespeicherten Zeichenketten im Suffixbaum S; T Vielwegsuchbaum, der diese Strings in umgekehrter Anordnung darstellt. ⇒ Bijektion zwischen der Menge der Knoten in T (mit Ausnahme der Wurzel) in die Menge der Blattknoten von S Beweis Auf der einen Seite entspricht jedem Suffix der Zeichenkette Wi ein Blatt in S. Auf der anderen Seite existiert für jeden Präfix von WiR ein Knoten in T . Algorithmus von McCreight 32 Beispiel Einfügung von 11010$ 0 1 $ 0 1 01 10 0 $ $ 1 10 $ $ 0 2 10 01$ $ 01 1 20 10$ $ 3 0 $ $ $ 13 10$ 01 9 01$ 8 $ 1$ 4 5 16 10$ $ $ 18 1$ 19 10$ 1001$ 15 17 11 6 12 7 14 1 1 0 1 1 1 2 20 19 18 3 0 4 0 5 1 6 1 7 0 $ 0 1 8 0 0 1 11 1 12 0 13 1 14 9 1 Algorithmus von McCreight 10 15 0 16 1 17 33 Erkenntnisse - Strings können vom längsten Suffix zum kürzesten Suffix gelöscht werden - Suffixlinks nach jedem einzelnen Löschschritt korrekt Problem entfernter String mitunter noch referenziert Lösung: übertrage die durch T eindeutig festgelegte Repräsentation an den Blättern auf die inneren Knoten Zwillinge: beschreiben Historie der Blattgenerierungen Algorithmus von McCreight 34 0 1 $ 0 1 01 0 $ $ 1 $ $ 10 9 01$ 01$ 13 2 01 1 3 1 $ $ 01$ 5 $ 01 10$ $ 4 16 8 $ 10 10 $ 1001$ 17 15 10$ 0 6 10$ 11 12 7 14 Theorem Seien I und L die Mengen aller inneren bzw. Blattknoten in dem generalisierten Suffixbaum S. Sei Γ(p) die Menge der Nachfolger von p und Γ0(p) die Menge der Zwillingsnachfolger von p. Invarianz (Ia) Für alle inneren Knoten p aus I existiert ein Blattknoten q aus L der zugleich Zwillingsnachfolger von p ist (q ∈ Γ0(p)) und dessen Stringrepräsentation mit p übereinstimmt. (Ib) Für alle inneren Knoten p aus I gilt: |Γ0(p)| = |Γ(p)| − 1, d.h. die Anzahl der direkten Nachfolger ist immer um eins größer als die Anzahl der Zwillingsnachfolger. Theorem S = generalisierte Suffixbaum nach einer beliebigen Anzahl P von Einfüge- und Löschoperationen; D = W ∈M |W | ⇒ Platz O(D) Jede Einzeloperation mit Wort W benötigt Zeit O(|W |) Algorithmus von McCreight 35 4 Suffix-Arrays . . . sortierte Liste aller Suffixe eines Textes, plus Zusatzinformationen über längste gemeinsame Präfixe zu Beschleunigung der Suche T = sufi = T [i, j] = pos = sufpos[k] = T [1] T [2] . . . T [n] ∈ Σn Text T [i] . . . T [n] ∈ Σn−i+1 i-tes Suffix (i ≤ n − 1) T [max(1, i)..min(j, n)] Teilwort mit pos[k] ∈ {1, . . . , n} und [i1, . . . , in] das lexikographisch k-kleinste Suffix von T mit sufpos[1] < sufpos[2] < · · · < sufpos[n] <p festgelegt durch A<pB :⇐⇒ A[1, p] < B[1, p] (analog: =p, ≤p, >p, ≥p, 6=p) Suffix-Arrays 36 Eigenschaft Theorem Suffix-Array suf mit Index pos ist bezl. ≤p sortiert, d.h. sufpos[1] ≤p sufpos[1] ≤p · · · ≤p sufpos[n] Beweis Alle Präfixe zm gesuchten Anfang W mit Länge p liegen im pos-Array hintereinander Suche untere Grenze LW für Vorkommen von W mit |W | = p im pos-Array: LW := min{k | W ≤p sufpos[k] ∨ k = n} durch binäre Suche nach LW im pos-Array. · Theorem Teilwortsuche in einem Suffix-Array benötigt O(m + log n) Zeit Suffix-Arrays 37 Beispiel k pos[k] sufpos[k] 1 8 aaa b ca b bd$ 2 3 aa ba baaa b ca b bd$ 3 9 aa b ca b bd$ 4 6 a baaa b ca b bd$ 5 1 a baa ba baaa b ca b bd$ 6 4 a ba baaa b ca b bd$ 7 13 a b b d $ 8 10 a b c a b b d $ 9 7 baaa b ca b bd$ 10 2 baa ba baaa b ca b bd$ 11 4 ba baaa b ca b bd$ 12 14 b bd$ 13 11 b ca b bd$ 14 15 bd$ 15 12 ca b bd$ 16 16 d $ 17 17 $ Suffix-Arrays 38 Algorithmus LW -search Input: Wort W = W [1] . . . W [p] mit p ≤ n Output: LW = min{k | W ≤p sufpos[k] ∨ k = n} 1 if W ≤p sufpos[1] then LW ← 1 else if W >p sufpos[n] 2 3 then LW ← n 4 else (L, R) ← (1, n) 5 while L − R > 1 do 6 M ← (L + R)/2 if W ≤p sufpos[M ] then R ← M 7 8 else L←M 10 end while 11 LW ← R 13 return LW