Algorithmique 4. Cours 3
Transcription
Algorithmique 4. Cours 3
Algorithmique 4. Cours 3 Marie-Pierre Béal d’après Maxime Crochemore http://www.dcs.kcl.ac.uk/staff/mac/TSP/index.html Recherche d’un motif dans un texte Chaı̂nes de caractères Alphabet : un ensemble fini de lettres. A = {a, b, c, . . . , }. Mots : A∗ suites finies de lettres. Le mot vide est noté ε. La longueur d’un mot x est notée |x|. Notation x = x[0]x[1] · · · x[|x| − 1] = abaaabababa. i x[i] 0 a 1 b 2 a 3 a 4 a 5 b 6 a 7 b 8 a 9 b 10 a Chaı̂nes de caractères Préfixe : x est préfixe de y s’il existe un mot z tel que y = xz. Suffixe : x est suffixe de y s’il existe un mot z tel que y = zx. Facteur : x est facteur de y s’il existe des mot z, t tel que y = zxt. Positions : x apparaı̂t dans y en position i si y = uxv et |u| = i, ou encore si x = y [i]y [i + 1]...y [i + |x| − 1] = y [i, i + |x| − 1]. Périodes et bords Soit x un mot non vide et p un entier tel que 0 < p ≤ |x|. p est une période de x si l’une des conditions équivalentes suivantes est satisfaite. 1 x[i] = x[i + p], pour 0 ≤ i < |x| − p. 2 x est préfixe de y k , pour un entier k > 0, |y | = p. 3 x = yw = wz, pour des mots y , z, w avec |y | = |z| = p. Une telle chaı̂ne w est appelée un bord de x. La période de x, period(x), est sa plus petite période (peut être égale à |x|). Le bord de x est son plus long bord (peut être le mot vide) Périodes et bords de abacabacaba 4 8 10 11 abacaba aba a ε Recherche d’un motif dans un texte texte pattern ✛ ✲ position de l’occurrence Problème Trouver toutes les occurrences du motif (ou pattern) x de longueur m dans le texte y de longueur n. Plusieurs solutions selon que l’on considère que Le pattern est fixé : solutions avec un pré-traitement du pattern. Le texte est fixé : solutions basées sur la construction d’un index. ”Pattern matching” Étant donné un pattern x, trouver toutes les positions de x dans n’importe quel texte y . Pattern : une suite x de m symboles. t a t a Texte : une suite y de n symboles. c a c g t a t a t a t g c g t t Occurrences en positions 4, 6, 15. c a c g t a t a t a t g c g t t t a t a t t a t a Opération de base : comparaison de symboles (=, = 6 ) a t a a a t t a a Stratégie de la fenêtre glissante texte y fenêtre ✞ ☎décalage ✲ scan . . . . . . . scan . . . . . . . scan pattern x décalage ✲ Scan et décalage de la fenêtre mettre la fenêtre au début du texte while fenêtre est sur le texte do scan : if fenêtre = pattern then enregistrer une occurrence décalage : décaler la fenêtre vers la droite et mémoriser des informations pour les scans et décalages futurs Algorithme naı̈f c a c g t t a a t t a a t a t g c g t t a t Principe On ne mémorise rien. On décale de 1 position à droite Complexité temps O(m × n), espace supplémentaire O(1) Nombre de comparaisons de symboles au maximum ≈ m × n en moyenne ≈ 2 × n sur un alphabet à deux lettres avec des sources sans mémoire équiprobables et indépendantes. Algorithme naı̈f pos 0 x 0 u j τ u i σ n−1 m−1 RechercheNaı̈ve (string x, y ; integer m, n) pos ←− 0 while pos ≤ n − m do i ←− 0 while i < m and x[i] = y [pos + i] do i ←− i + 1 if i = m then output(”x apparaı̂t dans y en position”, pos) pos ←− pos + 1 Recherche du motif avec un automate On utilise l’automate déterministe minimal A(x) acceptant A∗ x, où A est l’alphabet de y Exemple x = abaa, A = {a, b} a b a a 0 b 1 b a 2 a 3 b 4 b Recherche de abaa dans état 0 b 0 a 1 b 2 b 0 a 1 a 1 b 2 a 3 a 4 b 2 a 3 a 4 b 2 b 0 a 1 · · Algorithme de recherche du motif Simple scan du texte avec l’automate A(x) RechercheParAutomate (string x, y ; integer m, n) (Q, A, initial, {terminal }, δ) est l’automate A(x) q ←− état initial if q est terminal then enregistrer une occurrence de x dans y while not fin de y do σ ←− symbole suivant de y q ←− δ(q, σ) if q est terminal then enregistrer une occurrence de x dans y Construction de l’automate A(x) automate ConstructionAutomate (string x) Soit initial un nouvel état Q ←− {initial } terminal ←− initial for all σ in A do δ(initial, σ) ←− initial while not fin de x do τ ←− symbole suivant de x r ←− δ(terminal, τ ) ajouter un nouvel état s à Q δ(terminal, τ ) ←− s for all σ in A do δ(s, σ) ←− δ(r , σ) terminal ←− s return (Q, A, initial, {terminal }, δ) Complexité Pattern x de taille m, texte y de taille n Avec un automate implémenté par matrice de transitions Pré-traitement de x Recherche dans le texte y Délai temps espace temps espace temps O(m × card(A)) O(m × card(A)) O(n) O(m × card(A)) constant Amélioration (plus difficile) On peut calculer l’automate A(x) en temps et espace O(m) indépendamment de la taille de l’alphabet. Animation de Thierry Lecroq http ://www.dcs.kcl.ac.uk/staff/mac/TSP/DOC/Thierry-Lecroqsma.pdf Algorithme de Boyer-Moore Rappel : l’algorithme naı̈f fait un scan de gauche à droite a a a b a c a b a a a a b a a a a a b a a a a a a b . a a b a a a a a . a a a . a a a b a a b a b . . Scan de droite à gauche : exemple 1 a a a b a c a b a a a a b a a a a a b a a a a a a b . a a b a a a a a . a a a . a a a b a a b a b . . Scan de droite à gauche : exemple 2 a a b b a a a b a b a a b a a a a a b . a b a a a . a a b a a . b b a b a a b b b a b b a b a a b a b . . Scan de droite à gauche et décalage texte pattern ··· c c g g c c t t c a c g g g c c c c g c t a t c t g a c g t c a g c règle de décalage (fonction d) dite du ”bon suffixe” règle de décalage dite du ”mauvais caractère” while fenêtre est sur le texte do u ←− plus long suffixe commun à fenêtre et pattern if u = pattern then enregistrer une occurrence décaler la fenêtre de d(u) positions à droite g ··· texte y pos pattern x τ u σ i ? u τ u σ i u ✛ décalage ✲ u texte y pos pattern x décalage ✛ ✲ Pré-calcul des occurrences les plus à droite des mots u : O(m) Le décalage de type 2 est la période de x Le tableau D implémente une règle de décalage dite règle ”du bon suffixe” : décalage = d(u) = D[i] Algorithme de Boyer-Moore (règle ”du bon suffixe”) texte y 0 pos pattern x 0 τ j u σ i u n−1 m−1 BM(string x, y ; integer m, n) pos ←− 0 while pos ≤ n − m do i ←− m − 1 while i ≥ 0 and x[i] = y [pos + i] do i ←− i − 1 if i = −1 then output(”x apparaı̂t dans y en position”, pos) pos ←− pos + period(x) else pos ←− pos + D[i] Calcul du décalage Fonction de décalage d : d(u) = min{|z| > 0 | (x suffixe de uz) ou (τ uz suffixe de x et τ u n’est pas suffixe de x, pour τ ∈ A)} Tableau des décalages D : D[i] = d(x[i + 1, m − 1]), pour i = 0, .., m − 1 τ u z ′′ x σ u u z′ Note 1 : u est un bord de uz ′′ Note 2 : |z ′ | est une période de uz ′ (et donc |z ′ | est une période de x) Complexité de Boyer-Moore Phase de pré-traitement calcul du tableau D O(m) (voir plus loin) Phase de recherche (de toutes les occurrences) temps de calcul O(n × m) nombre minimum de comparaisons n/m nombre maximum de comparaisons n × m Calcul de la table des suffixes Calcul d’un tableau Suf de taille m Suf [i] = longueur du plus long suffixe de x qui est un bloc se terminant en position i dans x pattern x Suf [i] i Complexité La complexité en temps et espace du calcul de Suf sur un pattern de taille m est O(m). i fixé : Suf [j] connu pour i < j ≤ m − 1 k = min{j − Suf [j] | i < j < m} (pos. la plus à gauche déjà vue) σ 6= τ ; σ ′ 6= τ ′ ; Suf [i + m − j − 1] = |u ′ | 0 x σ u τ′ i +m−j −1 u j i k τ u′ τ′ u′ m−1 σ′ u′ Si Suf [i + m − j − 1] < i − k : Suf [i] = Suf [i + m − j − 1] 0 i +m−j −1 σ u j i k τ x u u′ τ′ u′ σ′ m−1 u′ Si Suf [i + m − j − 1] > i − k : Suf [i] = i − k 0 x j i k τ u u′ σ σ i +m−j −1 u u′ σ′ m−1 u′ Si Suf [i + m − j − 1] = i − k : trouver Suf [i] en scannant à partir de la position k. Donne un nouveau k et un nouveau j (= i) Calcul linaire du tableau Suf , puis de D à partir de Suf Compute Suf(string x ; integer m) Suf [m − 1] ←− m ; k ←− m − 1 ; j ←− m − 1 ; for i ←− m − 2 downto 0 do if i > k and Suf [i + m − j − 1] 6= i − k then Suf [i] ←− min{Suf [i + m − j − 1], i − k} else j ←− i ; k ←− min{i, k} ; while k ≥ 0 and x[k] = x[k + m − j − 1] do k ←− k − 1 ; Suf [i] ←− j − k return Suf i 0 x[i] a Suf [i] 1 1 b 0 2 a 3 3 a 1 4 a 1 5 b 0 6 a 3 7 b 0 8 a 5 9 b 0 10 a 11 Initialisation de D en utilisant les périodes de x Suf [2] = 3 =⇒ période 8 ; Suf [0] = 1 =⇒ période 10 ; période 11 8 8 8 8 8 8 8 8 10 Calcul du tableau D à partir de Suf Suf [3] = 1 =⇒ D[9] ≤ 7 ; Suf [8] = 5 =⇒ D[5] ≤ 2 D[i] 10 11 // 11 /9 /5 /3 1 1 8 8 8 8 8 /8 2 8 /8 /8 4 10 // 10 // 10 /7 6 8 8 8 8 8 2 8 4 10 6 Calcul de D à partir de Suf Compute D(string x ; integer m ; table D) j ←− 0 ; for i ←− m − 2 downto −1 do if i = −1 or Suf [i] = i + 1 then while j < m − i − 1 do D[j] ←− m − i − 1 ; j ←− j + 1 ; for i ←− 0 to m − 2 do D[m − Suf [i] − 1] ←− m − i − 1 ; return D Algorithme de Boyer-Moore Horspool Le décalage de la fenêtre est contrôlé par la règle dite du ”mauvais caractère”. texte y pos pattern x τ u σ i τ u ✛ décalage ✲ z ✛ ✲ DA[τ ] On définit une table DA indicée par les caractères. La table DA vérifie : DA[τ ] = min{|z| > 0 | τ z suffixe de x} ∪ {|x|} décalage = DA[τ ] − |u| = DA[τ ] − m + i + 1 Algorithme de Boyer-Moore Horspool Calcul de la table DA Compute DA(string x ; integer m) for all σ in A do DA[σ] = m for i ←− 0 to m − 2 do DA[x[i]] = m − i − 1 return DA Algorithme de Boyer-Moore BM(string x, y ; integer m, n) ; pos ←− 0 while pos ≤ n − m do i ←− m − 1 while i ≥ 0 and x[i] = y [pos + i] do i ←− i − 1 if i = −1 then output(’x occurs in y at position ’, pos) pos ←− pos + period(x) else pos ←− pos + max{D[i], DA[y [pos + i]] − m + i + 1}