Maior subsequência comum

O problema da maior subsequência comum(LCS) é sobre achar a maior subsequência em todas as sequências em um conjunto de sequências(normalmente duas). O problema da maior subsequência comum é um clássico da ciência da computação, é a base de programas de comparação de dados como o diff, e tem aplicações em computação linguística e bioinformática. Também é amplamente usado em sistemas de versionamento como Git para mesclar múltiplas mudanças feitas em arquivos.

Por exemplo, considere as sequências e . Ambos têm 5 subsequências comuns de tamanho 2: , , e ; e 2 subsequências comuns de tamanho 3: e . Então e são as maiores subsequências comuns.

Complexidade editar

Para os casos gerais de um número arbitrário de sequências, o problema é NP-difícil(veja complexidade de tempo)[1]. E quando o número de sequências é constante, pode ser resolvido em tempo polinomial com uso da programação dinâmica.

Dado   sequências de tamanho  , uma pesquisa pode testar cada uma das   subsequências da primeira sequência para determinar se é também subsequência das sequências restantes; cada subsequência pode ser testada em tempo linear nos tamanhos das sequências, então o tempo para isso seria:

 

Para o caso das 2 sequências de   e   elementos, o tempo de processamento usando a programação dinâmica seria  . Para um número arbitrário de sequências, a programação dinâmica nos daria a solução em

 

Existem métodos com menor complexidade[2], que geralmente necessitam do tamanho do LCS, ou tamanho do alfabeto quando não ambos.

O LCS não é necessariamente exclusivo; no pior caso, o número de subsequências comuns é exponencial nos tamanhos das sequências, então a complexidade deve ser pelo menos exponencial.

Solução para duas sequências editar

O problema LCS tem uma estrutura ideal: o problema pode ser quebrado em partes menores; problemas mais simples, que podem ser quebrados em menores; e então, a solução se torna trivial. O LCS em particular permite que soluções complexas possam ser quebradas em soluções mais simples e reutilizáveis. Problemas com essas características podem ser abordados com a programação dinâmica, em que as soluções para problemas menores podem ser memorizadas e reutilizadas

Prefixos editar

O prefixo   de   é definido como os   primeiros caracteres de  [3]. Por exemplo, os prefixos de   são:

 

 

 

 

 

Considere que   seja uma função que compute a maior subsequência comum de   e  . Esta função tem duas propriedades muito interessantes.

Primeira propriedade editar

 , para todas as strings  ,   e todos os símbolos  , onde '^' representa a concatenação de strings. Isso permite simplificar o processo de LCS para as duas sequências que terminam com o mesmo símbolo. Por exemplo, LCS("BANANA","ATANA") = LCS("BANAN","ATAN")^A, continuam com o mesmo símbolo comum, LCS("BANANA","ATANA") = LCS("BAN","AT")^"ANA".

Segunda propriedade editar

Se   e   são símbolos distintos ( ), então   é uma das strings de tamanho máximo no conjunto  , para todas as strings  ,  .

Por exemplo, LCS ("ABCDEFG", "BCDGK") é a sequência mais longa de <mathLCS ("ABCDEFG", "BCDG") e LCS ("ABCDEF", "BCDGK"); se ambos tivessem o mesmo comprimento, um deles poderia ser escolhido arbitrariamente.

Para prosseguir, diferencie os dois casos:

Se LCS ("ABCDEFG", "BCDGK") termina com um "G", então o "K" final não pode estar no LCS, portanto LCS ("ABCDEFG", "BCDGK") = LCS ("ABCDEFG", "BCDG ").

Se LCS ("ABCDEFG", "BCDGK") não terminar com um "G", então o "G" final não pode estar no LCS, portanto, LCS ("ABCDEFG", "BCDGK") = LCS ("ABCDEF", "BCDGK").

Definição da função editar

Considere duas sequências definidas da seguinte forma:   e  . Os prefixos de   são  ; os prefixos de   são  . Considere que   represente o conjunto das maiores subsequências comuns dos prefixos   e  . Esse conjunto de subsequências é dado por:

 

Para achar o LCS de   e  , compare   e  . Se forem iguais, então a sequência   é estendida pelo elemento  . Se não forem iguais, então a mais longa das duas sequências,   e   é retida. (Se forem do mesmo tamanho mas não idênticas, ambas serão retidas)

  1. David Maier (1978). «The Complexity of Some Problems on Subsequences and Supersequences». ACM Press. J. ACM. 25 (2): 322–336. doi:10.1145/322063.322075 
  2. L. Bergroth and H. Hakonen and T. Raita (2000). «A Survey of Longest Common Subsequence Algorithms». IEEE Computer Society. SPIRE. 00: 39–48. ISBN 0-7695-0746-8. doi:10.1109/SPIRE.2000.878178 
  3. Xia, Xuhua (2007). Bioinformatics and the Cell: Modern Computational Approaches in Genomics, Proteomics and Transcriptomics. New York: Springer. p. 24. ISBN 978-0-387-71336-6