Professional Documents
Culture Documents
1
Contents
1 Introduzione al Pattern Matching. 3
2 Keyword Tree 4
2.1 Caratteristiche . . . . . . . . . . . . . . . . . . . . . . . . . . . . 4
2.2 Costruzione . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 4
2.3 Ricerca . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 5
3 Algoritmo di Aho-Corasick 5
3.1 Automa di Aho-Corasick . . . . . . . . . . . . . . . . . . . . . . . 5
3.2 Ricerca . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 6
3.2.1 Complessità della ricerca . . . . . . . . . . . . . . . . . . 7
3.3 Costruzione dell'automa di Aho-Corasick . . . . . . . . . . . . . 8
3.3.1 Prima fase: funzione goto . . . . . . . . . . . . . . . . . . 8
3.3.2 Seconda fase: costruzione della funzione fail . . . . . . . . 8
3.3.3 Pseudocodice . . . . . . . . . . . . . . . . . . . . . . . . . 9
3.3.4 Complessità . . . . . . . . . . . . . . . . . . . . . . . . . . 10
6 Bioinformatica 16
6.1 Sequence Tagged Sites . . . . . . . . . . . . . . . . . . . . . . . . 16
6.2 Simple Sequence Repeats e TROLL . . . . . . . . . . . . . . . . . 16
6.2.1 TROLL . . . . . . . . . . . . . . . . . . . . . . . . . . . . 17
6.3 Motivi di Sequenza . . . . . . . . . . . . . . . . . . . . . . . . . . 17
6.4 Baeza-Yates & Perleberg (BYP) . . . . . . . . . . . . . . . . . . 18
2
1 Introduzione al Pattern Matching.
Un aspetto fondamentale della bioinformatica è lo studio delle informazioni
contenute nelle biosequenze. Queste sono costituite da stringhe di caratteri:
adenina (A), citosina (C), guanina (G) e timina (T) o uracile (U) ad sempio nel
caso del DNA o RNA.
Secondo il principio genetico del determinismo, è fattibile predire la funzione
di ogni gene nel genoma dalle relative informazioni di sequenza. Questo suppone
implicitamente che l'ambiente di ogni gene è inoltre calcolabile dalla sequenza
completa di genoma perché la funzione di una molecola può diventare espressiva
soltanto rispetto al relativo ambiente. Di conseguenza, le intere architetture
molecolari ed i processi di reazione molecolari in una cellula possono essere
calcolabile dalla sequenza genomica.
L'informatica ha il compito di considerare una varietà di problemi biologi-
camente importanti deniti soprattutto sulle sequenze, o sulle stringhe:
• ricostruzione delle serie lunghe di DNA dai suoi frammenti (fragment as-
sembly);
• determinazione di mappe siche e genetiche dai dati della sonda sotto i
vari protocolli sperimentali;
• immagazzinamento, richiamando e confrontando le stringhe del DNA;
• confronto di due o più stringhe per le somiglianze; cercando nelle basi di
dati le stringhe relative e le sottostringhe;
• denizione ed esplorazione di dierenti nozioni di stringhe relazionali;
• ricerca di modelli nuovi o mal deniti che occorrono frequentemente in
DNA;
• ricerca dei modelli strutturali in DNA e proteina;
Quando si determina una nuova sequenza, la prima operazione eettuata per
la sua caratterizzazione è la ricerca, all'interno di una banca dati, di sequenze
con un grado di similarità statisticamente signicativo rispetto alla sequenza in
esame. Questo prende il nome di pattern matching approssimato.
Ci concentreremo invece su un sottoproblema più semplice: il pattern match-
ing esatto su insiemi (exact set matching ). Il problema consiste nel localizzare
le occorrenze di più pattern appartenenti ad un insieme P = {P1 , . . . , Pz }in un
testo T [1, . . . , m].
Pk
Sia n = i=1 |Pi | il problema dell' Exact set matching può essere risolto con
un tempo O(|P1 | + m + . . . + |Pk | + m) = O(n + km) applicando un algoritmo
exact matching lineare una volta per ogni pattern dell'insieme (ovvero k volte).
Aho e Corasick furono tra i primi, intorno agli anni '80, ad arontare il
problema dello string matching esatto su un insieme di pattern.
L'algoritmo di Aho-Corasick ha complessità O(n+m+z), dove z è il numero
di occorrenze dei vari Pi in T. Per ottenere un tale risultato, serve una struttura
dati apposita.
3
Osservazione Per ottenere la complessità di P nell'ordine di O(n + m + z),
che implica una sola scansione del testo, bisognerà memorizzare gli elementi di
in modo eciente e "furbo". Nasce così una struttura dati chiamata keyword
tree (o trie ), che è una sorta di generalizzazione dei radix tree. L'algoritmo di
AC utilizzerà un trie per costruire un automa a stati niti che verrà utilizzato
per la ricerca, in modo simile all'algoritmo di Knuth-Morris-Pratt.
Per comprendere il funzionamento e la complessità dell'AC occorre prima
introdurre il keyword tree.
2 Keyword Tree
2.1 Caratteristiche
Un keyword tree (o trie ) per un insieme di pattern P è un albero K con le
seguenti caratteristiche:
2.2 Costruzione
Indicate le caratteristiche del keyword tree passiamo ora all'analisi dei passi
necessari per la sua costruzione per l'insieme P = P1 , . . . , Pz .
4
Figure 1: Keyword Tree
2.3 Ricerca
L'ultimo aspetto che resta da analizzare per concludere la nostra breve panoram-
ica sulla struttura dati keyword tree è la ricerca di una stringa s.
La ricerca è caratterizzata dai seguenti passi:
3 Algoritmo di Aho-Corasick
3.1 Automa di Aho-Corasick
Gli automi a stati niti possono esser considerati sia come modelli semplicati
di macchine che come meccanismi usati per specicare linguaggi, entrambi gli
aspetti sono utili al ne del problema del pattern matching. Diamo quindi una
denizione di automa a stati niti deterministico.
5
Un automa a stati niti deterministico è una quintupla A = hΣ, Q, g, q, F i,
dove Σ = {a1 , . . . , an } è l'alfabeto di input, Q = {q0 , . . . , qn } è un insieme nito
e non vuoto di stati, F ⊆ Q è l'insieme degli stati nali, q0 è lo stato iniziale
e g : Q × Σ 7−→ Q è la funzione di transizione che ad ogni coppia (carattere,
stato) associa uno stato successivo.
Assumiamo che la funzione di transizione non sia totale, ovvero il valore
g(q, a) è lo stato raggiunto dallo stato q mediante la transizione etichettata dal
carattere a, se presente. L'automa che a noi interessa è un automa di string
matching. Si parla di automa di string matching quando dato un pattern p,
tale automa Ap accetta l'insieme di tutte le parole contenenti p come susso.
Estendendo tale automa otterremmo l'automa di Aho-Corasick denito come
l'automa che accetta tutte le parole aventi una parola dell'insieme nito di
parole W come susso.
Detto questo siamo diamo allora la denizione dell'automa di Aho-Corasick.
L'automa viene denito mediante tre funzioni:
3.2 Ricerca
Vediamo ora come funziona la ricerca di un insieme di pattern all'interno di un
testo T [1...m], supponendo di aver gia inizializzato l'automa di AC. La funzione
di transizione può essere implementata mediante una tabella, che viene espressa
mediante una matrice. Devo:
• Partire dalla radice del trie ed eseguire fail transition nchè l'insieme resti-
tuito dalla funzione g non è vuoto per il carattere in esame.
6
Figure 2: Transizioni di Failure
7
A questo punto resta da considerare l'if alla ne del ciclo più interno, questo
sarà eseguito tante volte quante sono le occorrenze del pattern cercato, ovvero
z volte: la complessità della ricerca, quindi, è O(m + z).
• nella prima fase si determinano gli stati dell'automa e il grafo della fun-
zione goto
la costruzione della funzione output ha inizio nelle prima fase e si conclude nella
seconda fase.
La funzione goto e il suo grafo non sono altro che un keyword tree, o
trie, come già detto: basterà quindi eseguire l'algoritmo per la costruzione del
keyword tree sull'insieme di pattern.
Per completare la funzione goto, vengono creati dei cicli sullo stato iniziale
settando g(0,a) = 0 per ogni simbolo a appartenente all'alfabeto, diverso dai
caratteri iniziali delle keyword nell'insieme.
8
Figura 3: Esempio di costruzione dell'automa di AC: risultato della prima fase
3.3.3 Pseudocodice
Dato che la prima fase della costruzione dell'automa di AC è banale mostreremo
solo lo pseudocodice della seconda fase:
9
Figura 4: Esempio di costruzione dell'automa di AC: primi passi della seconda
fase
Q = emptyQueue()
for ((a in Σ) and (g(0,a) 6= 0)):
f(g(0,a)) = 0
Q.add(s)
while not Empty(Q):
r = Q.remove()
for ((a in Σ) and (g(r,a) 6= 0)):
s = g(r,a)
Q.add(s)
state = f(r)
while (g(state,a) = None):
state = f(state) //(*)
f(s) = g(state,a)
out(s) = out(s) ∪ out(f(s))
3.3.4 Complessità
La costruzione del keyword tree è O(n), come abbiamo già mostrato. La sec-
onda fase, la costruzione della funzione fail, è una scansione in ampiezza del
keyword tree e, dunque, il corpo dell'iterazione verrà eseguito una sola volta
per ogni nodo. All'interno dell'iterazione abbiamo diverse istruzioni che possi-
amo ragionevolmente assumere O(1) ; i punti critici dell'algoritmo, che possono
far aumentare la complessità sono: il ciclo indicato con (*) per il calcolo della
funzione fail e l'aggiornamento delle funzioni di output.
10
Dimostreremo induttivamente che per i = 1...k il numero di iterazioni della
riga (*) è proporzionale ad i:
• Caso Base: è evidente che per u1 la riga marcata non viene eseguita
(per i nodi tali che d(u) = 1 f (u) viene azzerata nell'inizializzazione della
scansione in ampiezza) e per u2 viene eseguita una sola volta.
11
2. Contenente un solo elemento: in questo caso l'elemento non sarà altro che
l'etichetta di f(u) ma essendo il nodo f(u) più vicino alla radice rispetto
ad u la sua etichetta deve essere più corta di quella del nodo u (per come
sono denite le etichette dei nodi), dunque out(u) = {L(u)} e out(f (u)) =
{L(f (u))} che sono disgiunti.
3. Se out(f(u)) contiene più di un elemento avremo che L(f (u)) ∈ out(f (u))
e gli elementi di out(f(u)) dierenti da L(f(u)) saranno stati inseriti es-
eguendo l'istruzione di aggiornamento qui discussa. Per questi elementi
vale, ricorsivamente, lo stessa proprietà che vale per gli elementi di out(u)
rispetto a quelli di out(f(u)) e avranno quindi lunghezza minore di L(f(u))
e quindi tutti gli elementi di out(f(u)) sono più corti di quello in out(u).
12
• La fase di preprocessing costruisce l'automa di Aho-Corasick per A ed
inizializza tutte le posizioni di C a 0.
• La fase di ricerca scandisce il testo T applicando Aho-Corasick con l'in-
sieme di pattern A (le sotto stringhe); quando viene trovato un pattern Pj
che termina in posizione i ≤ L [j] all'interno del testo T, viene incrementa-
to il contatore C [i − L [j] + 1] di un unità (contatore corrispondente alla
posizione di inizio di Pj nel testo).
Al termine della scansione di T ogni i tale che C [i] = z = |A| corrisponde alla
locazione di inizio di un occorrenza di P nel testo.
4.2 Esempio
Per fare pattern matching con caratteri Jolly per il pattern P = ΦAT CΦΦT CΦAT C ,
si esegue set pattern matching sull'insieme di pattern P = {00 AT C 00 ,00 T C 00 ,00 AT C 00 }
(insieme di tutte le sottostringhe massimali di P non contenenti caratteri Jolly).
Si procede scandendo il testo in modo sequenziale spostandoci sugli stati
dell'automa di Aho-Corarick generato in fase di preprocessing.
Arrivati alla ne del testo, l'unico contatore che risulta avere un valore uguale
a k = 3 è il contatore C[3]: questo indica quindi un occorrenza di P in posizione
3 del testo.
13
4.3 Complessità
Sia n la lunghezza della stringa con caratteri Jolly P e sia m la lunghezza del
testo.
La fase di preprocessing ha una complessità di O(n + m). Un costo di O(n)
è dovuto alla costruzione dell'automa di AC per l'insieme di pattern costitu-
ito dalle sottostringhe massimali di P non contenenti caratteri Jolly; questo
costo è O(n) in quanto, a causa della presenza di caratteri Jolly, la somma
delle lunghezze delle sottostringhe massimali non contenenti caratteri Jolly è
sicuramente minore o uguale alla lunghezza di P. A questa complessità si ag-
giunge un costo proporzionale alla lunghezza del testo, dovuto al dover azzerare
il contatore C in tutta la sua lunghezza.
La fase di ricerca ha una complessità di O(m + t) dove t è il numero delle
occorrenze. Infatti il costo O(m) è dovuto alla scansione sequenziale di tutto
il testo a cui si aggiunge un costo proporzionale al numero di occorrenze del
pattern all'interno del testo. Infatti ogni occorrenza incrementa una posizione
di C di un unità ed ogni posizione C [1] , . . . , C [m] è incrementata al più z volte.
Quindi t ≤ zm e quindi la fase di ricerca ha una complessità O(m) nel caso in
cui z è limitato da una costante.
E quindi possibile derivare il teorema che, se il numero di caratteri Jolly
è limitato da una costante, il pattern matching esatto con caratteri Jolly può
essere eettuato in tempo O(|P | + |T |).
E' da notare che la complessità della fase di ricerca è comunque legata al
numero di occorrenze presenti nel testo in quanto non si conoscono approcci
indipendenti del numero di occorrenze.
14
5 Baeza-Yates & Perleberg (BYP)
5.1 Introduzione al problema del Bounded Matching
La ricerca inesatta di una stringa S all'interno di una stringa (generalmente
molto più grande) T consiste nel cercare ogni occorrenza di S che può comparire
anche alcuni caratteri errati o mancanti e si risolve in modo simile al problema
di trovare un allineamento tra due stringhe con un algoritmo di programmazione
dinamica la cui complessità è O(nm) (dove |S| = n e|T | = m). Le prestazioni
di questa programmazione dinamica potrebbero essere considerate insucienti.
Per questo motivo si è scelto di esaminare una versione del problema della
ricerca inesatta di sottostringhe, semplicata alle sole occorrenze della stringa
S che compaiono con al più k errori. Questo problema viene detto di Bounded
Matching e, a dierenza del problema della ricerca inesatta, se ne conosce una
soluzione in O(m).
15
errori. Nel caso peggiore ognuna delle sottostringhe conterrà esattamente un
errore tranne una, dato che il numero massimo di errori è k mentre le stringhe
sono almeno k+1.
5.3 Complessità
Il primo punto e la costruzione dell'automa di AC possono essere eseguiti in
tempo O(n), la ricerca con l'automa di AC, da sola, viene eseguita in tempo
O(m). Dunque né il punto 1 né il punto 2 rappresentano un problema.
Più dicile è stabilire la complessità del terzo punto. Ogni esecuzione
dell'algoritmo di programmazione dinamica è O(n2 ) in quanto viene eseguito
su due stringhe di lunghezza O(n). Il numero medio di volte che una delle sot-
tostringhe costruite al punto 1 comparirà in T è m(k+1)
|Σ|r e quindi la complessità
2
del punto 3 sarà: O( mn|Σ|(k+1)
r ). Anché l'algoritmo sia lineare in m questa
quantità deve restare lineare in m ovvero:
mn2 (k + 1)
r ≤ cm
|Σ|
6 Bioinformatica
6.1 Sequence Tagged Sites
Uno dei primi obiettivi del sequenziamento di un genoma (ad esempio lo Human
Genome Project) è quello di mappare nel DNA un insieme di Sequence Tagged
Sites (STS), disposte in modo che ci sia almeno una STS ogni 100.000bp. Le
mappe di STS possono infatti essere utilizzate per localizzare l'esatta posizione
di una sequenza anonima all'interno del DNA.
Una STS non è altro che una stringa di 200 - 300bp le cui estremità, en-
trambe di circa 20 - 30bp, compaiono una sola volta all'interno del genoma;
di conseguenza l'intera STS compare dunque una sola volta nel genoma. Una
volta in possesso di una mappa di STS l'individuazione di una sequenza di
DNA anonima viene ridotta al problema di ricerca multipla esatta, risolvibile
con l'Aho-Corasick.
16
utilizza appunto questa strategia, vedremo una breve descrizione di questo al-
goritmo.
6.2.1 TROLL
TROLL cerca i microsatelliti utilizzando una lista di motivi specicata dall'utente,
verranno trovati solo i microsatelliti composti da ripetizioni di questi motivi.
TROLL eseguirà la scansione della biosequenza in cui cercare i microsatelliti
usando l'algoritmo di AC con un automa costruito sopra la lista di motivi e
manterrà in memoria i microsatelliti correnti. Ogni microsatellite verrà rappre-
sentato da tre parametri:
• Il motivo di cui è composto
• La posizione di inizio
• La lunghezza del microsatellite (nora)
Ogni volta che l'AC trova un motivo si aggiorna la struttura dati contenente
i microsatelliti correntemente attivi (eventualmente rimuovendo microsatelliti
terminati o aggiungendo un nuovo microsatellite, minimale, composto da una
sola ripetizione del motivo trovato).
Un'implementazione naif della struttura dati dei microsatelliti attivi porterebbe
ad un algoritmo O(mz), dove m è la lunghezza del testo cercato e z è il numero
di motivi. TROLL, invece, utilizza una matrice triangolare inferiore le cui celle
contengono descrizioni di microsatelliti, la cella di indice (i,j) conterrà un mi-
crosatellite il cui motivo è lungo i e che comincia in posizione ki + j dove k è
un intero qualsiasi.
Ogni volta che l'AC trova un motivo si dovrà solo controllare la cella (len,
start%len) dove start è la posizione di inizio del motivo trovato e len è la
lunghezza del motivo trovato.
Inoltre, TROLL, contiene un semplice accorgimento che gli permette di
evitare di segnalare per la stringa ACTACTACT microsatelliti di ACT, CTA e
TAC ma solo uno (il più lungo).
17
CΦΦCΦΦΦΦΦΦΦΦΦΦΦΦΦHΦΦH
dove C e H indicano la presenza degli amino acidi della cysteine e dell'
histidine mentre Φ è il carattere Jolly.
1. Prima del sequenziamento su larga scala diversi pezzi più piccoli di DNA
vengono sequenziati e inseriti in basi di dati. Si è spesso interessati a
comparare le sequenze generate dal sequenziamento su larga scala con
quelle già presenti nel database. Ci si aspetta, infatti, che il numero di
dierenze sia minimo e facilmente limitabile. In questo modo è possibile
correggere le sequenze nel database dato che il sequenziamento su larga
scala è considerato più accurato.
References
[1] Ecient String Matching: An Aid to Bibliographic Search, A.V. Aho e
M.J. Corasick, Communications of ACM: June 1975 Vol. 18 Num. 6
18
[8] Structural Motif Wikipedia Article, http://en.wikipedia.org/wiki/Structural_motif
19