Saltar para o conteúdo

Maior subsequência comum

Origem: Wikipédia, a enciclopédia livre.

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 | editar código-fonte]

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 | editar código-fonte]

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 | editar código-fonte]

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 | editar código-fonte]

, 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 | editar código-fonte]

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 | editar código-fonte]

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