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}