Suffixautomaten • Weitere mögliche Datenstrukturen, die uns Zugriff auf die Suffixe eines Suchtextes erlauben. Stringologie Suffix-Bäume • Etwas grösser als Suffix Arrays, dafür noch effizienterer Zugriff. • Keine speziellen Suchalgorithmen notwendig. Peter Leupold Universität Leipzig Der Suffix Trie eines Strings ist der • deterministische endliche Automat, Vorlesung SS 2014 • der alle Suffixe dieses Strings erkennt, • und bei dem verschiedene Pfade aus demselben Quellzustand stets in verschiedenen Endzuständen enden. P. Leupold Stringologie (1) Suffix Trie P. Leupold Stringologie (2) Suffix Trie Suffix Trie für den String ababbb: Aufbau durch sukzessives Hinzufügen der Suffixe vom längsten an. Dabei nennen wir Kopf (des aktuell einzufügenden Suffix) das längste gemeinsame Präfix mit einem größeren Suffix, Gabelung den letzten Zustand des Kopfes und Schwanz den Rest des Suffixes. Die Endzustände haben als Ausgabe die Position des jeweiligen Suffixes. P. Leupold Stringologie (3) P. Leupold Stringologie (4) Suffix Trie Suffix-Trie(y,n) Gabelungen sind alle Zustände mit mehr als einem Ausgang. Korrespondenz zu Lcp. 1 2 3 4 5 6 7 8 9 10 11 12 13 P. Leupold Stringologie M:= Neuer Automat; for (i := 0; i < n; i + +) do (fork, k) := Finde(initial(M), i); p := fork; for (j := k; j < n; j + +) do q := Neuer -Zustand(); Succ[p] := Succ[p] ∪ {(y [i], q)}; p := q; end output[p] := i; end output[initial(M)] := n; return M; (5) Finde(p,k) P. Leupold Stringologie (6) Suffix Trie Bei naivem Herangehen benötigt die Konstruktion eines Suffix Trie quadratisch viel Zeit in der Länge des Strings. 1 2 3 Nun analysieren wir die Funktion der Gabelungen. while (k < n AND Target(p, y [k])) do (p, k) := (Target(p, y [k]), k + 1); end • Sei av ein Suffix (des Textes) mit Kopf az. • Dann ist z ein Präfix des Suffixes v (von av ). • Also können wir die zugehörige Gabelung ab z suchen statt vom Startzustand aus. P. Leupold Stringologie (7) P. Leupold Stringologie (8) Suffix Trie Suffix Trie Suffix Links zum Finden der Gabelungen Der Suffix Link ist die Funktion s auf der Menge der Zustände, die definiert ist durch s(az) = z. Das Suffix Ziel eines Zustandes ist das Bild unter dem Suffix Link. Den Suffix Link speichern wir für jeden Zustand im Zeiger s`, der anfangs stets auf NIL gesetzt wird. P. Leupold Stringologie (9) Suffix-Trie-SL(y,n) 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 P. Leupold Stringologie (10) Finde-SL(p,k) M:= Neuer Automat; s`[initial(M)] := initial[M]; (fork, k) := (initial(M), 0); for (i := 0; i < n; i + +) do k := max(k, i); (fork, k) := Finde-SL(s`[fork], k); p := fork; for (j := k; j < n; j + +) do q := Neuer -Zustand(); Succ[p] := Succ[p] ∪ {(y [i], q)}; p := q; 1 2 3 4 5 6 7 8 9 end output[p] := i; 10 end output[initial(M)] := n; return M; 12 11 P. Leupold Stringologie (11) while (k < n AND Target(p, y [k])) do q := Target(p, y [k]); (e, f ) := (p, q); while (e 6= initial(M) AND s`[f ] = NIL) do s`[f ] := Target(s`[e], y [k]); (e, f ) := (s`[e], s`[f ]); end if (s`[f ] = NIL) then s`[f ] := initial(M); end (p, k) := (q, k + 1); end P. Leupold Stringologie (12) Suffix Baum Suffix Baum Der Suffix Baum entsteht aus dem Suffix Trie durch Löschen aller Zustände vom Grad eins, die nicht Endzustände sind. Für die Reduzierung auf linear viele Knoten bezahlen wir evtl. mit (insgesamt) quadratisch langen Namen der Transitionen. Darum: Dabei muss y stets mit vorliegen. P. Leupold Stringologie (13) P. Leupold Stringologie (14) Suffix Baum Suffix Baum Satz Der Suffixbaum eines Strings der Länge n hat zwischen n + 1 und 2n Knoten. Lemma In einem Suffix Trie ist das Suffix-Ziel einer nichtleeren Gabelung stets eine Gabelung. Die Anzahl der Gabelungen liegt zwischen 1 und n. • Ist Gabelung au von Grad mindestens 2, dann sind verschiedene aub und auc Faktoren von y . • Es gibt genau n + 1 Endzustände. • Jede Gabelung, die nicht Endzustand ist, hat mindestens zwei Kinder. • Dasselbe gilt für u = s(au), das somit mindestens Grad 2 hat. • Ist Gabelung au von Grad 1 und Endzustand, dann gibt es ein aub, • Bei n + 1 Endzuständen ergibt das maximal n Gabelungen. • Der Anfangszustand fällt in beide Klassen. P. Leupold Stringologie das Faktor von y ist; zugleich ist au Suffix. • Also ist auch ub Faktor und u ein Suffix. (15) P. Leupold Stringologie (16) Suffix Baum Suffix Baum Lemma Sei (p, q) eine Kante des Suffixbaumes von y mit Namen y [j . . . k − 1]. Falls q eine Gabelung des Baumes ist, dann ist δ(p, y [j + 1 . . . k − 1] falls p Anfangszutand , s(q) = δ(s(p), y [j . . . k − 1]) sonst. • Für den Anfangszustand gilt die Aussage per Definition. • Suffix ababbb wird durch Vergleiche vom Anfangszustand ab eingefügt. • Sonst sei av der eindeutige Pfad zu p. • Also ist δ(λ, v ) = s(p) und δ(λ, v · y [j . . . k − 1]) = s(q). • Es werden die Knoten 3 und 4 eingefügt. • Der Kopf ist abab, der Schwanz bb. • Da der Automat deterministisch ist, ist s(q) = δ(s(p), y [j . . . k − 1]). P. Leupold Stringologie P. Leupold (17) Suffix Baum Stringologie (18) Suffix Baum • Zur Berechnung von s(3) fehlt der Knoten für bab. • Einfügen von babbb. • Also wird die Kante bababbb geteilt. • Der Kopf ist bab, der Schwanz bb. • Braucht nicht mehr Zeit als der Pfad lang ist. P. Leupold Stringologie (19) P. Leupold Stringologie (20) Suffix Baum Suffix-Automaten p := δ(s(t), v ) P. Leupold Stringologie (21) Suffix-Automaten Der kompakte Suffixautomat lässt sich in • O(n · log |Σ|) Zeit und • O(n) Raum konstruieren. • Er spart ca. 50% Platz gegenüber dem minimierten, nicht kompaktierten Automaten. P. Leupold Stringologie (23) P. Leupold Stringologie (22)