Telechargé par bvouvou

CM Recherche de motifs (algorithmique de texte)

publicité
Algorithmique du texte
Recherche de motifs
Introduction
Rechercher un motif dans un texte, indexer des données textuelles,
expliciter les régularités d’un texte sont des problèmes omniprésents en
informatique :
éditeur de texte, moteur de recherche, bases de données textuelles, analyse de séquences biologiques, compression
Contingences pratiques :
• on travaille sur des données de grande taille
⇒ il est impératif de trouver des algorithmes qui soient de petites
complexités à la fois en temps et en espace
• les données sont des séquences de caractères et n’ont pas de
structure explicite
⇒ définir des algorithmes rapides nécessite de définir les structures
adéquates pour représenter et manipuler efficacement les chaı̂nes de
caractères (structures pas trop coûteuses à construire et peu
gourmandes en espace)
2
Notations
Un alphabet Σ : un ensemble fini de symboles, appelés lettres ou
caractères
Un motif ou un texte sur l’alphabet Σ : une suite de lettres de Σ
La longueur d’un mot w, notée |w| : le nombre de lettres du mot
Le mot vide, i.e., le mot de longueur 0 : ε
Par convention, on indice les lettres d’un mot à partir de 0 :
w = w[0]w[1] . . . w[n − 1] avec n = |w|
La séquence de lettres partant de la position i et de longueur j :
w[i : i + j] = w[i]w[i + 1] . . . w[i + j − 1]
Σ∗ : l’ensemble de tous les mots sur Σ
Σ+ : l’ensemble de tous les mots non vides sur Σ
3
Notations
Les préfixes de w :
Pref(w) = {x : il existe y ∈ Σ∗ tel que w = xy}
Les suffixes de w :
Suf(w) = {y : il existe x ∈ Σ∗ tel que w = xy}
Les facteurs de w :
Fact(w) = {z : il existe x, y ∈ Σ∗ tel que w = xzy}
Un préfixe, suffixe ou facteur d’un mot w est propre, s’il est différent de
w lui-même.
Exemple
w = abbaac
Pref(w) =
Suf(w) =
Fact(w) =
4
Notations
Les préfixes de w :
Pref(w) = {x : il existe y ∈ Σ∗ tel que w = xy}
Les suffixes de w :
Suf(w) = {y : il existe x ∈ Σ∗ tel que w = xy}
Les facteurs de w :
Fact(w) = {z : il existe x, y ∈ Σ∗ tel que w = xzy}
Un préfixe, suffixe ou facteur d’un mot w est propre, s’il est différent de
w lui-même.
Exemple
w = abbaac
Pref(w) = {ε, a, ab, abb, abba, abbaa, abbaac}
Suf(w) = {ε, c, ac, aac, baac, bbaac, abbaac}
Fact(w) = {ε, a, b, c, aa, ab, ac, ba, bb, aac, abb, baa, bba,
abba, baac, bbaa, abbaa, bbaac, abbaac}
4
Recherche de motif
Trouver les occurrences d’un motif u dans un texte t
0
u
1
n-1
texte t
i
motif u
0
m-1
Deux types de solutions
1. Motif fixé, texte variable
• Prétraitement sur le motif
basé sur des propriétés combinatoires du motif
• Recherche
2. Texte fixé, motif variable
• Prétraitement sur le texte
basé sur des techniques d’indexation
• Recherche
5
Menu des premières séances
Recherche d’un motif fixé dans un texte variable
Motif vu comme
- un simple mot
- une expression régulière
- un ensemble fini de mots
- un mot approché
Techniques variées :
- stratégie de la fenêtre coulissante
- basées sur les automates finis
- avec une structure de Trie
- via de la programmation dynamique
6
Stratégie de la fenêtre coulissante
Balayage et Décalage (Scan & Shift)
On lit le texte au travers d’une fenêtre coulissante de la taille du mot.
fenêtre
décalage
texte t
balayage
motif u
Schéma de base
Positionner la fenêtre au début du texte
Tant que la fenêtre est sur le texte
Si fenêtre == motif alors
Signaler occurrence
Décaler la fenêtre
Balayage
Décalage
7
Algorithme naı̈f
Recherche exhaustive
Entrée :
Un mot u de longueur m
Un texte t de longueur n
pour i de 0 à n-m faire
si u == t[i:i+m] alors
signaler une occurrence à la position i
Avec un balayage de gauche à droite
8
Algorithme naı̈f
Recherche exhaustive
Entrée :
Un mot u de longueur m
Un texte t de longueur n
pour i de 0 à n-m faire
si u == t[i:i+m] alors
signaler une occurrence à la position i
Avec un balayage de gauche à droite
Entrée :
Un mot u de longueur m
Un texte t de longueur n
i = 0
j = 0
tant que i < n-m+1
tant que j < m et u[j] == t[i+j] faire
j = j+1
si j == m alors
signaler une occurrence à la position i
i = i+1
j = 0
8
Algorithme naı̈f
Exemple
b
a
b
=
6=
Le texte : aababbabababb
Le
motif cherché : ababa
Exemple
a
a
b
a
b
a
b
a
b
a
b
a
b
a
a
b
a
b
a
a
b
a
b
a
a
b
a
b
a
a
b
a
b
a
a
b
a
b
a
a
b
a
b
a
a
b
a
b
a
a
b
a
b
b
Signaler occurrence
a
24 comparaisons
9
Algorithme naı̈f
Coût de l’algorithme au pire
Quel est le nombre maximal de comparaisons de l’algorithme naı̈f avec un
texte de longueur n et un motif de longueur m ?
Donner un exemple pour lequel ce nombre maximal est atteint
10
Algorithme naı̈f
Coût de l’algorithme au pire
Quel est le nombre maximal de comparaisons de l’algorithme naı̈f avec un
texte de longueur n et un motif de longueur m ? (n − m + 1) × m, i.e., une
complexité au pire en O(nm)
Donner un exemple pour lequel ce nombre maximal est atteint t = an ,
u = am
10
Algorithme naı̈f
Coût moyen de l’algorithme
σ dénote le nombre de lettres de l’alphabet Σ.
On se place dans le cas simple où toutes les lettres du texte et du mot
sont tirées avec une probabilité uniforme.
Probabilité que le balayage s’arrête après k comparaisons sur un échec
(i.e., u[: k − 1] = t[i : i + k − 1] et u[k − 1] 6= t[i + k − 1]) :
Probabilité que le balayage s’arrête sur un succès après m
comparaisons :
Nombre moyen de comparaisons réalisées lors de chaque balayage :
Le coût moyen est linéaire en la taille du texte, i.e., en O(n)
11
Algorithme naı̈f
Coût moyen de l’algorithme
σ dénote le nombre de lettres de l’alphabet Σ.
On se place dans le cas simple où toutes les lettres du texte et du mot
sont tirées avec une probabilité uniforme.
Probabilité que le balayage s’arrête après k comparaisons sur un échec
(i.e., u[: k − 1] = t[i : i + k − 1] et u[k − 1] 6= t[i + k − 1]) :
1
1
1
1
σ k−1 (1 − σ ) = σ k−1 − σ k
Probabilité que le balayage s’arrête sur un succès après m
1
comparaisons :
σm
Nombre moyen de comparaisons réalisées lors de chaque balayage :
m
m
m
P
P
P
1
1
k
m
k( σk−1
− σ1k ) + σmm =
( σk−1
k−1 − σ k ) + σ m
σ k−1 +
k=1
k=1
=
m−1
P
k=0
1
σk
=
1−1/σ m
1−1/σ
≤
1
1−1/σ
k=1
≤2
Le coût moyen est linéaire en la taille du texte, i.e., en O(n)
11
Algorithme naı̈f → Algorithme de Morris-Pratt
b
a
b
=
6=
Algo naı̈f : on oublie tout
Algo de Morris-Pratt : on mémorise les caractères du mot appareillés
à ceux du texte
a
a
b
a
b
a
b
a
b
a
b
a
b
a
a
b
a
b
a
a
b
a
b
a
a
b
a
b
a
a
b
a
b
a
a
b
a
b
a
a
b
a
b
a
a
b
a
b
a
a
b
a
b
b
Occurrence
a
12
Algorithme naı̈f → Algorithme de Morris-Pratt
b
a
b
=
6=
Algo naı̈f : on oublie tout
Algo de Morris-Pratt : on mémorise les caractères du mot appareillés
à ceux du texte
a
a
b
a
b
a
b
a
b
a
b
a
b
a
a
b
a
b
a
a
b
a
b
a
a
b
a
b
a
a
b
a
b
a
a
b
a
b
a
a
b
a
b
a
a
b
a
b
a
a
b
a
b
b
Décalage voué à l’échec
Décalage voué à l’échec
Occurrence
Décalage voué à l’échec
a
12
Algorithme naı̈f → Algorithme de Morris-Pratt
b
a
b
=
6=
Algo naı̈f : on oublie tout
Algo de Morris-Pratt : on mémorise les caractères du mot appareillés
à ceux du texte
a
a
b
a
b
a
b
a
b
a
b
a
b
a
a
b
a
b
a
a
b
a
b
a
a
b
a
b
a
a
b
a
b
a
a
b
a
b
a
a
b
a
b
a
a
b
a
b
a
a
b
a
b
b
Décalage voué à l’échec
Tests inutiles
Décalage voué à l’échec
Occurrence
Décalage voué à l’échec
a
Tests inutiles
12
Algorithme de Morris-Pratt
Principe
- Le balayage se fait de gauche à droite.
- Le décalage de la fenêtre est calculé à partir du motif et de ses bords
6=
=
t
0
=
u
i
Calculer un “bon” décalage suite à un échec à la position i :
Déterminer un préfixe propre de u[: i] qui soit également suffixe de u[: i],
et on veut le plus grand.
⇒ notion de bord
13
Bord
Un bord d’un mot w est un mot différent de w qui est à la fois préfixe et
suffixe de w
Le bord maximal de w, noté Bord(w), est le plus long bord de w
Exemple
w = abaababa
L’ensemble des bords de w :
Bord(w) =
w = aabaabaa
L’ensemble des bords de w :
Bord(w) =
14
Bord
Un bord d’un mot w est un mot différent de w qui est à la fois préfixe et
suffixe de w
Le bord maximal de w, noté Bord(w), est le plus long bord de w
Exemple
w = abaababa
L’ensemble des bords de w : {ε, a, aba}
Bord(w) = aba
w = aabaabaa
L’ensemble des bords de w : {ε, a, aa, aabaa}
Bord(w) = aabaa
14
Calculer le Bord
Fait
Pour tout mot u ∈ Σ+ et tout caractère a ∈ Σ :
(
Bord(u)a
si Bord(u)a est un préfixe de u
Bord(ua) =
Bord(Bord(u)a) sinon
u
a
x
a
Bord(u)
Bord(u)
ua
x=a
a
a
Bord(u)a
Bord(u)a
Pourquoi
Bord(u)a est
maximal ?
ua
x 6= a
x
Bord(Bord(u)a)
a
Bord(Bord(u)a)
Bord(Bord(u)a)
15
La table des bords
Définition (La table des bords d’un mot w)
Un tableau de |w| + 1 entiers, noté TB, et défini par :
−1
si i = 0
TB[i] =
|Bord(w[: i])| si i > 0
Exemple
w = abaababa
i
w[i-1]
TB[i]
0
1
a
2
b
3
a
4
a
5
b
6
a
7
b
8
a
1
a
2
a
3
b
4
a
5
a
6
b
7
a
8
a
w = aabaabaa
i
w[i-1]
TB[i]
0
16
La table des bords
Définition (La table des bords d’un mot w)
Un tableau de |w| + 1 entiers, noté TB, et défini par :
−1
si i = 0
TB[i] =
|Bord(w[: i])| si i > 0
Exemple
w = abaababa
i
w[i-1]
TB[i]
0
-1
1
a
0
2
b
0
3
a
1
4
a
1
5
b
2
6
a
3
7
b
2
8
a
3
1
a
0
2
a
1
3
b
0
4
a
1
5
a
2
6
b
3
7
a
4
8
a
5
w = aabaabaa
i
w[i-1]
TB[i]
0
-1
16
Calculer la table des bords
L’algorithme
Entrée : Un mot w de longueur m
Sortie : la table des bords TB de w
TB = [0, ..., 0]
TB[0] = -1
# table initialisée avec m+1 0
courant = -1
pour i de 0 à m-1 faire
# calculer TB[i+1]
tant que courant >= 0 et w[i] != w[courant] faire
courant = TB[courant]
courant = courant +1
TB[i+1] = courant
retourner TB
w[ :i]
Bord(w[:i])
Bord(w[:i])
Bord(Bord(w[:i]))
?
0
TB[TB[i]]
Bord(Bord(w[:i]))
?
w[i]
TB[i]
i
17
Calculer la table des bords
Complexité de l’algorithme
La complexité au pire est linéaire en la taille m du mot
Complexité est linéaire en le nombre de comparaisons entre lettres
≈ Nombre total de fois où la condition
courant >=0 et w[i] !=w [cour]
est examinée
La quantité ∆(i, courant) = 2i − courant augmente de 1 à chaque
comparaison
• Au début : ∆(0, −1) = 1
• À la fin : ∆(m − 1, courant) ≤ 2m − 2.
Donc #comparaisons ≤ 2m − 3.
18
Algorithme de Morris-Pratt
Exemple
Le motif cherché : ababa
0
i
w[i-1]
TB[i]
Exemple
-1
1
a
0
2
b
0
3
a
1
4
b
2
5
a
3
b
a
b
=
6=
Le texte : aababbabababb
a
a
a
b
a
b
a
a
b
a
b
a
a
b
1 − TB[1]
4 − TB[4]
b
a
b
a
b
a
a
b
a
2 − TB[2]
a
b
a
b
a
b
a
b
a
a
b
a
0 − TB[0]
a
b
b
Signaler occurrence
b
a
5 − TB[5]
16 comparaisons
À chaque étape, il est inutile de tester les TB[i] premiers caractères du motif
19
Algorithme de Morris-Pratt
L’étape recherche
Entrée :
Un mot u de longueur m
La table des bords TB de u
Un texte t de longueur n
i = 0
j = 0
tant que i < n-m+1 faire
tant que j < m et u[j] = t[i+j] faire
j = j+1
si j = m alors
signaler occurrence à la position j
i = i+j-TB[j]
# décalage
si TB[j] > 0 alors
j = TB[j]
# ne pas retester les 1ers caracs
sinon
j = 0
20
Algorithme de Morris-Pratt
Complexité de l’algorithme
La complexité au pire est linéaire en m+n , somme des tailles du mot et
du texte
• coût du prétraitement sur le motif :
Le calcul de la table des bords a un coût en O(m)
• coût de la recherche : O(n)
Considérer la quantité ∆0 (2i − j)
(croı̂t au moins de 1 à chaque comparaison)
Soit un coût en O(n)
21
De Morris-Pratt à Knuth-Morris-Pratt
b
a
b
=
6=
MP : on mémorise les caractères du mot appareillés à ceux du texte
KMP : on mémorise aussi les erreurs
a
a
b
a
b
a
b
a
b
a
a
b
a
b
a
a
b
a
b
a
b
a
a
b
a
a
a
b
a
b
a
b
a
a
b
a
b
b
Occurrence
b
a
22
De Morris-Pratt à Knuth-Morris-Pratt
b
a
b
=
6=
MP : on mémorise les caractères du mot appareillés à ceux du texte
KMP : on mémorise aussi les erreurs
a
a
b
a
b
a
b
a
b
a
a
b
a
b
a
a
b
a
b
a
a
b
a
a
b
a
b
a
a
b
a
b
a
a
b
a
b
b
Décalage voué à l’échec
Décalage voué à l’échec
Occurrence
b
a
22
Algorithme de Knuth-Morris-Pratt
Principe
- Le balayage se fait de gauche à droite.
- Le décalage de la fenêtre est calculé à partir du motif et de ses
bords stricts
6=
=
t
i
x
=
6=
0
u
y
Calculer un “bon” décalage suite à un échec à la position i :
Déterminer un préfixe propre de u[: i] qui soit suffixe de u[: i], et tel que
le caractère y suivant ce préfixe est différent du caractère x suivant le
suffixe (i.e., le caractère qui a provoqué l’échec)
Et on veut le plus grand ⇒ notion de bord strict
23
Bord strict
Soit w un mot et v un préfixe de w.
b est un bord strict de v relativement à w si
• b est un bord de v
• v = w ou w[|v|] 6= w[|b|]
Le bord strict maximal de v (relativement à w), noté BordStrict(v),
est le plus long bord strict de v quand il existe
w
v
x
BordStrict(w)
x
BordStrict(v)
Remarque : Le bord strict n’est pas toujours défini.
Exemple : Le préfixe ab n’admet pas de bord strict relativement à aba
24
La table des bords stricts
Définition (La table des bords stricts d’un mot w)
Un tableau de |w| + 1 entiers, noté SB, et défini par :
(
−1
si i=0 ou w[:i] n’a pas de bord strict
SB[i] =
.
|BordStrict(w[: i])| si i > 0
Fait
SB[0]
= −1
SB[|w|] = TB[|w|]
TB[i]
si w[i] 6= w[TB[i]]
SB[i]
=
SB[TB[i]] sinon
25
La table des bords stricts
Exemple
w = ababa
i
w[i-1]
TB[i]
SB[i]
0
Exemple
-1
-1
1
a
0
0
2
b
0
-1
3
a
1
0
−1
0
a
1
a
b
b
6=
=
=
=
w[0]
w[0]
w[1]
w[2]
5
a
3
3
a
a
w[1]
w[2]
w[3]
w[4]
4
b
2
-1
:
:
:
:
SB[1]
SB[2]
SB[3]
SB[4]
=
=
=
=
2
a
3
b
4
a
5
b
TB[1] = 0
SB[0] = -1
SB[1] = 0
SB[2] = -1
26
La table des bords stricts
Exemple
w = ababcab
Exemple
27
La table des bords stricts
Exemple
w = ababcab
i
0
Exemple
-1
-1
1
a
0
0
2
b
0
-1
3
a
1
0
4
b
2
2
5
c
0
-1
6
a
1
0
7
b
2
2
a
a
−1
0
a
b
1
a
b
c
2
a
3
b
4
c
5
a
6
b
7
b
b
27
Algorithme de Knuth-Morris-Pratt
Entrée : Un mot u de longueur m et un texte t de longueur n
Prétraitement
calcul de la table des bords de m
calcul de la table des bords stricts de m
Recherche
Même chose que pour Morris-Pratt
hormis le décalage calculé avec les bords stricts :
i = i+j-SB[j]
coût en O(m)
coût en O(m)
coût en O(n)
KMP offre une garantie supplémentaire par rapport à MP sur le nombre
de comparaisons maximal pour un caractère du texte.
Ce nombre est borné par :
- m pour MP
- logφ (1 + m) où φ =
√
1+ 5
2
pour KMP
Utile si on veut un algo à délai “constant” entre deux caracs traités
28
Algorithme de Knuth-Morris-Pratt
Exemple
Le motif cherché : ababa
i
w[i-1]
TB[i]
SB[i]
Exemple
0
-1
-1
1
a
0
0
2
b
0
-1
3
a
1
0
4
b
2
-1
5
a
3
3
b
a
b
=
6=
Le texte : aababbabababb
a
a
a
b
a
b
a
a
b
a
b
1 − SB[1]
b
a
b
a
b
a
a
b
a
b
a
a
b
a
b
b
a
4 − SB[4]
Signaler occurrence
b
a
5 − SB[5]
14 comparaisons
29
Téléchargement