String matching
Algorithme de Rabin-Karp
L’objectif de cette partie est d’implanter l’agorithme de string matching de Rabin-Karp.
On rappelle qu’en Python les chaînes de caractères se comportent comme des tableaux:
>>> s = "Hello world!"
>>> len(s)
12
>>> s[0]
'H'
>>> s[4]
'o'
>>> s[-1]
'!'
>>> s[0:5]
'Hello'
>>> s[:3]
'Hel'
>>> s[6:]
'world!'
>>> s[:-1]
'Hello world'
On ne s’autorisera que les opérations ci-dessus pour implanter nos algorithmes. En effet, ce serait de la triche d’utiliser
s.index('ello')
1
:
Implanter l’algorithme de string matching naïf: coder une fonction
match(string, pattern) qui renvoie la position de la première
occurrence de pattern dans string.
Tester votre algorithme sur le génome de l’Escherichia coli (souche
K-12, MG1655), que vous pouvez télécharger dans la variable genome
avec les commandes suivantes:
from requests import get
from gzip import decompress
req = get('ecoli.gz')
genome = decompress(req.content).decode()[71:]
Alternativement, si vous avez du mal à télécharger depuis le notebook jupyter, téléchargez le fichier ici, mettez-le dans le même dossier que votre notebook, et chargez-le avec
from gzip import open
genome = open('ecoli.gz').read().decode()[71:]
Trouvez la première occurrence de la séquence GATTACA.
:
Modifiez votre code pour trouver toutes les occurrences de pattern,
en une seule passe sur string.
:
Réalisez une fonction rabin_karp(string, pattern, mod) implantant
l’algorithme de Rabin-Karp. Le paramètre mod est un entier
paramétrant l’algorithme. Vous êtes libres d’optimiser l’algorithme
pour la recherche de séquences d’ADN (pour mémoire, l’ADN est codé par
quatre symboles: A, G, C, et T).
Testez votre algorithme en cherchant le gène dit “aaaD”:
GTGAATATATCGAACAGTCAGGTTAACAGGCTGCGGCATTTTGTCCGCGCCGGGCTTCGC
TCACTGTTCAGGCCGGAGCCACAGACCGCCGTTGAATGGGCGGATGCTAATTACTATCTC
CCGAAAGAATCCGCATACCAGGAAGGGCGCTGGGAAACACTGCCCTTTCAGCGGGCCATC
ATGAATGCGATGGGCAGCGACTACATCCGTGAGGTGAATGTGGTGAAGTCTGCCCGTGTC
GGTTATTCCAAAATGCTGCTGGGTGTTTATGCCTACTTTATAGAGCATAAGCAGCGCAAC
ACCCTTATT
ainsi que le gène dit “accC”:
ATGCTGGATAAAATTGTTATTGCCAACCGCGGCGAGATTGCATTGCGTATTCTTCGTGCC
TGTAAAGAACTGGGCATCAAGACTGTCGCTGTGCACTCCAGCGCGGATCGCGATCTAAAA
CACGTATTACTGGCAGATGAAACGGTCTGTATTGGCCCTGCTCCGTCAGTAAAAAGTTAT
CTGAACATCCCGGCAATCATCAGCGCCGCTGAAATCACCGGCGCAGTAGCAATCCATCCG
GGTTACGGCTTCCTCTCCGAGAACGCCAACTTTGCCGAGCAGGTTGAACGCTCCGGCTTT
ATCTTCATTGGCCCGAAAGCAGAAACCATTCGCCTGATGGGCGACAAAGTATCCGCAATC
GCGGCGATGAAAAAAGCGGGCGTCCCTTGCGTACCGGGTTCTGACGGCCCGCTGGGCGAC
GATATGGATAAAAACCGTGCCATTGCTAAACGCATTGGTTATCCGGTGATTATCAAAGCC
TCCGGCGGCGGCGGCGGTCGCGGTATGCGCGTAGTGCGCGGCGACGCTGAACTGGCACAA
TCCATCTCCATGACCCGTGCGGAAGCGAAAGCTGCTTTCAGCAACGATATGGTTTACATG
GAGAAATACCTGGAAAATCCTCGCCACGTCGAGATTCAGGTACTGGCTGACGGTCAGGGC
AACGCTATCTATCTGGCGGAACGTGACTGCTCCATGCAACGCCGCCACCAGAAAGTGGTC
GAAGAAGCGCCAGCACCGGGCATTACCCCGGAACTGCGTCGCTACATCGGCGAACGTTGC
GCTAAAGCGTGTGTTGATATCGGCTATCGCGGTGCAGGTACTTTCGAGTTCCTGTTCGAA
AACGGCGAGTTCTATTTCATCGAAATGAACACCCGTATTCAGGTAGAACACCCGGTTACA
GAAATGATCACCGGCGTTGACCTGATCAAAGAACAGCTGCGTATCGCTGCCGGTCAACCG
CTGTCGATCAAGCAAGAAGAAGTTCACGTTCGCGGCCATGCGGTGGAATGTCGTATCAAC
GCCGAAGATCCGAACACCTTCCTGCCAAGTCCGGGCAAAATCACCCGTTTCCACGCACCT
GGCGGTTTTGGCGTACGTTGGGAGTCTCATATCTACGCGGGCTACACCGTACCGCCGTAC
TATGACTCAATGATCGGTAAGCTGATTTGCTACGGTGAAAACCGTGACGTGGCGATTGCC
CGCATGAAGAATGCGCTGCAGGAGCTGATCATCGACGGTATCAAAACCAACGTTGATCTG
CAGATCCGCATCATGAATGACGAGAACTTCCAGCATGGTGGCACTAACATCCACTATCTG
GAGAAAAAACTCGGTCTTCAGGAAAAATAA
Comparez les performances avec la méthode naïve, et avec différentes
valeurs pour mod, en utilisant la clef magique %time.
Automates finis
L’objectif de cette partie est d’implanter l’agorithme de string matching par automates finis vu en cours.
:
On considère l’automate fini représenté par la structure de données Python suivante:
automate = {
0: { 'a': 1 },
1: { 'b': 2, 'a': 1 },
2: { 'a': 3 },
3: { 'a': 4, b: 2 },
4: { 'b': 5, 'a': 1 },
5: { 'a': 6 },
6: { 'a': 7, b: 2 },
7: { 'a': 8, b: 5 },
8: { 'a': 1, b: 2 },
}
Où chaque ligne représente un état, l’état 0 étant l’état de départ
et l’état 8 étant l’état d’acceptation, et le dictionnaire associé à
chaque état représentant les transitions (le retour à l’état 0 est
représenté implicitement par l’absence d’une lettre dans la liste des
transitions).
Dessiner à la main cet automate. Quel pattern reconnaît-il ?
:
Écrire une fonction match(string, automaton) qui prend en entrée une
chaîne de caractères string, et un automate représenté comme au
point précédent, et qui renvoie les positions de toutes les
occurrences du pattern dans string.
Tester la fonction sur l’automate précédent.
:
Écrire une fonction qui calcule l’automate à partir d’un pattern. Tester sur les génomes de la partie précédente.