Boyer-Moore-Algorithmus

9,873 views
9,547 views

Published on

Einführung in den Boyer-Moore-Algorithmus für die Textsuche

Published in: Technology
1 Comment
1 Like
Statistics
Notes
  • I respectfully disagree with a couple of the ideas on AC Moore Arts & Crafts in Asheville North Carolina especially as it has to do with ac moore but will research this further externally on Friday to see how I feel about this.
       Reply 
    Are you sure you want to  Yes  No
    Your message goes here
No Downloads
Views
Total views
9,873
On SlideShare
0
From Embeds
0
Number of Embeds
147
Actions
Shares
0
Downloads
0
Comments
1
Likes
1
Embeds 0
No embeds

No notes for slide

Boyer-Moore-Algorithmus

  1. 1. Boyer-Moore-Algorithmus Ein Textsuchalgorithmus für große Alphabete Martin Szugat (Martin.Szugat@GMX.net)
  2. 2. Agenda <ul><li>Evolution: Von der naiven Suche über Knuth-Morris-Pratt zu Boyer-Moore </li></ul><ul><li>Schlechte Zeichen und gute Suffixe </li></ul><ul><li>Boyer-Moore vom Anfang bis zum Ende </li></ul><ul><li>Fazit: Der Durchschnitt siegt! </li></ul>
  3. 3. Problemstellung <ul><li>Exakte Suche von </li></ul><ul><li>kurzen Zeichenfolgen in </li></ul><ul><li>langen Zeichenfolgen </li></ul>
  4. 4. Zur Erinnerung!!! <ul><li>Das Muster (engl. Pattern) ist die gesuchte Zeichenfolge. </li></ul><ul><li>Der Text ist die durchsuchte Zeichenfolge. </li></ul><ul><li>Als ( Mis- ) Match wird die (Nicht-)Überein-stimmung von einem Zeichen aus dem Muster mit einem Zeichen im Text bezeichnet. </li></ul><ul><li>Nach einem Mismatch wird das Muster im Text verschoben, was als Shift bezeichnet wird. </li></ul>
  5. 5. Lösung I: Naive Suche <ul><li>Vergleiche die Zeichen des Musters mit den Zeichen des Textes, </li></ul><ul><li>solange wie kein Mismatch auftritt. </li></ul><ul><li>Bei einem Mismatch verschiebe das Muster um ein Zeichen im Text und </li></ul><ul><li>beginne von vorne. </li></ul><ul><li>Falls alle Zeichen übereinstimmen, wurde ein Treffer erzielt. </li></ul>
  6. 6. Naive Suche - Beispiel <ul><li>Text aaaabaaaac... </li></ul><ul><li>Muster aaaac </li></ul>Anzahl der Vergleiche: 0
  7. 7. Naive Suche - Beispiel <ul><li>Text a aaabaaaac... </li></ul><ul><li>Muster a aaac </li></ul>Anzahl der Vergleiche: 1
  8. 8. Naive Suche - Beispiel <ul><li>Text a a aabaaaac... </li></ul><ul><li>Muster a a aac </li></ul>Anzahl der Vergleiche: 2
  9. 9. Naive Suche - Beispiel <ul><li>Text aaaa b aaaac... </li></ul><ul><li>Muster aaaa c </li></ul>Anzahl der Vergleiche: 5
  10. 10. Naive Suche - Beispiel <ul><li>Text aaaa b aaaac... </li></ul><ul><li>Muster aaaa c </li></ul>Anzahl der Vergleiche: 5
  11. 11. Naive Suche - Beispiel <ul><li>Text a aaa b aaaac... </li></ul><ul><li>Muster aaa a c </li></ul>Anzahl der Vergleiche: 9
  12. 12. Naive Suche - Beispiel <ul><li>Text aa aa b aaaac... </li></ul><ul><li>Muster aa a ac </li></ul>Anzahl der Vergleiche: 12
  13. 13. Naive Suche - Beispiel <ul><li>Text aaaab aaaac ... </li></ul><ul><li>Muster aaaac </li></ul>Anzahl der Vergleiche: 20
  14. 14. Naive Suche - Laufzeit <ul><li>Um in einem Text der Länge n </li></ul><ul><li>ein Muster der Länge m zu finden, </li></ul><ul><li>benötigt die naive Suche maximal </li></ul><ul><li>m (n – m + 1) </li></ul><ul><li>Vergleiche. </li></ul>
  15. 15. Lösung II: Knuth-Morris-Pratt <ul><li>Idee: Größere Shifts durch Wiederholungen von Zeichenfolgen im Muster. </li></ul><ul><li>Algorithmus: </li></ul><ul><li>Berechne die Länge der eigentlichen Ränder aller Präfixe des Musters. </li></ul><ul><li>Vergleiche das Muster mit dem Text. </li></ul><ul><li>Bei einem Mismatch verwende die Ränderlängen, um das Muster im Text zu verschieben. </li></ul>
  16. 16. Länge der Ränder aller Präfixe <ul><li>Muster ε a b a b c </li></ul><ul><li>Randlänge </li></ul>Leeres Wort
  17. 17. Länge der Ränder aller Präfixe <ul><li>Muster ε a b a b c </li></ul><ul><li>Randlänge -1 </li></ul>Per Definition Leeres Wort
  18. 18. Länge der eigentlichen Ränder aller Präfixe <ul><li>Muster ε a b a b c </li></ul><ul><li>Randlänge -1 0 0 </li></ul>
  19. 19. Länge der Ränder aller Präfixe <ul><li>Muster ε a b a b c </li></ul><ul><li>Randlänge -1 0 0 1 </li></ul>
  20. 20. Länge der Ränder aller Präfixe <ul><li>Muster ε a b a b c </li></ul><ul><li>Randlänge -1 0 0 1 2 </li></ul>
  21. 21. Länge der Ränder aller Präfixe <ul><li>Muster ε a b a b c </li></ul><ul><li>Randlänge -1 0 0 1 2 0 </li></ul>
  22. 22. Knuth-Morris-Pratt - Beispiel <ul><li>Text a b a b a b c ... </li></ul><ul><li>Muster a b a b c </li></ul>
  23. 23. Knuth-Morris-Pratt - Beispiel <ul><li>Text a b a b a b c ... </li></ul><ul><li>Muster a b a b c </li></ul><ul><li>Position 0 1 2 3 4 </li></ul><ul><li>- Randlänge -1 0 0 1 2 0 </li></ul><ul><li>= Shift 2 </li></ul>Anzahl der Vergleiche: 5
  24. 24. Knuth-Morris-Pratt - Beispiel <ul><li>Text a b a b a b c ... </li></ul><ul><li>Muster a b a b c </li></ul>Anzahl der Vergleiche: 5
  25. 25. Knuth-Morris-Pratt - Beispiel <ul><li>Text a b a b a b c ... </li></ul><ul><li>Muster a b a b c </li></ul>Anzahl der Vergleiche: 6
  26. 26. Knuth-Morris-Pratt - Beispiel <ul><li>Text a b a b a b c ... </li></ul><ul><li>Muster a b a b c </li></ul>Anzahl der Vergleiche: 8
  27. 27. Knuth-Morris-Pratt - Laufzeit <ul><li>Für die eigentliche Suche: </li></ul><ul><li>2n – m + 1 </li></ul><ul><li>Für die Tabelle mit den Längen der Ränder: </li></ul><ul><li>2m - 1 </li></ul><ul><li>Für den KMP-Algorithmus insgesamt: </li></ul><ul><li>2n + m </li></ul>
  28. 28. Knuth-Morris-Pratt - Worst-Case <ul><li>Text a a c a a c a a b </li></ul><ul><li>Muster a a b </li></ul><ul><li>Position 0 1 2 </li></ul><ul><li>– Randlänge -1 0 1 0 </li></ul><ul><li>= Shift 1 </li></ul>Anzahl der Vergleiche: 3
  29. 29. Knuth-Morris-Pratt - Worst-Case <ul><li>Text a a c a a c a a b </li></ul><ul><li>Muster a a b </li></ul><ul><li>Position 0 1 2 </li></ul><ul><li>– Randlänge -1 0 1 0 </li></ul><ul><li>= Shift 1 </li></ul>Anzahl der Vergleiche: 5
  30. 30. Knuth-Morris-Pratt - Worst-Case <ul><li>Text a a c a a c a a b </li></ul><ul><li>Muster a a b </li></ul><ul><li>Position 0 1 2 </li></ul><ul><li>– Randlänge -1 0 1 0 </li></ul><ul><li>= Shift 1 </li></ul>Anzahl der Vergleiche: 6
  31. 31. Knuth-Morris-Pratt - Worst-Case <ul><li>Text a a c a a c a a b </li></ul><ul><li>Muster a a b </li></ul><ul><li>Position 0 1 2 </li></ul><ul><li>– Randlänge -1 0 1 0 </li></ul><ul><li>= Shift 1 </li></ul>Anzahl der Vergleiche: 9
  32. 32. Knuth-Morris-Pratt - Worst-Case <ul><li>Text a a c a a c a a b </li></ul><ul><li>Muster a a b </li></ul>Anzahl der Vergleiche: 14
  33. 33. Bad Character <ul><li>Definition: Ein Zeichen, welches einen Mismatch auslöst, wird Bad Character genannt. </li></ul><ul><li>Problem: Das Bad Character wird beim Shift nicht berücksichtigt </li></ul><ul><li>Folge: Das Muster wird im schlechtesten Fall stets nur um ein Zeichen verschoben. </li></ul><ul><li>Sonderfall: Das Bad Character taucht im Muster überhaupt nicht auf. </li></ul><ul><li>Lösung: Falls das Bad Character nicht im Muster vorkommt, verschiebe das Muster um die volle Länge. </li></ul>
  34. 34. Bad Character – Beispiel I <ul><li>Text a a c a a c a a b </li></ul><ul><li>Muster a a b </li></ul>Anzahl der Vergleiche: 3
  35. 35. Bad Character - Beispiel I <ul><li>Text a a c a a c a a b </li></ul><ul><li>Muster a a b </li></ul>Anzahl der Vergleiche: 6
  36. 36. Bad Character - Beispiel I <ul><li>Text a a c a a c a a b </li></ul><ul><li>Muster a a b </li></ul>Anzahl der Vergleiche: 9
  37. 37. Muster von rechts nach links vergleichen <ul><li>Problem: Es müssen weiterhin alle Zeichen im Text mindestens einmal mit einem Zeichen aus dem Muster verglichen werden. </li></ul><ul><li>Lösung: Vergleiche das Muster von rechts nach links mit dem Text. </li></ul><ul><li>Vorteil: Bad Character werden schneller erkannt! </li></ul>
  38. 38. Bad Character - Beispiel II <ul><li>Text a a c a a c a a b </li></ul><ul><li>Muster a a b </li></ul>Anzahl der Vergleiche: 1
  39. 39. Bad Character - Beispiel II <ul><li>Text a a c a a c a a b </li></ul><ul><li>Muster a a b </li></ul>Anzahl der Vergleiche: 2
  40. 40. Bad Character - Beispiel II <ul><li>Text a a c a a c a a b </li></ul><ul><li>Muster a a b </li></ul>Anzahl der Vergleiche: 5
  41. 41. Bad Character-Regel <ul><li>Sei A das verwendete Alphabet, </li></ul><ul><li>und c ein Zeichen aus dem Alphabet A , </li></ul><ul><li>dann liefert die Funktion s(c) </li></ul><ul><ul><li>die Position des letzten Auftretens von c im Muster </li></ul></ul><ul><ul><li>den Wert -1 , falls c nicht im Muster auftaucht. </li></ul></ul><ul><li>Für einen Mismatch an Position j gilt: </li></ul><ul><li>Shift = j – s(c) , sofern s(c) < j </li></ul>
  42. 42. Bad Character-Regel - Laufzeit <ul><li>Im Best-Case hat der Boyer-Moore-Algorithmus dank der Bad Character-Regel eine Laufzeit von </li></ul><ul><li>n / m </li></ul><ul><li>Im Worst-Case hat er mit der Bad Character-Regel alleine jedoch eine Laufzeit von </li></ul><ul><li>n · m </li></ul>
  43. 43. Sprungtabelle <ul><li>Der Boyer-Moore-Algorithmus benötigt zusätzlich eine Sprungtabelle, </li></ul><ul><li>um auch im Worst-Case eine Laufzeit linear zu n zu erreichen. </li></ul><ul><li>Vorgehen: </li></ul><ul><li>Berechne die Längen der Teilzeichenfolgen des Musters, die auch Suffixe des Musters sind.  Good Suffix </li></ul><ul><li>Berechne die Sprungtabelle. </li></ul>
  44. 44. Good Suffix - Beispiel <ul><li>Text: Wiederholung von </li></ul><ul><li>baabaabaaaabaabaabaaaabaabaabaaaa... </li></ul><ul><li>baabaabaaba </li></ul><ul><li>Muster </li></ul>Anzahl der Vergleiche: 0
  45. 45. Good Suffix - Beispiel <ul><li>Text: Wiederholung von </li></ul><ul><li>baabaabaa a a baabaabaaaabaabaabaaaa... </li></ul><ul><li>baabaabaa b a </li></ul><ul><li>Muster </li></ul>Anzahl der Vergleiche: 2
  46. 46. Good Suffix - Beispiel <ul><li>Text: Wiederholung von </li></ul><ul><li>baabaaba a aaba abaabaaaabaabaabaaaa... </li></ul><ul><li>baabaa b aaba </li></ul><ul><li>Muster </li></ul>Anzahl der Vergleiche: 7 Shift um 2
  47. 47. Good Suffix - Beispiel <ul><li>baabaaba a aaba abaabaaaabaabaabaaaa... </li></ul><ul><li>baabaa b aaba </li></ul>Anzahl der Vergleiche: 7 Weak Good Suffix!
  48. 48. Good Suffix - Beispiel <ul><li>baabaaba a aabaaba abaaaabaabaabaaaa... </li></ul><ul><li>baa b aabaaba </li></ul>Anzahl der Vergleiche: 15 Mismatch an derselben Stelle im Text mit dem gleichen Zeichen im Muster! Shift um 3
  49. 49. Strong Good Suffix-Regel <ul><li>Problem: Mit einer Weak Good Suffix-Regel hat der Boyer-Moore-Algorithmus in diesem Fall eine Laufzeit von (n · m) / 6 </li></ul><ul><li>Lösung: Strong Good Suffix-Regel </li></ul><ul><li>Vorteil: An der Stelle, an der ein Mismatch erfolgte, befindet sich nach einem Shift ein anderes Zeichen als jenes, welches den Mismatch verursachte. </li></ul>
  50. 50. Strong Good Suffix - Beispiel <ul><li>Text: Wiederholung von </li></ul><ul><li>baabaabaa a a baabaabaaaabaabaabaaaa... </li></ul><ul><li>aaabaabaa b a </li></ul><ul><li>Muster </li></ul>Anzahl der Vergleiche: 2
  51. 51. Strong Good Suffix - Beispiel <ul><li>Text: Wiederholung von </li></ul><ul><li>baabaaba a aaba abaabaaaabaabaabaaaa... </li></ul><ul><li>aaabaa b aaba </li></ul><ul><li>Muster </li></ul>Anzahl der Vergleiche: 7 Shift um 2
  52. 52. Strong Good Suffix - Beispiel <ul><li>baabaaba a aaba abaabaaaabaabaabaaaa... </li></ul><ul><li>aaabaa b aaba </li></ul>Anzahl der Vergleiche: 7 Weak Good Suffix
  53. 53. Strong Good Suffix - Beispiel <ul><li>baabaaba a aaba abaabaaaabaabaabaaaa... </li></ul><ul><li>aaabaa b aaba </li></ul>Anzahl der Vergleiche: 7 Strong Good Suffix!
  54. 54. Strong Good Suffix - Beispiel <ul><li>baabaaba a aaba abaaba aaabaabaabaaaa... </li></ul><ul><li>a aaba abaaba </li></ul>Anzahl der Vergleiche: 18 Shift um 6 Bereits überprüfter Bereich wird erneut verglichen.
  55. 55. Kein Strong Good Suffix?! <ul><li>baabaaba a aaba abaabaaaabaabaabaaaa... </li></ul><ul><li>baabaa b aaba </li></ul>Anzahl der Vergleiche: 7 Weak Good Suffix
  56. 56. Regel für die Ränder <ul><li>Problem: Die übereinstimmende Zeichenfolge kommt kein zweites Mal (als Strong Good Suffix ) im Muster vor. </li></ul><ul><li>Folge: Die Sprungtabelle liefert für diesen Fall einen Shift von 0! </li></ul><ul><li>Lösung: Eine 2. Sprungtabelle wird berechnet, welche die eigentlichen Ränder des Musters berücksichtigt. </li></ul>
  57. 57. Randregel - Beispiel <ul><li>baabaaba a aaba abaabaaaabaabaabaaaa... </li></ul><ul><li>baabaa b aaba </li></ul>Anzahl der Vergleiche: 7 In einer 2. Sprungtabelle werden die eigentlichen Ränder des Musters berücksichtigt.
  58. 58. Randregel - Beispiel <ul><li>baabaabaaaa ba abaabaa a a baabaabaaaa... </li></ul><ul><li>ba abaabaa b a </li></ul><ul><li>To be continued ... </li></ul>Anzahl der Vergleiche: 9 Vorheriger Mismatch
  59. 59. Boyer-Moore: Top-Down <ul><li>Berechne die Tabelle für die Bad Character-Regel und die Sprungtabelle (Strong Good Suffix und Randregel). </li></ul><ul><li>Vergleiche das Muster mit dem Text, solange bis ein Mismatch auftritt. </li></ul><ul><li>Bei einem Mismatch ermittle anhand der aktuellen Position den Sprungwert für die Bad Character-Regel und für die Sprungtabelle. </li></ul><ul><li>Führe den größeren der beiden Shifts durch. </li></ul>
  60. 60. Algorithmus für die Bad Character-Regel <ul><li>Erzeuge eine Tabelle mit der Größe des verwendeten Alphabets und initialisiere die Felder mit dem Wert -1 . </li></ul><ul><li>Durchlaufe das Muster von links nach rechts </li></ul><ul><li>und speichere die Position des aktuellen Zeichens in der Tabelle. Als Index verwende das Zeichen. </li></ul><ul><li>Beispiel „abcab“: &quot;a&quot;  3, &quot;b&quot;  4, &quot;c&quot;  2, &quot;d&quot;  -1, ... </li></ul>
  61. 61. Algorithmus für die Sprungtabelle <ul><li>Berechne eine Zwischentabelle mit den Längen der Teilzeichenfolgen, die ein starkes Suffix des Musters sind. </li></ul><ul><li>Berechne anhand der Zwischentabelle die Sprungtabelle 1. für die Strong Good Suffix-Regel und die Sprungtabelle 2. für die Randregel. </li></ul><ul><li>Kombiniere beide Sprungtabellen. </li></ul>
  62. 62. Berechnung der Zwischentabelle <ul><li>Index i 0 1 2 3 4 5 6 7 8 </li></ul><ul><li>Muster P b a b a c b a b a </li></ul><ul><li>Suffixlänge N(i) 0 2 0 4 0 0 2 0 - </li></ul>N(i):= max{j: j ≥ 0 Λ P[(i – j + 1)..i] ist Suffix von P}
  63. 63. Berechnung der Zwischentabelle <ul><li>Index i 6 </li></ul><ul><li>Muster P b a b a c b a b a </li></ul><ul><li>Suffixlänge N(i) 2 </li></ul>N( 6 ):= max{j: j ≥ 0 Λ P[( 6 – j + 1).. 6 ] ist Suffix von P} = 2
  64. 64. Algorithmus für die Berechnung der Zwischentabelle (1) <ul><li>Durchsuche das Muster von rechts nach links per Brute-Force nach einem Suffix des Musters. </li></ul>d c b a b a c b a i,e b a a N(i) = i – a Muster P
  65. 65. Algorithmus für die Berechnung der Zwischentabelle (2) <ul><li>Falls gilt: a < i < e </li></ul><ul><li>Wird N(i) mit N(|P| + i - e - 1) berechnet. </li></ul><ul><li>1. Fall: N(|P| + i - e - 1) < i - a </li></ul>d c b a b a c b a b a i c b a b a N(i) = N(|P| + i – e - 1) N(3) = N(8) = 2 e a c b a b a
  66. 66. Algorithmus für die Berechnung der Zwischentabelle (3) <ul><li>2. Fall: N(|P| + i - e - 1) >= i - a </li></ul>a b a b a c b a b a i b a b a N(i) >= N(|P| + i – e - 1) N(2) = N(7) + 1 = 2 + 1 = 3 e a b a b a
  67. 67. Berechnung der Sprungtabelle 1. <ul><li>Für den Fall, dass </li></ul><ul><li>Gesucht Shift s minimal mit: N(|P| - s – 1) = |P| - j - 1 </li></ul>Text Muster P Muster P Fehler bei i + j i s |P| - j - 1 s
  68. 68. Berechnung der Sprungtabelle 2. <ul><li>Für den Fall, dass </li></ul><ul><li>Gesucht Shift s minimal mit: N(|P| - s – 1) = |P| - s </li></ul>Text Muster P Muster P Fehler bei i + j i s |P| - s
  69. 69. Laufzeiten bei Boyer-Moore I <ul><li>Für die Berechnung der Bad Character-Regel: </li></ul><ul><ul><li>Abhängig von der Größe des Alphabets </li></ul></ul><ul><ul><li>Allerdings: Keine Zeichenfolgenvergleiche </li></ul></ul><ul><ul><li>Sondern: Nur Speicherzugriffe über einen Index </li></ul></ul><ul><li>Für die Berechnung der Sprungtabelle 1. und 2.: </li></ul><ul><ul><li>Vergleichbar zum KMP </li></ul></ul><ul><ul><li>Laufzeit: linear </li></ul></ul>
  70. 70. Laufzeiten bei Boyer-Moore II <ul><li>Für die eigentliche Suche: </li></ul><ul><ul><li>Unterscheidung zwischen initialen und wiederholten Vergleichen mit einem Zeichen im Muster </li></ul></ul><ul><ul><li>Laufzeit: linear </li></ul></ul><ul><li>Für den Boyer-Moore-Algorithmus insgesamt: </li></ul><ul><ul><li>Aufwendige Analyse </li></ul></ul><ul><ul><li>Maximal 3(n + m) Vergleiche notwendig </li></ul></ul>
  71. 71. Fazit: Vorteile von Boyer-Moore <ul><li>Bad Character-Regel </li></ul><ul><li> Große Alphabete: Proteine </li></ul><ul><li>Muster von rechts nach links vergleichen </li></ul><ul><li> Im Best-Case eine Laufzeit von n / m </li></ul><ul><li>Strong Good Suffix-Regel </li></ul><ul><li> Im Worst-Case eine Laufzeit von 3 (n + m) </li></ul>
  72. 72. Vergleich zu Knuth-Morris-Pratt Um so größer das verwendete Alphabet ist und um so weniger Wiederholungen das Muster und der Text enthält, um so stärker nähert sich die tatsächliche Laufzeit der Laufzeit im Best-Case an. 3 (n + m) 2 (n + m) Worst-Case n / m 2 (n + m) Best-Case Boyer-Moore Knuth-Morris-Pratt Algo Case
  73. 73. Noch Fragen??? <ul><li>May the source be with you ... </li></ul>

×