Hauptseminar Automaten und Formale Sprachen: „Algorithmen der Bioinformatik“ Ausarbeitung: Thomas Heilbock 08.06.2007 Exact String Matching: A Deeper Look at Classical Methods Erweiterte Anwendungen zu Boyer-Moore und Knuth-Morris-Pratt Exact String Matching II 1 Gliederung 1. Apostolico-Giancarlo (Boyer-Moore-Variante in Linearzeit) - Wiederholung / Grundlagen - Die Idee / Modifizierungen - Ablauf einer Vergleich/Shift-Phase - Korrektheit / Laufzeit 2. Exact Set Matching (Aho-Corasick, in Anlehnung an Knuth-Morris-Pratt) - Wiederholung / Grundlagen - erste Ansätze - Hilfsmittel: keyword-tree - Hilfsmittel: Fehlerfunktion / FehlerLink - Aho-Corasick komplett 3. Anwendung von Exact Set Matching - Exact Matching mit Wildcards 4. Literatur / Fragen Exact String Matching II 2 1. Apostolico-Giancarlo - Wiederholung / Grundlagen - - Wiederholung / Grundlagen: - Boyer-Moore - gegeben: Text T=y[0..n-1], Pattern P=x[0..m-1] - Anlegen des linken Endes von P an die Textposition j - Vergleich von rechts nach links - Shift um den maximalen Wert aus der BadCharacter-Regel und der Good-Suffix-Regel Exact String Matching II 3 1. Apostolico-Giancarlo - Wiederholung / Grundlagen - - Vorverarbeitung: - Für jeden Buchstaben des Textalphabets: Bad-Character-Liste: erstes Auftreten in x[0..m-2] (von rechts) - Für jedes Zeichen i aus P: - Suffix-Liste: Länge des längsten Suffix von x[0..i], das auch Suffix von P ist - Good-Suffix-Liste: Länge des längsten echten Suffix von x[0..i], das Suffix von P ist Exact String Matching II 4 1. Apostolico-Giancarlo - Wiederholung / Grundlagen - - Bad-Character-Regel: - bei Mismatch zwischen den Zeichen y[i+j] und x[i] suche (von rechts) das erste Auftreten von y[i+j] in x Shift-Weite - Good-Suffix-Regel: - wurde ein Suffix u von x bis zu Mismatch an Position x[i] gefunden, suche (von rechts) das erste Auftreten von u in x, so das u einem Zeichen ungleich x[i] folgt Shift-Weite Exact String Matching II 5 1. Apostolico-Giancarlo - Die Idee / Modifikationen - - Problem von Boyer-Moore: - - Nach jeder Vergleich/Shift-Phase werden potentielle Informationen vergessen Neues Ziel: - Jedes Zeichen aus T, welches schon einmal zu einem Zeichen aus P gepasst hat (Match) soll nicht noch einmal verglichen werden Exact String Matching II 6 1. Apostolico-Giancarlo - Die Idee / Modifikationen - Notationen: - Pattern P = y[0..n-1] Text T = x[0..m-1] h – Laufvariable auf T i – Laufvariable auf P j – Startposition des Vergleichs auf T (rechtes Ende von P) N(i) – Suffix-Liste für P M(i) – Substring-Tabelle für T (neu) Exact String Matching II 7 1. Apostolico-Giancarlo - Die Idee / Modifikationen - Zwei Modifikationen von Boyer-Moore Nutzen einer zusätzlichen Tabelle M(i) für T, welche zur Laufzeit wie folgt ausgefüllt wird: a) Zu Beginn sind alle Werte undefiniert b) Findet der Algorithmus bei einem Vergleich einen Substring der Länge 0<k≤n, welches Suffix von P ist, wird M(j) auf k gesetzt Exact String Matching II 8 1. Apostolico-Giancarlo - Die Idee / Modifikationen - Zwei Modifikationen von Boyer-Moore 2. Nutzen des Wissens aus M und N, um die Suche zu beschleunigen Vergleich/Shift-Phase mit Fallunterscheidung wie folgt: h:=j, i:=n Starte Fallunterscheidung Exact String Matching II 9 1. Apostolico-Giancarlo - Ablauf einer Vergleich/Shift-Phase a) Fallunterscheidung: M(h) undefiniert oder M(h)=N(i)=0 Vergleich von T(h) und P(i): i) wenn T(h)=P(i) und i=1, dann berichte Auftreten von P in T an Position (j-n), setze M(j)=n und mache Shift (nach BM) ii) wenn T(h)=P(i) und i>1, dann setze h=h-1, i=i-1 und starte die Fallunterscheidung neu iii) wenn T(h)≠P(i), dann setzte M(j)=j-h und mache Shift (nach BM) Exact String Matching II 10 1. Apostolico-Giancarlo - Ablauf einer Vergleich/Shift-Phase b) M(h)<N(i) P stimmt mit dem Substring aus T von Position i-M(h)+1 zu Position n überein Vergleich muss vor diesem Substring wieder aufgenommen werden: i:=i-M(h), h:=h-M(h), starte Fallunterscheidung neu c) M(h)≥N(i) und N(i)=i >0, P in T gefunden. M(j):=j-h, mache Shift (nach BM) d) M(h)>N(i) und N(i)<i P und T stimmen von j zu Position i-N(i)+1 überein, dann folgt ein Mismatch M(j):=j-h. mache Shift (nach BM) e) M(h)=N(i) und 0<N(i)<i, P und T stimmen für die ersten M(h) überein, Rest von P muss noch verglichen werden i=i-M(h), h=h-M(h), starte Fallunterscheidung neu Exact String Matching II 11 1. Apostolico-Giancarlo - Korrektheit / Laufzeit - - Korrektheit: - zu zeigen: Algorithmus simuliert original BM a) Algorithmus nutzt original Shift-Regeln dieser Teil stimmt b) für jeden Vergleich von P mit einem Textabschnitt aus T muss AG die gleiche Zeichenfolge bis zum ersten Unterschied finden - Betrachtung der Fallunterscheidung: - Fall a) arbeitet nach Boyer-Moore - Fall b,c,e) überspringen eventuell Zeichen, aber nur Match - Fall d) überspringt Mismatches nach Definition von M und N aber nur wirklich ungleiche Bereiche Exact String Matching II 12 1. Apostolico-Giancarlo - Korrektheit / Laufzeit - - Laufzeit: a) AG macht höchstens 2m Zeichenvergleiche jede Phase endet durch Mismatch, und jede Phase (außer der letzten) wird gefolgt von einem Shift>0 höchstens m Mismatches - Zeichen werden expliziert nur in Phase 1 verglichen findet ein Vergleich bei T(h) ein Match, wird am Ende der Phase M(j)=j-h+1 (mind.) gesetzt alle Zeichen aus T die Zeichen aus P glichen (während dieser Phase) sind im Intervall [j-M(j)+1 .. j)] Trifft ein anderer Vergleich nun auf so ein Zeichen, ist für dieses M(h)>0 der Vergleich überspringt diesen Bereich um genau M(h) und fährt davor fort Exact String Matching II 13 1. Apostolico-Giancarlo - Korrektheit / Laufzeit Zu a) m Matches + m Mismatches 2m Vergleiche b) AG braucht höchstens O(m) zusätzliche Arbeit Zusätzlicher Aufwand: O(m) - Fall a): Vergleich O(m), maximal 2m Vergleiche (siehe a) - Fall c/d): Shift O(m), da maximal m Shifts - Fall b/e): maximal einmal pro Position / Zeichen von T O(m) O(m) Fazit: AG arbeitet in Linearzeit Exact String Matching II 14 2. Exact Set Matching - Wiederholung / Grundlagen - • Wiederholung / Grundlagen: – Knuth-Morris-Pratt • gegeben: Text T=y[0..n-1], Pattern P=x[0..m-1] • Vergleich von links nach rechts • Tabelle spi für Shift-Weiten Zu jeder Position i in Pattern P finde die Länge des längsten echten Suffix von P[0..i-1] das Präfix von P ist Exact String Matching II 15 2. Exact Set Matching - Wiederholung / Grundlagen - - Verallgemeinerung vom Exact Matching gegeben: - Satz/Liste von Pattern P=[P1,...,Pz] n sei Gesamtlänge aller Pattern aus P m sei Länge des Textes T gesucht: - Alle Vorkommen aller Pattern aus P in T naheliegender Ansatz: - Jedes Pattern wird einzeln mit einem beliebigen LinearzeitAlgorithmus in T gesucht O(n+zm): Zielvorstellung (Aho-Corasick): - O(n+m+k), k = Anzahl der Vorkommen der Pattern aus P Exact String Matching II 16 2. Exact Set Matching - Hilfsmittel: keyword-tree - Keyword-Tree K: gerichteter Baum mit den Eigenschaften: a) genau ein Zeichen pro Kante (genannt: Bezeichnung) b) zwei Kanten, die aus dem selben Knoten heraus führen, haben unterschiedliche Bezeichnungen c) Jedes Pattern Pi kann auf einem Pfad im Baum, von der Wurzel bis zu einem Knoten, abgebildet werden, so dass die Zeichen an den Kanten der Reihe nach gelesen, Pi ergeben Exact String Matching II 17 2. Exact Set Matching - Hilfsmittel: keyword-tree Für endliches Alphabet ist keyword-tree zu P in O(n) berechenbar: Def.: Ki sei der keyword-tree der Pattern P1 ... Pi von P a) K1: von Wurzel aus beschrifte jede Kante (nach Reihenfolge) des Zweiges mit dem jeweils nächsten Zeichen von P1. benenne letzten Knoten mit „1“ b) K2 aus K1: - folge dem Pfad von K1 bis das längste Präfix von P2 in P1 erreicht ist Pfad endet entweder, wenn P2 zu Ende ist (P2 in P1 ) oder wenn ein Knoten v keine passende ausgehende Kante mehr hat für den letzten Fall starte neuen Pfad ab diesem Knoten benenne letzten Knoten mit „2“ Exact String Matching II 18 2. Exact Set Matching - Hilfsmittel: keyword-tree c) Ki +1 aus Ki : - von Wurzel aus folge genau dem Pfad Ki, der mit den Zeichen von Pi+1 (in Reihenfolge) übereinstimmt entweder Pi+1 kommt in Ki vor oder es gibt Knoten, an dem eine neue Kante angefügt werden muss, um das Pattern fortzuführen Für jedes Pattern Pi braucht man O(|Pi+1|) Zeit zum Einfügen des Pattern Pi+1 in Ki O(n) über alle Pattern Exact String Matching II 19 2. Exact Set Matching - erste Ansätze Naiver Ansatz einer Suche: - starte für jede Position l in T und: - folge dem einen Pfad in K, der einem Präfix von T gleicht - ein mit i nummerierter Knoten gibt das Vorkommen von Pi in T an - wenn kein weiteres Match zu funden ist, gehe setze l:=l+1 … aber: Zeitaufwand O(m*n) Erinnerung an Knuth-Morris-Pratt: - verbessern der naiven Idee Shift ≥1 Exact String Matching II 20 2. Exact Set Matching - erste Ansätze Aho-Corasick-Ansatz: - Shift ≥1 überspringen von initialen Teilen von Pfaden in K, wenn möglich verallgemeinern der KMP-Funktion spi, damit sie für Pattern-Sätze funktioniert - vorerst mit Einschränkung: kein Pattern aus P darf echter Substring eines anderen Pattern aus P sein Exact String Matching II 21 2. Exact Set Matching - Hilfsmittel: Fehlerfunktion/ FehlerLink Fehlerfunktion für keyword-trees: Def.: Jeder Knoten v in K bekommt den Namen des Substrings, den er repräsentiert genannt L(v) Def.: Für jeden Knoten v in K sei lp(v) die Länge des längsten echten Suffix von String L(v), das Präfix eines Pattern aus P ist Lemma: Sei α das lp(v)- lange Suffix von String L(v). Dann existiert genau ein Knoten im keyword-tree, der die Bezeichnung α hat. Exact String Matching II 22 2. Exact Set Matching - Hilfsmittel: Fehlerfunktion/ FehlerLink Def.: Für einen Knoten v in K sei nv der eine Knoten in K, der mit dem Suffix von L(v) der Länge lp(v) benannt ist. Ist lp(v) = 0 für einen Knoten v, dann ist nv gleich der Wurzel. Def.: Das geordnete Paar (v,nv) nennen wir FehlerLink. Exact String Matching II 23 2. Exact Set Matching - Hilfsmittel: Fehlerfunktion/ FehlerLink Nutzen des FehlerLink zum Beschleunigen der Suche: - Annahme: FehlerLinks zu allen v:vnv sind bekannt l indiziert die Startposition in T, Zeiger c zeigt auf das aktuelle Zeichen in T, das mit einem Zeichen von K verglichen werden soll Algorithmus: L:=1; c:=1; w:=root Wiederhole Solange es eine Kante (w,w‘) gibt mit der Bezeichnung T(c) Begin Wenn w‘ von einem Pattern Pi nummeriert ist, dann berichte das Vorkommen des Pattern Pi an Position l m Text T w:=w‘; c:=c+1; End W:=nw; l:=c-lp(w) Bis c>m Exact String Matching II 24 2. Exact Set Matching - Hilfsmittel: Fehlerfunktion/ FehlerLink Was passiert?: - Suchen, bis Mismatch vorliegt: T(c) steht an keiner Kante raus aus v wir wissen nun, dass String L(v) in T vorkommt, von Position l bis zu Position c-1 nach Definition von vnv gilt L(nv)=T[c-lp(v) .. c-1] wenn lp(v)≥0, kann l auf c-lp(v) erhöht werden, c bleibt unverändert. die nächsten Vergleiche beginnen also ab Knoten nv, der Zweig vor nv muss nicht noch einmal verglichen werden Nächstes T(c) wird mit den von nv wegführenden Kanten-Bezeichnungen verglichen. Exact String Matching II 25 2. Exact Set Matching - Hilfsmittel: Fehlerfunktion/ FehlerLink - für lp(v) erhöhe l auf c und starte den nächsten Vergleich ab der Wurzel bei Mismatch an der Wurzel, wird c:=c+1 gesetzt Funktion vnv beschleunigt die naive Suche nach Pattern aus P Laufzeit: O(m) – Analogie zu KMP mit O(m) Vergleichen Exact String Matching II 26 2. Exact Set Matching - Hilfsmittel: Fehlerfunktion/ FehlerLink Berechnung der Fehlerfunktion in Linearzeit: Induktive Herangehensweise: IA: für v=r (root) oder Abstand von v zu r = 1 ist gilt: nv = r IV: für ein k wurden alle nv zu allen Knoten berechnet, welche Abstand ≤k zu r haben IS: nimm Knoten v‘, der Abstand k zu r hat: die Kante von v‘ zu seinem KindKnoten v sei mit x bezeichnet 1. 2. Suche nach einer von nv‘ wegführenden Kante mit Bezeichnung x wenn gefunden, sei diese Kante (nv‘, w‘) und wir setzen nv auf w‘ Gibt es keine solche Kante aus nv‘ heraus, dann ist L(nv) ein echtes Suffix von L(nv‘), gefolgt von x. Nun sucht man weiter bei nnv‘ (bekannt, da nv‘Abstand ≤k von r hat) nach einer wegführenden Kante mit Bezeichner x… usw Exact String Matching II 27 2. Exact Set Matching - Hilfsmittel: Fehlerfunktion/ FehlerLink - Algorithmus nv: - v‘ ist Elternknoten von v in K x ist Zeichen an der Kante (v,v‘) w:=nv‘ solange keine Kante raus aus w die Bezeichnung x hat und w ungleich r ist, setze w:=nw wenn eine Kante (w,w‘) wegführend von w den Bezeichner x hat, - dann: nv:=w‘ - Sonst: nv:=r (für kompletten Baum: starte nv bei root mit nv=0) Exact String Matching II 28 2. Exact Set Matching - Aho-Corasick komplett Aho-Corasick-Algorithmus komplett: - bisherige Einschränkung: kein Pattern Substring ist Substring eines anderen Pattern - solche Pattern könnten bei der Suche übersprungen werden Exact String Matching II 29 2. Exact Set Matching - Aho-Corasick komplett Lemma: Angenommen, in einem keyword-tree K gibt es einen direkten Pfad von FehlerLinks von einem Knoten v zu einem nummerierten Knoten. Dann kommt Pattern Pi in T vor, endend an Position c (aktuell verglichenes Zeichen), wann immer Knoten v während einer Suchphase von AhoCorasick erreicht wird. Lemma: Angenommen, ein Knoten v wurde während des Algorithmus erreicht. Dann kommt Pattern Pi nur in T vor (an Position c endend), wenn v eine Nummer hat oder es einen direkten Pfad von FehlerLinks zu einem nummerierten Knoten gibt. Exact String Matching II 30 2. Exact Set Matching - Aho-Corasick komplett Algorithmus volle AC Suche: l:=1; c:=1; w:=root; Wiederhole Solange es eine Kante (w,w‘) mit T(c) bezeichnet gibt Begin Wenn w‘ von Pattern i nummeriert ist oder es gibt einen direkten Pfad von FehlerLinks von w‘ zu einem mit i nummerierten Knoten Dann berichte Vorkommen von Pi in T an Endposition c W:=w‘; c:=c+1 End w:=nw; l:=c-lp(w) Bis c>n Exact String Matching II 31 2. Exact Set Matching - Aho-Corasick komplett Implementierungsansatz: Wie realisiert man den direkten Pfad der Fehlerlinks? Einführung des Zeigers „OutputLink“ zeigt von v aus auf den nummerierten (von v verschiedenen Knoten) der über die wenigsten FehlerLinks zu erreichen ist - - Erstellung der OutputLinks während Preprocessing von nv O(n) wurde nv ermittelt, setze OutputLink von v wie folgt: a) b) c) hat nv eine Nummer, zeigt der OutputLink von v auf nv hat nv keine Nummer, aber der OutputLink von nv zeigt auf w, dann setze OutputLink von v auf w Andernfalls hat v keinen OutputLink Korrektheit über Aufbau von nv Exact String Matching II 32 2. Exact Set Matching - Aho-Corasick komplett mittels dieser OutputLinks können alle k Vorkommen von Pattern aus P in T nun in O(m+k) erkannt werden Fazit/Theorem: Wenn P ein Satz von Pattern mit Gesamtlänge n ist und T ist Text der Länge m, kann man alle k Vorkommen von Pattern aus P in T mit O(n) Vorverarbeitungszeit + O(m+k) Suchzeit finden. Dies gilt auch, wenn Pattern aus P Substrings in anderen Pattern sind. Exact String Matching II 33 3. Anwendung von Exact Set Matching - Exact Matching mit Wildcards - Exact Matching mit Wildcards: Problemstellung: - nur ein Pattern zu vergleichen - Einführen des neuen Zeichens Φ, genannt Wildcard, welches zu jedem Zeichen in T passt - Aufgabe: finde ein Pattern P mit Wildcards in T - einfachster Fall: T enthält keine Wildcards, Φ ist nur 1 Zeichen lang Exact String Matching II 34 3. Anwendung von Exact Set Matching - Exact Matching mit Wildcards - Algorithmus: 0. C sei ein Vektor der Länge |T|, mit Nullen initialisiert 1. Sei P={P1,P2,...Pz} die Menge der maximalen Substrings von P, die keine Wildcards enthalten l1,l2,...,lz seien die Startpositionen dieser Substrings in P 2. Unter Nutzung von Aho-Corasick suche zu jedem String Pi von P alle möglichen Startpositionen im Text T Für jede dieser Positionen j (auf T) von Pi erhöhe den Zähler der Zelle C[j-li+1] um 1 3. Suche im Vektor C nach Zellen mit dem Wert z (Anzahl Substrings) an jeder dieser Positionen auf T startet P Exact String Matching II 35 3. Anwendung von Exact Set Matching - Exact Matching mit Wildcards - Korrektheit: - - klar: es gibt Vorkommen von P in T ab Position p gdw. für jedes i das Subpattern Pi in P an Position j=p+li+1 von T vorkommt wird also Pattern Pi in P an Position j in T gefunden, und Pi startet an Position li in P, ist das ein erster Zeuge dafür, dass P in T ab Position p-li+1 vorkommt. wird für jedes Pi so ein Zeuge gefunden, kommt P in T ab Position - der Algorithmus zählt (in C) für jede Position p die Anzahl der Zeugen eines Auftretens von P ist die Zahl = z, wurde ein P gefunden - merke: jeder String kann die Zelle C zu p um maximal 1 erhöhen maximal k Werte pro Zelle (Eindeutigkeit) Exact String Matching II 36 3. Anwendung von Exact Set Matching - Exact Matching mit Wildcards - Komplexität: - - Keyword-Tree-Aufbau erfolgt nach Aho-Corasick in O(n) Suche nach Pi in T erfolgt in O(m+k), k = Anzahl der Vorkommnisse von P in T - Wann immer ein Teilpattern aus P in T vorkommt, wird genau eine Zelle von C erhöht, jede Zelle kann maximal auf z erhöht werde - Also ist k begrenz durch m*z Algorithmus läuft in O(m*z) Für ein konstantes z gilt O(m*z) = O(m) O(m) + O(n) = O(m+n) Exact String Matching II 37 4. Literatur / Fragen Literatur: 1. 2. Algorithms on Strings, Trees, and Sequences Dan Gusfield (Cambridge University Press, 1999) Handbook of Exact String Matching Algorithms Christian Charras, Thierry Lecroq (King‘s College London, 2004) Fragen? Exact String Matching II 38