UNIVERSITA’ DI MILANO-BICOCCA LAUREA MAGISTRALE IN BIOINFORMATICA Corso di BIOINFORMATICA: TECNICHE DI BASE Prof. Giancarlo Mauri Lezione 5 Algoritmi di string matching esatto
Exact matching: il problema DATE: una stringa T di lunghezza n (detta testo) e una stringa P di lunghezza m<n (detta pattern) definite su un alfabeto S TROVARE: l’ insieme di tutte le posizioni nel testo T a partire da cui occorre il pattern P Il confronto di sequenze su larga scala, di solito nella forma di ricerca in un DB, è uno strumento molto potente per l’inferenza biologica nella biologia molecolare moderna, ed è universalmente usato dai biol. Mol. . La scoperta di un legame tra geni che causano il cancro e geni coinvolti normalmente nel processo di crescita è stato il primo risultato significativo nel confronto di sequenze.
Exact matching: il problema Esempio Algoritmo di exact matching P=aba T=bbabaxababay NB: le occorrenze di P in T possono anche sovrapporsi (es. 7 e 9) {3,7,9}
Exact matching: prime idee Algoritmo “forza bruta” Allinea il primo carattere di P con il primo carattere di T Confronta, da sinistra a destra, i caratteri corrispondenti di P e T fino a quando trovi un mismatch o raggiungi la fine di P Se hai raggiunto la fine di P, restituisci la posizione del carattere di T che corrisponde al primo carattere di P Sposta P di un posto a destra Se l’ultimo carattere di P va oltre la fine di T, termina l’esecuzione; altrimenti ripeti da 2 Ci sono vari modi per formalizzare la nozione di distanza tra stringhe. La distanza di edit” si focalizza sulla trasformaz di una stringa nell’altra attraverso una successione di operazioni di modifica di singoli caratteri: cancell, inserim, sostituz.
Exact matching: prime idee Se hai raggiunto la fine di P, restituisci la posizione del carattere di T che corrisponde al primo carattere di P => 6 Confronta, da sinistra a destra, i caratteri corrispondenti di P e T fino a quando trovi un mismatch o raggiungi la fine di P L’ultimo carattere di P va oltre la fine di T. Termina l’esecuzione Sposta P di un posto a destra... Confronta, da sinistra a destra, i caratteri corrispondenti di P e T fino a quando trovi un mismatch o raggiungi la fine di P Confronta, da sinistra a destra, i caratteri corrispondenti di P e T fino a quando trovi un mismatch o raggiungi la fine di P Sposta P di un posto a destra Sposta P di un posto a destra Confronta, da sinistra a destra, i caratteri corrispondenti di P e T fino a quando trovi un mismatch o raggiungi la fine di P Sposta P di un posto a destra Allinea il primo carattere di P con il primo carattere di T Esempio T = xabxyabxyabxz P = abxyabxz x a z b y T P z x b a y x b a y z z x b a y z x a b y a b x y z a z b x y z x b a y z x b a y
Exact matching: prime idee Caratteristiche dell’algoritmo “forza bruta” Non è necessaria una fase di pre-processing Il pattern P viene sempre spostato di una posizione a destra La complessità in tempo è O(nm) NB: non sempre è necessario spostare P di una sola posizione. Come aumentare lo spostamento senza rischiare di perdere occorrenze?
Exact matching: preprocessing Fase di pre-processing per imparare la struttura “interna” del pattern P o del testo T e RIDURRE IL TEMPO DI ESECUZIONE Un’altra possibile rappresentazione è attraverso l’allineamento Un allin può essere facilmente trasformato in un transcript e viceversa. Tuttavia, pur matematicam equivalenti, hanno significato diverso: Transcript enfasizza un ipotetico proceso evolutivo, e dipende dalle operazioni assunte, allineam confronta i prodotti del processo.
Exact matching: preprocessing Def.: un suffisso S[i…|S|] di una stringa S è una sottostringa che inizia alla posizione i e termina alla posizione finale di S Esempio S = A A T G C A T T C G C T Def.: un prefisso S[1…i] di una stringa S è una sottostringa che inizia alla posizione 1 di S e termina alla posizione i Esempio Un’altra possibile rappresentazione è attraverso l’allineamento Un allin può essere facilmente trasformato in un transcript e viceversa. Tuttavia, pur matematicam equivalenti, hanno significato diverso: Transcript enfasizza un ipotetico proceso evolutivo, e dipende dalle operazioni assunte, allineam confronta i prodotti del processo. S = A A T G C A T T C G C T
Exact matching: preprocessing Si supponga di essere nella seguente situazione con P in s+1 T g a c t P s a g c q k NB: all’interno del matching lungo q=5 esiste la sottostringa P[3..5] = aga che coincide con il prefisso P[1..3]
Exact matching: preprocessing E’ evidente che conviene spostare P in s’+1 = s+(q-k)+1 Si supponga di essere nella seguente situazione con P in s T g a c t P s’ s q-k a g c k NB: si è così sicuri che esiste un matching iniziale di lunghezza k=3 per il prefisso P[1..3] NB: all’interno del matching lungo 5 esiste la sottostringa P[3..5]=“aga” che coincide con il prefisso P[1..3]
Exact matching: preprocessing Intuitivamente... Dato che il prefisso P[1...q] coincide con la sottostringa T[s+1…s+q], ci si chiede quale sia il minimo spostamento s’>s tale che: P[1...k] = T[s'+1…s'+k] Ovviamente s’ = s+q-k NB: il confronto dei primi k caratteri di P è superfluo
Exact matching: preprocessing Formalmente... Dato un pattern P[1, …, m], si calcola la sua funzione prefisso : {1,2,...,m} {0,1,...,m-1} [q] = max{k: k<q e P[1..k] è suffisso di P[1..q]} Calcoliamo D(n,m) risolvendo il problema più generale di calcolare D(i,j) per qualunque combinazione di valori di i e j. La progr din ha tre componenti: relaz di ricorrenza, calcolo tabulare, risalita. NB: p[q] è la lunghezza del più lungo prefisso di P che è anche suffisso di P[1..q] 1 m q k
Exact matching: preprocessing Algoritmo per il calcolo della funzione prefisso p begin m:=length(P); p(1):=1; k:=0; for q:=2 to m do while P[k+1]P[q] do k:=p[k]; if P[k+1]=P[q] then k:=k+1; p[q]:=k; end return p;
Exact matching: preprocessing Esempio di funzione prefisso p per un pattern P q 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 P[q] g a c t Calcoliamo D(n,m) risolvendo il problema più generale di calcolare D(i,j) per qualunque combinazione di valori di i e j. La progr din ha tre componenti: relaz di ricorrenza, calcolo tabulare, risalita. p[q] 1 2 a
Algoritmo di Knuth-Morris-Pratt begin n:= length(T); m:=length(P); p:= precomputed prefix function of P; q:=0; for i:=1 to n do while q>0 and P[q+1]T[i] then q:=p[q]; if P[q+1]=T[i] then q:=q+1; if q=m then print “pattern in i-m+1”; end Numero di matches Scansione da sx a dx Il prossimo carattere è diverso Il prossimo carattere è uguale Trovata occorrenza di P Cerca nuova occorrenza
Algoritmo di Knuth-Morris-Pratt Caratteristiche dell’algoritmo KMP E’ suddiviso in due fasi: pre-processing + ricerca effettiva Sposta in genere il pattern P di più posizioni a destra La complessità in tempo della fase di pre-processing è O(m) La complessità in tempo della fase di ricerca è O(n) Complessità algoritmo K-M-P: O(m+n)
Algoritmo di Boyer-Moore Idee generali Il confronto tra il pattern e il testo avviene da destra a sinistra Il numero dei confronti viene ridotto usando due euristiche euristica del carattere discordante (bad character rule) euristica del buon suffisso (good suffix rule) NB: quando pattern e testo non coincidono si sceglie il massimo tra gli spostamenti proposti dalle due euristiche
Algoritmo di Boyer-Moore Si supponga di essere nella seguente situazione con P in s E’ evidente che conviene spostare P in s’+1 = s+1+j-k T g a c t P s a g c k j NB: il carattere P[4] coincide con il carattere T[s+7]
Algoritmo di Boyer-Moore E’ evidente che conviene spostare P in s’+1 = s+1+j- k T g a c t P s’ a g c k NB: il carattere P[4] coincide con il carattere T[s+7]
Algoritmo di Boyer-Moore Intuitivamente... Dato che esiste un j (1jm) per cui P[j] T[s+j], trovare il massimo k (1km), se esiste, tale che: P[k] = T[s+j] Calcoliamo D(n,m) risolvendo il problema più generale di calcolare D(i,j) per qualunque combinazione di valori di i e j. La progr din ha tre componenti: relaz di ricorrenza, calcolo tabulare, risalita. e spostare P in s’+1 tale che s'+k = s+j
Algoritmo di Boyer-Moore Formalmente... Dato un pattern P, si trova la funzione carattere discordante l: l:{s1, s2,..., s|S|} {1,2,...,m} l[si] = max{k: 1km e P[k] = si} Calcoliamo D(n,m) risolvendo il problema più generale di calcolare D(i,j) per qualunque combinazione di valori di i e j. La progr din ha tre componenti: relaz di ricorrenza, calcolo tabulare, risalita. NB: s(i) è l’i-esimo simbolo dell’alfabeto S
Algoritmo di Boyer-Moore Algoritmo per il calcolo della funzione carattere discordante l begin m:=length(P); foreach s in S do l[s]:=0; for j:=1 to m do l[P[j]]:=j; return l; end Si verificano 3 casi...
Algoritmo di Boyer-Moore Euristica del carattere discordante CASO 1: il carattere discordante non appare nel pattern P T g a c t g Calcoliamo D(n,m) risolvendo il problema più generale di calcolare D(i,j) per qualunque combinazione di valori di i e j. La progr din ha tre componenti: relaz di ricorrenza, calcolo tabulare, risalita. P s a t c
Algoritmo di Boyer-Moore Euristica del carattere discordante CASO 1: il carattere discordante non appare nel pattern P T g a c t P s+6 a t c Calcoliamo D(n,m) risolvendo il problema più generale di calcolare D(i,j) per qualunque combinazione di valori di i e j. La progr din ha tre componenti: relaz di ricorrenza, calcolo tabulare, risalita. lo spostamento è tale da allineare il primo carattere di P con il carattere di T successivo al carattere discordante
Algoritmo di Boyer-Moore Euristica del carattere discordante CASO 2: l’occorrenza più a destra in P del carattere discordante è in una posizione k minore dell’indice j che corrisponde al carattere di P allineato con il carattere discordante T g a c t Calcoliamo D(n,m) risolvendo il problema più generale di calcolare D(i,j) per qualunque combinazione di valori di i e j. La progr din ha tre componenti: relaz di ricorrenza, calcolo tabulare, risalita. g P s a t g c g
Algoritmo di Boyer-Moore Euristica del carattere discordante CASO 2: l’occorrenza più a destra in P del carattere discordante è in una posizione k minore dell’indice j che corrisponde al carattere di P allineato con il carattere discordante T g a c t Calcoliamo D(n,m) risolvendo il problema più generale di calcolare D(i,j) per qualunque combinazione di valori di i e j. La progr din ha tre componenti: relaz di ricorrenza, calcolo tabulare, risalita. P s+3 a t g c lo spostamento è tale da allineare P[k] con il carattere discordante in T
Algoritmo di Boyer-Moore Euristica del carattere discordante CASO 3: l’occorrenza più a destra in P del carattere discordante è in una posizione k maggiore dell’indice j che corrisponde al carattere di P allineato con il carattere discordante T g a c t g Calcoliamo D(n,m) risolvendo il problema più generale di calcolare D(i,j) per qualunque combinazione di valori di i e j. La progr din ha tre componenti: relaz di ricorrenza, calcolo tabulare, risalita. P s a t g c g
Algoritmo di Boyer-Moore Euristica del carattere discordante CASO 3: l’occorrenza più a destra in P del carattere discordante è in una posizione k maggiore dell’indice j che corrisponde al carattere di P allineato con il carattere discordante T g a c t g Calcoliamo D(n,m) risolvendo il problema più generale di calcolare D(i,j) per qualunque combinazione di valori di i e j. La progr din ha tre componenti: relaz di ricorrenza, calcolo tabulare, risalita. P s+1 a t g c g si può solo effettuare lo spostamento di un posto a destra
Algoritmo di Boyer-Moore Si supponga di essere nella seguente situazione con P in s E’ evidente che conviene spostare P in s’ T g a c t P s a c g k j NB: la sottostringa P[2..5] coincide il suffisso P[5..7] e quindi con la sottostringa T[s+5..s+7]
Algoritmo di Boyer-Moore Si supponga di essere nella seguente situazione con P in s E’ evidente che conviene spostare P in s’ T g a c t P s’ a c g k NB: si è così sicuri che esiste un matching per la sottostringa P[2..5] NB: la sottostringa P[2..5] coincide il suffisso P[5..7] e quindi con la sottostringa T[s+5..s+7]
Algoritmo di Boyer-Moore Intuitivamente... Dato che il suffisso P[j+1, m] coincide con la sottostringa T[s+j+1, s+m], occorre trovare, se esiste,la posizione k<j più a destra tale che: P[k] P[j] P[k+1, k+m-j] = T[s+j+1, s+m] Calcoliamo D(n,m) risolvendo il problema più generale di calcolare D(i,j) per qualunque combinazione di valori di i e j. La progr din ha tre componenti: relaz di ricorrenza, calcolo tabulare, risalita. e spostare P in s’+1 tale che s'+k = s+j NB: il confronto dei caratteri di P da k a k+m-j è superfluo
Algoritmo di Boyer-Moore Formalmente... Dato un pattern P, si trova la funzione suffisso g: g: {0,1,...,m-1} {0,1,...,m-1} g[j] = max{k: k<j+1, P[j+1,...,m] suffisso di P[1..g[j]+m-j] e P[k] P[j]} Calcoliamo D(n,m) risolvendo il problema più generale di calcolare D(i,j) per qualunque combinazione di valori di i e j. La progr din ha tre componenti: relaz di ricorrenza, calcolo tabulare, risalita.
Algoritmo di Boyer-Moore Algoritmo per il calcolo della funzione suffisso g begin m:=length(P); P’:=inverso(P); :=funzione prefisso di P; //come KMP ’:=funzione prefisso di P’; //come KMP for j:=0 to m do [j]:=m-[m]; for l:=1 to m do j:=m-’[l]; if [j] > l - ’[l] then [j]:=l-’[l]; end return
Algoritmo di Boyer-Moore Euristica del buon suffisso CASO 1: k non esiste si sposta P fino a far coincidere un suo prefisso con un suffisso di T[s+j+1..s+m], o di m passi se nessun prefisso di P è suffisso di T[s+j+1..s+m] CASO 2: k esiste si sposta P fino del numero minimo di passi per far coincidere un suo prefisso proprio con un suffisso dell’occorrenza di P in T, o di m passi se questo non esiste Calcoliamo D(n,m) risolvendo il problema più generale di calcolare D(i,j) per qualunque combinazione di valori di i e j. La progr din ha tre componenti: relaz di ricorrenza, calcolo tabulare, risalita.
Algoritmo di Boyer-Moore Euristica del buon suffisso + Euristica del carattere discordante (esempio) T g a c t c P s a c g c Calcoliamo D(n,m) risolvendo il problema più generale di calcolare D(i,j) per qualunque combinazione di valori di i e j. La progr din ha tre componenti: relaz di ricorrenza, calcolo tabulare, risalita. l’euristica del carattere discordante genererebbe uno spostamento in s+1
Algoritmo di Boyer-Moore Euristica del buon suffisso + Euristica del carattere discordante (esempio) T g a c t c P s+1 a c g Calcoliamo D(n,m) risolvendo il problema più generale di calcolare D(i,j) per qualunque combinazione di valori di i e j. La progr din ha tre componenti: relaz di ricorrenza, calcolo tabulare, risalita. l’euristica del carattere discordante genererebbe uno spostamento in s+1
Algoritmo di Boyer-Moore Euristica del buon suffisso + Euristica del carattere discordante (esempio) T g a c t P s a c g Calcoliamo D(n,m) risolvendo il problema più generale di calcolare D(i,j) per qualunque combinazione di valori di i e j. La progr din ha tre componenti: relaz di ricorrenza, calcolo tabulare, risalita. l’euristica del buon suffissso genererebbe uno spostamento in s+4
Algoritmo di Boyer-Moore Euristica del buon suffisso + Euristica del carattere discordante (esempio) T g a c t P s+4 a c g Calcoliamo D(n,m) risolvendo il problema più generale di calcolare D(i,j) per qualunque combinazione di valori di i e j. La progr din ha tre componenti: relaz di ricorrenza, calcolo tabulare, risalita. l’euristica del buon suffissso genererebbe uno spostamento in s+4 che risulta essere lo spostamento da effettuare l’euristica del buon suffissso genererebbe uno spostamento in s+4
Algoritmo di Boyer-Moore n:=length(T); m:=length(P); :=BadCharacterRule(P); :=GoodSuffixRule(P); s:=0; while s ≤ n-m do begin j:=m; while j > 0 and P[j] = T[s+j] do j:=j-1; if j = 0 then stampa(“pattern in posizione s+1”); s:=s+[0]; else s:=s+max([j], j-[T[s+j]]); end /*Pre-processing*/ /*Scansione da destra*/ /*Proposta euristiche*/
Exact Matching: algoritmo di Boyer-Moore Car. discordante Buon suffisso ... ... f a i s c n r t l h b s s non valido a c m i n u l s + 4 proposta del car. discordante a c m i n u l s + 3 proposta del buon suffisso c l n u i m a Proposta vincente: carattere discordante
Algoritmo di Boyer-Moore Caratteristiche dell’algoritmo BM E’ suddiviso in due parti: pre-processing + ricerca effettiva Sposta in genere il pattern P di più posizioni a destra La fase di pre-processing è basata su due euristiche Funziona “bene” se il pattern P è relativamente lungo e se l’alfabeto |S| è ragionevolmente grande
Algoritmo di Boyer-Moore Caratteristiche dell’algoritmo BM La complessità in tempo della fase di pre-processing è O(|S|+m)+O(m)=O(|S|+m) La complessità in tempo della fase di ricerca è O(n-m+1)m=O(nm) La complessità in tempo di BM è O(nm) NB: nella pratica è più efficiente