CSI2510 Structures de données et algorithmes Recherche des motifs

publicité
Chaînes de caractères (string)
CSI2510
Structures de données et
algorithmes
Exemples de chaînes (ou séquences) de caractères:
Programme Java
HTML document
séquence DNA
Image numérique
Un alphabet S est l’ensemble des caractères utilisés dans
les mots d’un texte; Exemple d’ alphabets:
Recherche des motifs
ASCII
Unicode
{0, 1}
{A, C, G, T}
1
Recherche de motif
2
CSI2510 - Motifs
Recherche de motif : ‘Brute force’
Soit P une séquences de caractères de taille m
Une sous- séquence P[i .. j] de P est composée par les caractères entre i
et j
Un préfixe de P est une sous- séquence de type P[0 .. i]
Un suffixe de P est une sous- séquence de type P[i ..m - 1]
L’algorithme de recherche de motif “brute force”
compare le motif P avec le texte T pour chaque décalage
de P relatif à T, jusqu’à ce que:
Une correspondance est trouvée ou
on a essayé toutes les possibilités
Étant donné deux séquences T (texte) et P (motif), le
problème de recherche du motif est de trouver une sousséquences de T égale à P
a
b
a
c
a
a
c
Applications:
Éditeurs de texte
Moteurs de recherche
Recherche biologique
c a
CSI2510 - Motifs
a
3
a
c
a
a
a
b
c
a
a
c
a
a
c
a
a
c
a
CSI2510 - Motifs
c
a
4
1
Algorithme exhaustif Force brute
Algorithme de Boyer-Moore
Algorithm BruteForceMatch(T, P)
Input text T of size n and pattern
P of size m
Output starting index of a
substring of T equal to P or −1
if no such substring exists
for i ← 0 to n − m
{ test shift i of the pattern }
j←0
while ( j < m && T[i + j] = P[j])
j←j+1
if j = m
return i {match at i}
return -1 {no match anywhere}
Alphabet de taille moyenne et motif long
L’algorithme de recherche des motifs de Boyer-Moore
est basé sur deux heuristiques:
Heuristique Looking-glass:
Comparer P avec une sous-séquence de T en commençant
par la fin de P (jusqu’au premier caractère)
Heuristique character-jump:
Quand un “mismatch” arrive àT[i] = c (avec P[j])
Temps d’execution: O(nm)
Exemples du pire cas:
T = aaa … ah et P = aaah
Il pourrait se présenter en
images et en séquences ADN
Rare dans les langues
naturelles
CSI2510 - Motifs
5
Algorithme de Boyer-Moore
– Si P contient c, décaler P pour aligner la dernière occurrence (la
plus à droite) de c en P avec T[i]
– Si P ne contient pas c, décaler P complètement après T[i]
CSI2510 - Motifs
6
Algorithme de Boyer-Moore
Heuristique character-jump:
Heuristique looking-glass:
4
3 2
1
a
a x x b
Si P contient c, décaler P pour aligner la dernière occurrence (la
plus à droite) de c en P avec T[i]
CSI2510 - Motifs
7
CSI2510 - Motifs
8
2
Algorithme de Boyer-Moore
Algorithme de Boyer-Moore
Heuristique character-jump:
Heuristique character-jump:
Si P contient c, shift P pour aligner la dernière occurrence
(la plus à droite) de c en P avec T[i]
Si P ne contient pas c, décaler P pour aligner P[0] avec T[i + 1]
a
a
a x x b
x x x b
Si c est à la fin de P (parmi les caractères déjà vérifiés) se déplacer
d’une seule unité (voir exemple plus tard)
9
CSI2510 - Motifs
10
CSI2510 - Motifs
Algorithme de Boyer-Moore
Algorithme de Boyer-Moore
Heuristique character-jump :
Si P ne contient pas c, décaler P pour aligner P[0] avec T[i + 1]
T
a
p a t
r
1
i t h m
P
x x x b
CSI2510 - Motifs
a
11
t e r n
m a t c h i n g
CSI2510 - Motifs
a l g o r
i t h m
12
3
Algorithme de Boyer-Moore
Algorithme de Boyer-Moore
T
T
a
p a t
P
r
t e r n
m a t c h i n g
a l g o r
a
i t h m
p a t
2
i t h m
t e r n
P
r
Algorithme de Boyer-Moore
a l g o r
i t h m
3
i t h m
13
CSI2510 - Motifs
m a t c h i n g
14
CSI2510 - Motifs
Algorithme de Boyer-Moore
T
T
a
p a t
t e r n
m a t c h i n g
P
r
a l g o r
a
i t h m
p a t
t e r n
m a t c h i n g
P
4
i t h m
CSI2510 - Motifs
r
15
CSI2510 - Motifs
a l g o r
i t h m
5
i t h m
16
4
Algorithme de Boyer-Moore
Algorithme de Boyer-Moore
T
T
a
p a t
t e r n
m a t c h i n g
a l g o r
P
a
i t h m
p a t
t e r n
m a t c h i n g
a l g o r
6
i t h m
r
P
i t h m
r
7
i t h m
11 10 9 8
17
CSI2510 - Motifs
Algorithme de Boyer-Moore
Algorithm BMMatch(T, P)
Input: Text T with n characters, pattern P with
m characters
Output: Starting index first substring of T
matching P, or indication there is no match
// last(c)=-1 si P ne contient pas c
i←m−1
j←m−1
repeat
if T[i] = P[j]
if j = 0
return i {a match ! }
else
i←i−1
j←j−1
else {mismatch => a jump !}
i ← i + m – min(j, 1 + last(T[i]))
j←m−1
until i > n − 1
return “There is no match”
18
CSI2510 - Motifs
Algorithme de Boyer-Moore
.
Cas 1: j ≤ 1 + l
.
.
.
.
.
a .
i
.
.
.
.
b a
j l
m −j
.
.
.
.
a
c
a
b a
c
j
a b
Cas 2: 1 + l ≤ j
CSI2510 - Motifs
.
.
.
.
.
.
a .
l=
last
.
.
.
a .
i
.
.
.
.
d
c
a b
a
c
a
a
a b a
a b
b
b
4
3
c
a b
2
13 12 11 10 9
a b
a
c
b a
c
a
5
a
.
a b a
.
b .
j
m − (1 + l )
a .
a
1
b a
.
b a
b a
c
a b
a b
a
c
8
a b
7
a
b
6
a
b
b .
1+l
19
CSI2510 - Motifs
20
5
Algorithme de Boyer-Moore: Complexité
Algorithme de Boyer-Moore: Complexité
Garder un tableau de taille |∑|(alphabet). Pour chaque entrée mémoriser
la dernière occurrence en P de la lettre correspondante.
Construire cette fonction a coûté
O(m + |∑|)
else
0 2 1 -1
a b c d
{a jump !}
last(T[i])
i ← i + m – min(j, 1 + last(T[i]))
j←m−1
T
a
P
f c a b c e r l
m s a c a b b b
m mm o r f f h k
1
a c b h m
La partie de recherche: O(mn) au pire des cas comme brute-force
O(m + |∑|)
21
CSI2510 - Motifs
Algorithme de Boyer-Moore: Complexité
Le temps d’exec. de l’algorithme
Boyer-Moore est O(nm + |∑|) au
pires des cas
a
a
6
5
4
3
2
1
b
a
a
a
a
a
Exemple du pire cas :
a
a
12 11 10
T = aaa … a
P = baaa
b
Le pire de cas peut arriver dans les
images et les séquences ADN; il est
rare dans le texte;
Boyer- Moore beaucoup plus vite
que l’algorithme ‘brute force’ pour
les textes
CSI2510 - Motifs
a
a
a
a
a
9
8
7
a
a
a
a
a
a
a
a
L’algorithme Knuth-Morris-Pratt compare le motif avec le texte
de-gauche-a-droite, mais le décalage est choisi de façon plus
intelligente que dans l’algorithme ‘brute force’
a
Quand il y a un “mismatch” quel est le décalage maximal que l’on
puisse faire pour éviter les comparaisons redondantes ?
Réponse:
Aligner le plus long préfixe de P[0..j] qui est un suffixe de P[1..j]
a
24 23 22 21 20 19
b
a
a
a
a
22
Algorithme KMP
18 17 16 15 14 13
b
CSI2510 - Motifs
a
23
CSI2510 - Motifs
24
6
Algorithme KMP
Algorithme KMP
Le plus long préfixe de P[0..j] qui est un suffixe de P[1..j]
a b a a b a
.
.
a b a a b x .
.
.
.
.
a b a a b a
Ex: j=4 ---- >
a b
Ex: j=5 ---- >
a b a a b a
a b a
Je dois trouver le préfixe
(aussi long que possible)
a b a a b a
qui s’apparie avec un suffixe
de la chaine en haut
a b a a b a
Ex: j=2 ---- >
a
mais ces deux chaines sont identiques!
Ex: j=1 ---- > none
25
CSI2510 - Motifs
Algorithme KMP
Algorithme KMP
Décalage tel que le préfixe
coïncide avec le suffixe
.
.
26
CSI2510 - Motifs
a b a a b x .
.
.
.
L’algorithme Knuth-Morris-Pratt
calcule en avance les préfixes du motif
qui coïncident avec ses suffixes
.
CSI2510 - Motifs
j
0
1
2
3
4
P[j]
a
b
a
a
b
a
F(j)
0
0
1
1
2
3
5
La “failure function” F(j) est définie
comme la taille du plus long préfixe de
P[0..j] qui est aussi un suffixe de P[1..j]
a b a a b a
Pas besoin de répéter
ces comparaisons
a b a a b a
a b a a b a
Recommencer
à comparer ici
j=2 ---- >
27
a
a b a a b a
j=3 ---- >
a
CSI2510 - Motifs
a b a a b a
j=4 ---- > a b
a b a a b a
j=5 ---- >
aba
28
7
Algorithme KMP
Algorithme KMP
L’algorithme Knuth-Morris-Pratt
modifie l’algorithme de ‘brute
force’ de manière que si le
“mismatch” arrive à (P[j] ≠ T[i])
on échange j par F(j - 1) et i (la
position dans T) reste la même
(ou si j =0, i est incrémentée de
1)
.
.
j
0
1
2
3
4
P[j]
a
b
a
a
b
a
F(j)
0
0
1
1
2
3
a b a a b x .
.
5
.
.
.
Donc, il n’y a pas plus que 2n
itérations de la boucle while
Donc, l’algorithme KMP a un
temps optimal de O(m + n)
a b a a b a
F(j − 1)
29
CSI2510 - Motifs
Algorithme KMP
Algorithme KMP
La “failure function” peut être
représentée par un tableau qui
peut être calculé en temps
O(m)
La construction est similaire à
celle de l’algorithme KMP
A chaque itération de la boucle
i augmente de un, OU
la quantité de décalage i - j
augmente de au moins un
(observez que F(j - 1) < j)
Donc il n y a pas plus que 2m
itérations de la boucle while
i
j
Algorithm failureFunction(P)
F[0] ← 0
i←1
j←0
while i < m
if P[i] = P[j]
{we have matched j + 1 chars}
F[i] ← j + 1
i←i+1
j←j+1
else if j > 0 then
{use failure function to shift P}
j ← F[j − 1]
else
F[i] ← 0 { no match }
i←i+1
CSI2510 - Motifs
Algorithm KMPMatch(T, P)
F ← failureFunction(P)
i←0
j←0
while i < n
if T[i] = P[j]
if j = m − 1
return i − j { match }
else
i←i+1
j←j+1
else
if j > 0
j ← F[j − 1]
else
i←i+1
return −1 { no match }
i est incrémenté de un, OU
La quantité de décalage i - j est
incrémentée de au moins un
(observez que F(j - 1) < j)
a b a a b a
j
CSI2510 - Motifs
La “failure function” peut être
représentée par un tableau qui
peut être calculé en un temps
O(m)
A chaque itération de la boucle
while :
31
a b a a b a
i
0
1
F(i)
0
0
2
3
4
5
30
Algorithm failureFunction(P)
F[0] ← 0
i←1
j←0
while i < m
if P[i] = P[j]
{we have matched j + 1 chars}
F[i] ← j + 1
i←i+1
j←j+1
else if j > 0 then
{use failure function to shift P}
j ← F[j − 1]
else
F[i] ← 0 { no match }
i←i+1
CSI2510 - Motifs
32
8
Algorithme KMP
i
j
a b a a b a
i
0
1
2
F(i)
0
0
1
3
4
5
{on a ‘matché’ 1 car.}
Algorithm failureFunction(P)
F[0] ← 0
i←1
j←0
while i < m
if P[i] = P[j]
{we have matched j + 1 chars}
F[i] ← j + 1
i←i+1
j←j+1
else if j > 0 then
{use failure function to shift P}
j ← F[j − 1]
else
F[i] ← 0 { no match }
i←i+1
Algorithme KMP
i
j
a b a a b a
i
0
1
2
F(i)
0
0
1
3
4
5
Algorithm failureFunction(P)
F[0] ← 0
i←1
j←0
while i < m
if P[i] = P[j]
{we have matched j + 1 chars}
F[i] ← j + 1
i←i+1
j←j+1
else if j > 0 then
{use failure function to shift P}
j ← F[j − 1]
else
F[i] ← 0 { no match }
i←i+1
Il n’y a pas de ‘match’ de 2 car… Il faut verifier s’il y a un
‘match’ avec 1 car.
CSI2510 - Motifs
Algorithme KMP
j
i
a b a a b a
i
0
1
2
F(i)
0
0
1
3
4
5
33
Algorithm failureFunction(P)
F[0] ← 0
i←1
j←0
while i < m
if P[i] = P[j]
{we have matched j + 1 chars}
F[i] ← j + 1
i←i+1
j←j+1
else if j > 0 then
{use failure function to shift P}
j ← F[j − 1]
else
F[i] ← 0 { no match }
i←i+1
CSI2510 - Motifs
35
CSI2510 - Motifs
Algorithme KMP
j
i
a b a a b a
i
0
1
2
3
F(i)
0
0
1
1
4
5
34
Algorithm failureFunction(P)
F[0] ← 0
i←1
j←0
while i < m
if P[i] = P[j]
{we have matched j + 1 chars}
F[i] ← j + 1
i←i+1
j←j+1
else if j > 0 then
{use failure function to shift P}
j ← F[j − 1]
else
F[i] ← 0 { no match }
i←i+1
CSI2510 - Motifs
36
9
Algorithme KMP
i
j
a b a a b a
i
0
1
2
3
4
F(i)
0
0
1
1
2
5
Algorithm failureFunction(P)
F[0] ← 0
i←1
j←0
while i < m
if P[i] = P[j]
{we have matched j + 1 chars}
F[i] ← j + 1
i←i+1
j←j+1
else if j > 0 then
{use failure function to shift P}
j ← F[j − 1]
else
F[i] ← 0 { no match }
i←i+1
On avait un ‘match’ de 1 car., maintenant de 2 !
i
j
a b a a b a
i
0
1
2
3
4
5
F(i)
0
0
1
1
2
3
Algorithm failureFunction(P)
F[0] ← 0
i←1
j←0
while i < m
if P[i] = P[j]
{we have matched j + 1 chars}
F[i] ← j + 1
i←i+1
j←j+1
else if j > 0 then
{use failure function to shift P}
j ← F[j − 1]
else
F[i] ← 0 { no match }
i←i+1
On avait un ‘match’ de 2 car., maintenant de 3 !
37
CSI2510 - Motifs
Algorithme KMP
CSI2510 - Motifs
38
Exemple
a b a c a a b a c c a b a c a b a a b b
1 2 3 4 5 6
a b a c a b
7
a b a c a b
8 9 10 11 12
a b a c a b
13
j
0
1
2
3
4
5
P[j]
a
b
a
c
a
b
F(j)
0
0
1
0
1
2
a b a c a b
14 15 16 17 18 19
a b a c a b
CSI2510 - Motifs
39
10
Téléchargement