Cours10 PDF
Cours10 PDF
Cours10 PDF
Novembre 2012
. . . . . .
(C) 2012 Michel Van Caneghem () SIN5U1 : Algorithmique avancée #10 Novembre 2012 1 / 23
Recherche de motifs
. . . . . .
(C) 2012 Michel Van Caneghem () SIN5U1 : Algorithmique avancée #10 Novembre 2012 2 / 23
Algorithme naïf
i = 1; j = 1;
while (i <= m && j <= n) do
if (t[j] == x[i]) i++; j++;
else j = j - i + 2; i = 1;
if (i > m) then "motif trouve en j - m"
else "pas d'occurrences"
. . . . . .
(C) 2012 Michel Van Caneghem () SIN5U1 : Algorithmique avancée #10 Novembre 2012 3 / 23
Algorithme naïf (2)
1
(1 + )n ≤ 2n
q−1
si les caractères sont uniformément distribués dans le texte.
En pratique pour rechercher √ une chaîne de 7 chiffres parmi 100000
chiffres (les décimales de 2) j'ai fait 111267 comparaisons (th :
111111).
. . . . . .
(C) 2012 Michel Van Caneghem () SIN5U1 : Algorithmique avancée #10 Novembre 2012 4 / 23
Recherche avec automate
. . . . . .
(C) 2012 Michel Van Caneghem () SIN5U1 : Algorithmique avancée #10 Novembre 2012 5 / 23
Algorithme de Knuth Morris Pratt
. . . . . .
(C) 2012 Michel Van Caneghem () SIN5U1 : Algorithmique avancée #10 Novembre 2012 6 / 23
Algorithme de Knuth Morris Pratt (2)
motif : ABACABAC
texte : B A B A C A C A B A C A A B
A .
A B A C A B .
A B .
A .
A B A C A B .
A B
A B A C A B A C
s(i) = 0 1 1 2 1 2 3 4
. . . . . .
(C) 2012 Michel Van Caneghem () SIN5U1 : Algorithmique avancée #10 Novembre 2012 7 / 23
Algorithme de Knuth Morris Pratt (3)
i = 1; j = 1;
while (i <= m && j <= n) do
if (i >= 1 && t[j] != x[i]) i = s[i]
else {i++; j++;}
if (i > m) then "motif trouve en j - m"
else "pas d'occurrences"
. . . . . .
(C) 2012 Michel Van Caneghem () SIN5U1 : Algorithmique avancée #10 Novembre 2012 8 / 23
Algorithme de Knuth Morris Pratt (4)
On peut montrer que le nombre de comparaisons dans le pire des cas est
borné par 2n.
La complexité en moyenne est donnée par
1 2
(1 + − 2 )n
q−1 q
. . . . . .
(C) 2012 Michel Van Caneghem () SIN5U1 : Algorithmique avancée #10 Novembre 2012 9 / 23
Algorithme de Boyer et Moore
motif : OBELIX
texte : J E C H E R C H E U N G A U L O I S
. . . . . X
. . . . . X
. . . . . X
Nombre de comparaisons : 3
. . . . . .
(C) 2012 Michel Van Caneghem () SIN5U1 : Algorithmique avancée #10 Novembre 2012 10 / 23
Algorithme de Boyer et Moore (2)
O B E L I X *
d = 5 4 3 2 1 6 6
. . . . . .
(C) 2012 Michel Van Caneghem () SIN5U1 : Algorithmique avancée #10 Novembre 2012 11 / 23
Algorithme de Boyer et Moore (3)
j = m;
while (j <= n) do {
i = m;
while (i > 0 && t[j-m+i] == x[i]) do i--;
if i == 0 then "motif trouve en j - m"
else j = j + d[t[j]];
}
. . . . . .
(C) 2012 Michel Van Caneghem () SIN5U1 : Algorithmique avancée #10 Novembre 2012 12 / 23
Algorithme de Boyer et Moore (4)
2
n
q+1
ou souvent n/m comparaisons. En reprenant le même exemple on trouve
18181 comparaisons (soit 5 fois moins).
C'est cet algorithme amélioré qui est à la base de tous les outils de
recherche rapide du style egrep, fgrep, agrep, .... (qui sont d'une
rapidité stupéfiante)
Par exemple 100 copies des Misérables (260Mo) et on cherche le dernier
mot : grep -F archeopterix LesMiserables.txt. Le temps : 0,12 s.
. . . . . .
(C) 2012 Michel Van Caneghem () SIN5U1 : Algorithmique avancée #10 Novembre 2012 13 / 23
Algorithme de Rabin-Karp
. . . . . .
(C) 2012 Michel Van Caneghem () SIN5U1 : Algorithmique avancée #10 Novembre 2012 14 / 23
Algorithme de Rabin-Karp (2)
m−1
hi = ∑ code(t[i + k])dm−1−k (mod q)
k=0
. . . . . .
(C) 2012 Michel Van Caneghem () SIN5U1 : Algorithmique avancée #10 Novembre 2012 15 / 23
Algorithme de Rabin-Karp (3)
La complexité dans le pire des cas est O(mn), mais si q est bien choisi on
peut espérer une complexité linéaire : O(m + n).
L'intérêt de cet algorithme est de montrer que l'on a pu trouver un
algorithme très simple à programmer ayant une complexité linéaire.
D'un point de vue pratique, sauf si l'on fait des recherches multiples sur
des chaînes ayant les mêmes longueurs, cet algorithme semble n'avoir
aucun intérêt spécial.
. . . . . .
(C) 2012 Michel Van Caneghem () SIN5U1 : Algorithmique avancée #10 Novembre 2012 16 / 23
Recherches multiples
On veut rechercher en même temps plusieurs (p) motifs dans un texte.
La première idée consiste à appliquer p fois un des algorithmes
précédents. Cela implique qu'il faut passer p fois sur le texte.
Cela peut être amélioré en codant l'ensemble des motifs en partie
commune et en appliquant par exemple l'algorithme naïf.
b a b a
c
a b a
b c
b a b
a
b
. . . . . .
(C) 2012 Michel Van Caneghem () SIN5U1 : Algorithmique avancée #10 Novembre 2012 17 / 23
Recherches multiples (2)
. . . . . .
(C) 2012 Michel Van Caneghem () SIN5U1 : Algorithmique avancée #10 Novembre 2012 18 / 23
Recherche par expression régulière
. . . . . .
(C) 2012 Michel Van Caneghem () SIN5U1 : Algorithmique avancée #10 Novembre 2012 19 / 23
Recherche par expression régulière (2)
On sait que le langage reconnu par une expression régulière est le même
que celui reconnu par un automate d'état finis. Deux stratégies sont
possibles :
Construire l'automate déterministe reconnaissant l'expression
régulière. Cela sera très efficace, mais on risque d'avoir un très
grand nombre d'état.
Construire un automate non-déterministe (donc moins efficace)
mais dont le nombre d'état est proportionnel à la taille de
l'expression régulière.
C'est en général le deuxième choix que l'on fait.
. . . . . .
(C) 2012 Michel Van Caneghem () SIN5U1 : Algorithmique avancée #10 Novembre 2012 20 / 23
Recherche par expression régulière (3)
Théorème : Pour toute expression rationnelle e de taille m, il existe un
automate normalisé reconnaissant L(e), et dont le nombre d'états est au
plus 2m.
AB A B
A
A|B
B
A* A
. . . . . .
(C) 2012 Michel Van Caneghem () SIN5U1 : Algorithmique avancée #10 Novembre 2012 21 / 23
Recherche par expression régulière (4)
test = log(7,2);
test = log(x+y,b*3);
test = log(2,7);
test = log(b*3,x+y);
. . . . . .
(C) 2012 Michel Van Caneghem () SIN5U1 : Algorithmique avancée #10 Novembre 2012 22 / 23
Recherche par expression régulière (5)
Mais ceci est de base dans Java !!! et sans déclaration : ce sont des
méthodes de la classe String. Très souvent utilisé avec split pour
découper une chaîne en morceaux par des expressions régulières.
Bien sûr si vous voulez compiler les expressions régulières, il faut utiliser
les méthodes de la classe java.util.regex.
. . . . . .
(C) 2012 Michel Van Caneghem () SIN5U1 : Algorithmique avancée #10 Novembre 2012 23 / 23