Algoritmos clásicos

Anuncio
Algoritmos para
strings
Bioinformática
12-2-16
Elvira Mayordomo
Hoy …
Notación básica para strings
 El problema de string matching:

 String
matching automata
 Boyer-Moore
 Árboles de sufijos (con otras aplicaciones)
 Vectores de sufijos
Basic bibliography
D. Gusfield: Algorithms on Strings, Trees,
and Sequences. Cambridge University
Press, 1997.
 T.H. Cormen, C.E. Leiserson, R.L. Rivest,
C. Stein: Introduction to Algorithms (3rd
ed.). MIT Press, 2009.

Notación









Alfabeto 
Símbolo (carácter, letra)
String (secuencia, cadena) s
Longitud de s, |s|
Cadena vacía 
n
*
s[i]
s[i,j]
Definiciones básicas






Concatenación s.t
s es un substring de t si t=usv (algún u,v)
s es un prefijo de t si t=sv (para algún v)
s es un sufijo de t si t=us (para algún u)
s es un substring (prefijo, sufijo) propio de t si s
es un substring (prefijo, sufijo) de t y s t
s es una subsecuencia de t si todos los
símbolos de s aparecen en el mismo orden en t
(pero no necesariamente seguidos)
“Overlap” de s y t

El solape de s y t es el string y que cumple:
1.
2.
3.





y es sufijo de s, (s=xy)
y es prefijo de t, (t=yz)
|y| es máximo cumpliendo 1. y 2.
Ov(s,t)=y
<s,t>= xyz, la mezcla de s y t
Pref(s,t)=x, Suff(s,t)=z
ov(s,t)= |Ov(s,t)|, pref(s,t)=|Pref(s,t)|,
|Suff(s,t)|
Ov(s,s)
suff(s,t)=
Algoritmos para strings …
Comparar, encontrar repeticiones …
 Algunos los usaremos directamente
 Buscar repeticiones exactas nos ayudará
en problemas más complicados

El problema del string matching



Consiste en encontrar un string (corto), el
patrón, como substring de un string (largo), el
texto
En bioinformática lo más frecuente es buscar un
fragmento nuevo de DNA (un gen) en una
colección de secuencias
En este caso permitimos un cierto error, pero el
pattern matching exacto es una subrutina
Enunciado del problema …
Entrada: Dos strings t= t1 … tn, p= p1 … pm
sobre 
 Salida: El conjunto de posiciones de t
donde aparece p, es decir, I  {1,…,
n-m+1} tales que i I sii ti … ti+m-1 =p

Algoritmo inocente …
Input:A pattern p=p1. . .pm and a text t=t1. . .tn.
I:=∅
for j:=0 to n-m do
i:=1
while pi = tj+i and i  m do
i:=i+1
if i=m+1 then {p1 … pm = tj+1 … tj+m}
I:=I{j+1}
Output: The set I of positions, where an occurrence of p as a substring
in t starts.
Ejemplo …
Algoritmo inocente …



¿Complejidad?
¿Casos peores?
Buscamos mejorar esto explotando la estructura
del patrón
t= ababb p=abb
Resto de métodos
Preprocesar el patrón
 Preprocesar el texto (árboles de sufijos)

Preprocesar el patrón:
String matching automata
Vamos a ver una solución en la que una
vez preprocesado p en tiempo O(|p|.||)
resolvemos el problema en una sola
pasada de t
 Usa autómatas finitos …

Autómata finito (DFA)
Un DFA es una 5-tupla (Q, , q0,, F) donde:
1) Q : conjunto de estados
2)  : alfabeto de entrada
4) q0  Q : estado inicial
3)  : función de transición
:QxQ
5) F  Q : conjunto de estados finales
(o de aceptación)
Ejemplo de autómata
Aceptar

El autómata acepta un string x si
empezando en q0 y siguiendo  llega a un
estado final …
String matching automata

Dado un patrón p=p1. . .pm construimos un
autómata que acepte los textos con sufijo
p (es decir, los textos que acaban en p)
Ejemplo p=aba
t= bababaa
Cada vez que encuentro aba llego al estado final 3
¿Por qué funciona?
Ir al estado i quiere decir p1. . .pi es “el
prefijo más largo de p que es sufijo de lo
que llevo leído del texto”
 O sea, si estoy en el estado i, lo que llevo
leído del texto termina en p1. . .pi

Cómo construir el autómata para
un patrón

(recordad) El solape de s y t es el string y
que cumple:
1. y
es sufijo de s, (s=xy)
2. y es prefijo de t, (t=yz)
3. |y| es máximo cumpliendo 1. y 2.
Ov(s,t)=y
 ov(s,t)= |Ov(s,t)|,

Cómo construir el autómata para
un patrón



Dado un patrón p=p1. . .pm definimos el string
matching autómata Mp con estados
Q={0,1,…,m}, estado inicial q0=0, un único
estado final m (F={m}) y la transición
(i,a) = ov(p1. . .pia, p)
para cada símbolo a y estado i
(i,a) = ov(p1. . .pia, p)=“(la longitud d)el prefijo
más largo de p que es sufijo de p1. . .pia”
Si estoy en el estado i, lo que llevo leído del
texto termina en p1. . .pi
Por qué funciona …
Se puede probar por inducción:
 Si empiezo en el estado inicial 0 y leo
t1…tk llego al estado i que cumple:
 p 1.
. .pi = ov(t1…tk, p)
 p1. . .pi es “el prefijo más largo de p que es
sufijo de t1…tk”
Por qué funciona …

Si empiezo en el estado inicial 0 y leo t1…tk llego
al estado i que cumple:
 p1.
. .pi es “el prefijo más largo de p que es sufijo de
t1…tk”

Luego hay una ocurrencia de p en posición km+1 si p= p1. . .pm es sufijo de t1…tk, es decir,
 Si
empiezo en el estado inicial 0 y leo t1…tk llego al
estado m
Algoritmo para construir el
autómata
String matching con autómata
Complejidad
Construir el autómata: O(||.m2)
 String matching: O(n)


Se puede construir el autómata en tiempo
O(||.m)
Enunciado del problema …
Entrada: Dos strings t= t1 … tn, p= p1 … pm
sobre 
 Salida: El conjunto de posiciones de t
donde aparece p, es decir, I  {1,…,
n-m+1} tales que i I sii ti … ti+m-1 =p

Vistos
Algoritmo inocente: O(m.(n-m))
 String matching autómata:

 O(||.m)
preprocessing of pattern
 O(n) string matching
Algoritmo de Boyer-Moore
Se trata de utilizar el algoritmo “inocente”:
ir moviendo patrón sobre el texto
 Pero …

 Cada
comparación de p1…pm con tj+1…tj+m la
hacemos empezando por el final
 Si podemos movemos más de una posición la
j

Usa preprocesamiento de p
Ejemplo del inocente …
Para mover más de una posición
1.
Regla del carácter malo:

Si estoy comparando p1…pm con tj+1…tj+m
empezando por pm con tj+m, si encuentro pi
distinto de tj+i,

Muevo el p hacia la derecha hasta la última vez
que aparece el símbolo tj+i en p (es decir, la
primera vez por la derecha)
Regla del carácter malo
Preprocesamiento para la regla del
carácter malo
(a)= última ocurrencia de a en p
Preprocesamiento para la regla del
carácter malo

Si estoy comparando p1…pm con tj+1…tj+m
empezando por pm con tj+m, si encuentro pi
distinto de tj+i=a, muevo el patrón i-(a)
posiciones a la dcha del texto

Coste del preprocesamiento O(m+||)
Para mover más de una posición
2.
Regla del buen sufijo:

Si estoy comparando p1…pm con tj+1…tj+m
empezando por pm con tj+m, si encuentro pi-1
distinto de tj+i-1,

Muevo el p hacia la derecha hasta la siguiente
ocurrencia de pi…pm en p
Regla del buen sufijo
Para mover más de una posición
2.
Regla del buen sufijo PLUS:

Si estoy comparando p1…pm con tj+1…tj+m
empezando por pm con tj+m, si encuentro pi-1
distinto de tj+i-1,



Muevo el p hacia la derecha hasta la siguiente
ocurrencia de pi…pm en p
Si no aparece muevo al mayor k tal que p1…pk
es sufijo de pi…pm
(i) es dónde colocar pm
Regla del buen sufijo PLUS
Cómo calcular …

La siguiente ocurrencia de pi…pm en p
(Muevo el p hacia la derecha hasta la siguiente
ocurrencia de pi…pm en p)


Es como la segunda ocurrencia de (pi…pm)R en
pR
Es como la primera ocurrencia de
(pi…pm)R=pm…pi en (p1…pm-1)R=pm-1…p1
Para calcular …
La primera ocurrencia de pm…pi en
pm-1…p1
 uso el autómata string matching con
patrón pm…pi
 Es como el de patrón pm…p2 pero con
estado final distinto (estado final m-i+1)

Además (regla del buen sufijo PLUS)

Si no aparece (la siguiente ocurrencia de pi…pm en p)
muevo al mayor k tal que p1…pk es sufijo de pi…pm

El último estado de buscar pm…p2 en pm-1…p1 nos dice:
Si hemos llegado al estado m-j+1, eso quiere decir que


pm…pj es sufijo de pm-1…p1
 pm…pj-1 NO es sufijo de pm-1…p1

j es el menor tal que pj…pm es prefijo de p1…pm-1

k=m-j+1 es el mayor tal que p1…pk es sufijo de p2…pm
Para i<=j, k=m-j+1 es el mayor tal que p1…pk es sufijo
de pi…pm

Complejidad buen sufijo
Podemos hacer todo el preprocesamiento
con el string matching autómata para
pm…p2 usándolo una sola vez con entrada
pm-1…p1
 Coste de calcular el autómata: O(||.m)
 Usarlo con entrada pm-1…p1 : O(m)

Complejidad de Boyer-Moore
Preprocesamiento O(||.m)
 Caso peor: igual que el inocente
O(||.m+n.m)
 Bastante rápido en la práctica
 Se puede mejorar el preproceso para que
el caso peor sea O(n+m)

Comparando complejidades
Caso peor …
 Algoritmo inocente O(m.(n-m))
 String matching automata O(n+||.m2),
O(n+||.m)
 Boyer-Moore O(||.m+n.m), O(n+m+||)
El caso peor del Boyer-Moore ocurre poco
Alternativa: el Knuth-Morris-Pratt (mejor en el caso
peor, peor en la práctica)
Separando el preprocesamiento …
Algoritmo inocente: O(m.(n-m))
 String matching autómata:

 O(||.m)
preprocesamiento del patrón
 O(n) string matching

Boyer-Moore
 O(||.m)
preprocesamiento del patrón ,
mejorado O(||+m)
 O(n.m) string matching, mejorado O(n)
El próximo día …

El problema de string matching:
 String
matching automata
 Boyer-Moore
 Árboles de sufijos (con otras aplicaciones)
 Vectores de sufijos
Documentos relacionados
Descargar