+ All Categories
Home > Documents > Bioinformática Aplicada - azevedolab.net · Algoritmos de Aprendizado de Máquina (Machine...

Bioinformática Aplicada - azevedolab.net · Algoritmos de Aprendizado de Máquina (Machine...

Date post: 13-Dec-2018
Category:
Upload: trankiet
View: 217 times
Download: 0 times
Share this document with a friend
122
© 2017 Dr. Walter F. de Azevedo Jr. 000000000000000000000000000000000000000 000000000000000000000000000000000000000 000000000000111111111110001100000000000 000000000001111111111111111111000000001 000000000111111111111111111111111000000 000000000111111111111111111111111000000 000000000011111111111111111111100000000 000000001111111111111111111111111000000 000011111111111111111111111111111000000 001111111111111111111111111111110000000 111111111111111111111111111110000000000 111111111111111111111111111110000000000 000011111111111111111111111111111110000 001111111111111111111111111111111111000 011111111111111111111111111111111111000 001111111111111111111111111111111111100 000000011111111111111111111111111111110 000000001111111111111111111111111111110 000000000001111111111111111111111111110 000000000000011111111111111111111111110 000000000000000111111111111111111111000 000000000000000000000000001111000000000 000000000000000000000000000000000000000 000000000000000000000000000000000000000 000000000000000000000000000000000000000 www.python.org 1
Transcript

© 2

01

7 D

r. W

alter

F.

de

Aze

ve

do

Jr.

000000000000000000000000000000000000000 000000000000000000000000000000000000000 000000000000111111111110001100000000000 000000000001111111111111111111000000001 000000000111111111111111111111111000000 000000000111111111111111111111111000000 000000000011111111111111111111100000000 000000001111111111111111111111111000000 000011111111111111111111111111111000000 001111111111111111111111111111110000000 111111111111111111111111111110000000000 111111111111111111111111111110000000000 000011111111111111111111111111111110000 001111111111111111111111111111111111000 011111111111111111111111111111111111000 001111111111111111111111111111111111100 000000011111111111111111111111111111110 000000001111111111111111111111111111110 000000000001111111111111111111111111110 000000000000011111111111111111111111110 000000000000000111111111111111111111000 000000000000000000000000001111000000000 000000000000000000000000000000000000000 000000000000000000000000000000000000000 000000000000000000000000000000000000000

www.python.org

1

Consideremos um algoritmo que tem um tempo de execução t dado t = 5n2 +12n+18

(linha azul do gráfico abaixo), onde n é o tamanho da entrada. Dizemos que este

algoritmo tem um tempo de execução de ordem quadrática, ou O(n2) pois este é o

termo de mais alto grau do polinômio.

De uma forma geral, podemos determinar uma constante c para o qual a desigualdade

5n2 +12n+18 c.n2 se verifica, assim o tempo de execução é uma função quadrática.

Quando usamos essa aproximação, estamos usando a notação Big-O.

Notação Big-O

www.python.org

t(s)

n

t = 5n2 +12n+18

t = 35n2

2

O desenvolvimento de algoritmos para Bioinformática teve um grande crescimento nos

últimos anos. Iremos descrever as ideias centrais das técnicas mais usadas na

pesquisa científica em Bioinformática.

Busca Exaustiva

“Branch-and-Bound”

“Greedy”

Aprendizado de Máquina

Algoritmos Randomizados

Dividir e Conquistar

Programação Dinâmica

Algoritmos para Bioinformática

www.python.org

3

Para ilustrar os conceitos atrás das técnicas de desenho de algoritmos, vamos

considerar um problema hipotético de procurarmos um telefone sem fio em casa. Para

complicar a situação estamos com as duas mãos ocupadas e está escuro, de forma

que não podemos confiar na visão, como indicado abaixo (Jones & Pevzner, 2004).

Fonte: Jones, N. C. & Pevzner, P. A. An Introduction to

Bioinformatics Algorithms. The MIT Press,Cambridge, 2004.

Algoritmos para Bioinformática

www.python.org

4

O algoritmo de busca exaustiva, ou força bruta, testa todas as alternativas do

problema, para encontrar uma solução particular. No exemplo do telefone, ignoramos

o som do toque do telefone, e, assim, simplesmente procuramos por cada cm2 da

casa, até acharmos o telefone. Os algoritmos que seguem este desenho, são fáceis

de entender, mas tem como principal problema o tempo de execução. Outra

característica que podemos destacar, é como iremos dividir a casa para procurar o

telefone, um parâmetro comumente considerado em algoritmos de busca. Por

exemplo, se procurarmos em quadrados de 10 cm de lado teremos um tempo, e

usarmos um quadrado de 1 cm de lado, teremos um tempo bem maior.

Algoritmo de Busca Exaustiva (ou Força Bruta)

www.python.org

Fonte: Jones, N. C. & Pevzner, P. A. An Introduction to

Bioinformatics Algorithms. The MIT Press,Cambridge, 2004. 5

Nesta classe de algoritmo, ao iniciarmos o algoritmo de foça bruta, podemos omitir

certas alternativas, diminuindo o tempo da busca. No exemplo do telefone, considere

que ao chegarmos no segundo andar da casa escutamos a campainha do telefone

como vinda do andar de cima. Nesta situação, podemos ignorar o andar inferior.

Algoritmo do Tipo “Branch-and-Bound”

www.python.org

Fonte: Jones, N. C. & Pevzner, P. A. An Introduction to

Bioinformatics Algorithms. The MIT Press,Cambridge, 2004. 6

Muitos algoritmos são iterativos, os algoritmos do tipo “greedy’ consideram em cada

iteração a alternativa mais promissora. Tomando-se o exemplo do telefone, podemos

considerar que nos movimentaremos na direção de onde vem o som do telefone. Isto

pode causar alguns problemas, como ilustrado abaixo, mas é uma forma de

reduzirmos as alternativas testadas. Em cada aplicação temos que identificar como

determinar a solução mais atrativa.

Algoritmo do Tipo “Greedy”

www.python.org

Fonte: Jones, N. C. & Pevzner, P. A. An Introduction to

Bioinformatics Algorithms. The MIT Press,Cambridge, 2004. 7

Algoritmos de Aprendizado de Máquina (Machine Learning) usam o comportamento

prévio do sistema para a decidir como varrer as alternativas. No exemplo do telefone,

temos da experiência prévia que em 85 % da vezes o telefone estava sobre o sofá da

sala, em 5 % das vezes no quarto do casal, em 4 % das vezes na cozinha, e em 6 %

em outros locais. Assim, podemos começar procurando no sofá da sala e seguimos a

ordem indicada.

Algoritmo com Aprendizado de Máquina

www.python.org

Fonte: Jones, N. C. & Pevzner, P. A. An Introduction to

Bioinformatics Algorithms. The MIT Press,Cambridge, 2004.

85 %

5 % 4 %

8

No algoritmo estocástico, a faixa de alternativas a serem testadas é escolhida de

forma aleatória. Assim, no exemplo do telefone, consideremos que temos uma casa

com seis cômodos, podemos atribuir números de 1 a 6 aos cômodos e jogar um dado

para escolher que cômodo começar. Podemos também pensar que jogamos uma

moeda e decidimos se começamos com os cômodos da parte superior ou da inferior.

Em todo caso, temos um componente aleatório na decisão.

Algoritmo Estocástico

www.python.org

Fonte: Jones, N. C. & Pevzner, P. A. An Introduction to

Bioinformatics Algorithms. The MIT Press,Cambridge, 2004. 9

A ideia atrás desta classe e dividir um problema maior em subproblemas,

independentes. Depois os subproblemas são resolvidos e combinados de forma a

obtermos a solução do problema original. O ponto crítico nesta classe de algoritmos é

como combinar as soluções dos subproblemas para obtermos a solução do problema

principal.

Algoritmo do Tipo Dividir e Conquistar

www.python.org

Fonte: Jones, N. C. & Pevzner, P. A. An Introduction to

Bioinformatics Algorithms. The MIT Press,Cambridge, 2004. 10

O algoritmo de programação dinâmica tem uma abordagem mais refinada do algoritmo

de dividir em conquistar. Ao dividir o problema, em subproblemas menores, o algoritmo

evita repetir computações já realizadas, usando valores armazenados de iterações

anteriores. Vamos dar como exemplo o jogo das pedras.

No jogo das Pedras consideramos dois jogadores e duas pilhas de pedras. Cada

jogador pode tirar uma pedra da pilha 1, ou uma pedra do pilha 2, ou duas pedras,

sendo uma de cada pilha. Os jogadores não podem tirar duas pedras da mesma pilha.

Vence o jogador que tirar a última pedra. Vamos montar um gráfico que ilustra o mapa

de como ganhar o jogo. Para exemplificar, vamos considerar que temos duas pilhas de

10 pedras cada.

Algoritmo do Programação Dinâmica

www.python.org

11

O “W” considera a situação ganhadora e “L” a perdedora. A situação é ganhadora

quando há pelo menos um movimento que leva você a vencer. Montaremos um mapa

bidimensional considerando todas as situações para duas pilhas de 10 pedras.

0 1 2 3 4 5 6 7 8 9 10

0 W

1 W W

2

3

4

5

6

7

8

9

10

Pilha B

Pilha A

Jogo das Pedras

www.python.org

12

Inicialmente consideremos um jogo com uma pedra na pilha A e zero pedras na pilha

B, como indicado no mapa abaixo, ou seja, um jogo J1,0, usando-se a notação

matricial. Esta é uma situação vencedora, visto que ao tirar a pedra o jogador vence.

0 1 2 3 4 5 6 7 8 9 10

0

1 W

2

3

4

5

6

7

8

9

10

Pilha B

Pilha A

J1,0

Jogo das Pedras

www.python.org

13

O mesmo é verdadeiro para um jogo J0,1, que indica uma pedra na pilha B.

0 1 2 3 4 5 6 7 8 9 10

0 W

1 W

2

3

4

5

6

7

8

9

10

Pilha B

Pilha A

Jogo das Pedras

www.python.org

14

Quando o jogador encontra-se na situação J1,1, ele está numa situação vencedora,

visto que ele pode tirar uma pedra de cada pilha.

0 1 2 3 4 5 6 7 8 9 10

0 W

1 W W

2

3

4

5

6

7

8

9

10

Pilha B

Pilha A

Jogo das Pedras

www.python.org

15

No jogo J2,0 temos uma situação perdedora, pois só podemos tirar uma pedra da pilha

A, o que leva a situação do jogo J1,0, que é vitoriosa para o adversário.

0 1 2 3 4 5 6 7 8 9 10

0 W

1 W W

2 L

3

4

5

6

7

8

9

10

Pilha B

Pilha A

Jogo das Pedras

www.python.org

16

O mesmo é verdadeiro para no jogo J0,2. Observe que o jogo é simétrico, o que vale

para Ji,j é mantido para Jj,i.

0 1 2 3 4 5 6 7 8 9 10

0 W L

1 W W

2 L

3

4

5

6

7

8

9

10

Pilha B

Pilha A

Jogo das Pedras

www.python.org

17

No jogo J1,2 temos uma situação de vitória, pois podemos escolher tirar uma pedra da

pilha A, o que leva o adversário a um jogo J0,2, onde ele perde.

0 1 2 3 4 5 6 7 8 9 10

0 W L

1 W W W

2 L

3

4

5

6

7

8

9

10

Pilha B

Pilha A

Jogo das Pedras

www.python.org

18

Por simetria.

0 1 2 3 4 5 6 7 8 9 10

0 W L

1 W W W

2 L W

3

4

5

6

7

8

9

10

Pilha B

Pilha A

Jogo das Pedras

www.python.org

19

No jogo J2,2 não importa o movimento, o adversário ganha, então temos uma situação

perdedora. Aplicando-se o mesmo raciocínio podemos preencher o mapa.

0 1 2 3 4 5 6 7 8 9 10

0 W L

1 W W W

2 L W L

3

4

5

6

7

8

9

10

Pilha B

Pilha A

Jogo das Pedras

www.python.org

20

0 1 2 3 4 5 6 7 8 9 10

0 W L

1 W W W

2 L W L

3 W

4

5

6

7

8

9

10

Pilha B

Pilha A

Jogo das Pedras

www.python.org

21

0 1 2 3 4 5 6 7 8 9 10

0 W L W

1 W W W

2 L W L

3 W

4

5

6

7

8

9

10

Pilha B

Pilha A

Jogo das Pedras

www.python.org

22

0 1 2 3 4 5 6 7 8 9 10

0 W L W

1 W W W

2 L W L

3 W W

4

5

6

7

8

9

10

Pilha B

Pilha A

Jogo das Pedras

www.python.org

23

0 1 2 3 4 5 6 7 8 9 10

0 W L W

1 W W W W

2 L W L

3 W W

4

5

6

7

8

9

10

Pilha B

Pilha A

Jogo das Pedras

www.python.org

24

0 1 2 3 4 5 6 7 8 9 10

0 W L W

1 W W W W

2 L W L

3 W W W

4

5

6

7

8

9

10

Pilha B

Pilha A

Jogo das Pedras

www.python.org

25

0 1 2 3 4 5 6 7 8 9 10

0 W L W

1 W W W W

2 L W L W

3 W W W

4

5

6

7

8

9

10

Pilha B

Pilha A

Jogo das Pedras

www.python.org

26

0 1 2 3 4 5 6 7 8 9 10

0 W L W

1 W W W W

2 L W L W

3 W W W W

4

5

6

7

8

9

10

Pilha B

Pilha A

Jogo das Pedras

www.python.org

27

0 1 2 3 4 5 6 7 8 9 10

0 W L W

1 W W W W

2 L W L W

3 W W W W

4 L

5

6

7

8

9

10

Pilha B

Pilha A

Jogo das Pedras

www.python.org

28

0 1 2 3 4 5 6 7 8 9 10

0 W L W L

1 W W W W

2 L W L W

3 W W W W

4 L

5

6

7

8

9

10

Pilha B

Pilha A

Jogo das Pedras

www.python.org

29

0 1 2 3 4 5 6 7 8 9 10

0 W L W L

1 W W W W

2 L W L W

3 W W W W

4 L W

5

6

7

8

9

10

Pilha B

Pilha A

Jogo das Pedras

www.python.org

30

0 1 2 3 4 5 6 7 8 9 10

0 W L W L

1 W W W W W

2 L W L W

3 W W W W

4 L W

5

6

7

8

9

10

Pilha B

Pilha A

Jogo das Pedras

www.python.org

31

0 1 2 3 4 5 6 7 8 9 10

0 W L W L

1 W W W W W

2 L W L W

3 W W W W

4 L W L

5

6

7

8

9

10

Pilha B

Pilha A

Jogo das Pedras

www.python.org

32

0 1 2 3 4 5 6 7 8 9 10

0 W L W L

1 W W W W W

2 L W L W L

3 W W W W

4 L W L

5

6

7

8

9

10

Pilha B

Pilha A

Jogo das Pedras

www.python.org

33

0 1 2 3 4 5 6 7 8 9 10

0 W L W L

1 W W W W W

2 L W L W L

3 W W W W

4 L W L W

5

6

7

8

9

10

Pilha B

Pilha A

Jogo das Pedras

www.python.org

34

0 1 2 3 4 5 6 7 8 9 10

0 W L W L

1 W W W W W

2 L W L W L

3 W W W W W

4 L W L W

5

6

7

8

9

10

Pilha B

Pilha A

Jogo das Pedras

www.python.org

35

0 1 2 3 4 5 6 7 8 9 10

0 W L W L

1 W W W W W

2 L W L W L

3 W W W W W

4 L W L W L

5

6

7

8

9

10

Pilha B

Pilha A

Jogo das Pedras

www.python.org

36

Abaixo temos a tabela completa.

0 1 2 3 4 5 6 7 8 9 10

0 W L W L W L W L W L

1 W W W W W W W W W W W

2 L W L W L W L W L W L

3 W W W W W W W W W W W

4 L W L W L W L W L W L

5 W W W W W W W W W W W

6 L W L W L W L W L W L

7 W W W W W W W W W W W

8 L W L W L W L W L W L

9 W W W W W W W W W W W

10 L W L W L W L W L W L

Pilha B

Pilha A

Jogo das Pedras

www.python.org

37

Completamos com o jogo J0,0 como uma situação hipotética de derrota.

0 1 2 3 4 5 6 7 8 9 10

0 L W L W L W L W L W L

1 W W W W W W W W W W W

2 L W L W L W L W L W L

3 W W W W W W W W W W W

4 L W L W L W L W L W L

5 W W W W W W W W W W W

6 L W L W L W L W L W L

7 W W W W W W W W W W W

8 L W L W L W L W L W L

9 W W W W W W W W W W W

10 L W L W L W L W L W L

Pilha B

Pilha A

Jogo das Pedras

www.python.org

38

A implementação da tabela abaixo identifica se dada uma posição de início, o jogador

ganha ou perde.

0 1 2 3 4 5 6 7 8 9 10

0 L W L W L W L W L W L

1 W W W W W W W W W W W

2 L W L W L W L W L W L

3 W W W W W W W W W W W

4 L W L W L W L W L W L

5 W W W W W W W W W W W

6 L W L W L W L W L W L

7 W W W W W W W W W W W

8 L W L W L W L W L W L

9 W W W W W W W W W W W

10 L W L W L W L W L W L

Pilha B

Pilha A

Jogo das Pedras

www.python.org

39

Chamaremos este algoritmo, de programação dinâmica, de Rocks(n,m), ele retorna a

string “W” ou “L” e tem como entrada o números de pedras em cada pilha.

0 1 2 3 4 5 6 7 8 9 10

0 L W L W L W L W L W L

1 W W W W W W W W W W W

2 L W L W L W L W L W L

3 W W W W W W W W W W W

4 L W L W L W L W L W L

5 W W W W W W W W W W W

6 L W L W L W L W L W L

7 W W W W W W W W W W W

8 L W L W L W L W L W L

9 W W W W W W W W W W W

10 L W L W L W L W L W L

Pilha B

Pilha A

Jogo das Pedras

www.python.org

40

Rocks(n,m)

J0,0 = “L”

Para i de 1 até n

Se Ji-1,0 == “W”

Ji,0 = “L”

Senão

Ji,0 = “W”

Para j de 1 até m

Se J0, j-1 == “W”

J0,j = “L”

Senão

J0,j = “W”

Para i de 1 até n

Para j de 1 até m

Se Ji-1, j-1 == “W” e Ji, j-1 == “W” e Ji-1, j == “W”

Ji,j = “L”

Senão

J0,j = “W”

Retorna Jn,m

Segue o pseudocódigo de Rocks(n,m).

Algoritmo do Programação Dinâmica (Rocks)

www.python.org

41

Se olharmos com atenção para a tabela veremos um padrão que facilita a

programação. Veja que, quando i e j são pares, temos “L”. Nos outros casos temos

“W”.

0 1 2 3 4 5 6 7 8 9 10

0 L W L W L W L W L W L

1 W W W W W W W W W W W

2 L W L W L W L W L W L

3 W W W W W W W W W W W

4 L W L W L W L W L W L

5 W W W W W W W W W W W

6 L W L W L W L W L W L

7 W W W W W W W W W W W

8 L W L W L W L W L W L

9 W W W W W W W W W W W

10 L W L W L W L W L W L

Pilha B

Pilha A

Algoritmo do Programação Dinâmica (FastRocks)

www.python.org

42

FastRocks(n,m)

Se n e m são ambos pares

retorna “L”

Senão

retorna “W”

Segue o pseudocódigo de FastRocks(n,m).

Algoritmo do Programação Dinâmica (FastRocks)

www.python.org

43

O algoritmo de Needleman & Wunsch (Needleman and Wunsch, 1970) tem como foco

o alinhamento global de sequências de DNA e proteínas. Com a explosão dos dados

genômicos no final do século passado, um problema central nos estudos genômicos

foi o alinhamento de sequências. Esses alinhamentos permitem inferir similaridade

sequencial e relacionar com as aspectos biológicos, como evolução, função,

conservação de estrutura tridimensional entre outros. O algoritmo de Needleman &

Wunsch será descrito aqui como modelo para entendermos as principais

características computacionais do alinhamento de sequências.

Algoritmo de Needleman & Wunsch

www.python.org

Referência:

Needleman, S. B. & Wunsch, C. D. (1970) "A General Method Applicable to the Search for Similarities in the

Amino Acid Sequence of Two Proteins," J. Mol. Biol., 48, 443-453.

44

Considerando-se os tipos de algoritmos vistos até o momento, temos que o algoritmo

de Needleman & Wunsch é de programação dinâmica.

O algoritmo de Needleman & Wunsch é dividido nas seguintes etapas:

1) Inicialização da matriz caminho;

2) Preenchimento da matriz caminho;

3) Alinhamento.

Para ilustrar o funcionamento do algoritmo, vamos considerar o alinhamento de duas

sequências:

GAATTCAGTTA (sequência #1) (temos m bases na sequência)

GGATCGA (sequência #2) (temos n bases na sequência)

Algoritmo de Needleman & Wunsch

www.python.org

45

Na fase de inicialização do algoritmo, montamos uma matriz m x n, como indicado

abaixo. Essa matriz é chamada matriz caminho (path matrix). Na matriz caminho, às

primeiras coluna e linha atribuímos zero, visto que estamos considerando um

alinhamento sem penalidade de gap inicial.

Algoritmo de Needleman & Wunsch (Inicialização)

www.python.org

0 G A A T T C A G T T A

0 0 0 0 0 0 0 0 0 0 0 0 0

G 0

G 0

A 0

T 0

C 0

G 0

A 0

Sequência #2

Sequência #1

0

1

2

3

4

5

6

7

0 1 2 3 4 5 6 7 8 9 10 11

46

Para o preenchimento da matriz, consideramos o início a partir da esquerda superior

da matriz. Para cada elemento Mi,j da matriz, determinaremos a seguinte função

escore:

Mi,j = MAXIMUM[

Mi-1, j-1 + Si,j (coincidência ou não na diagonal da matriz),

Mi,j-1 + w (gap na sequência #1),

Mi-1,j + w (gap na sequência #2)]

Onde w é o peso para inserção de um gap (intervalo), consideramos w = 0.

Si,j = 1 se a base na posição i da sequência #1 é a mesma da posição j na sequência #

2 (escore de coincidência), caso contrário,

Si,j = 0 (escore para não coincidência)

Algoritmo de Needleman & Wunsch (Preenchimento)

www.python.org

47

Aplicando-se o critério temos: M1,1 = MAXIMUM[

M0, 0 + S1,1 (coincidência ou não na diagonal da matriz),

M1,0 + w (gap na sequência #1),

M0,1 + w (gap na sequência #2)] = MAXIMUM[1,0,0], ou seja, M1,1 = 1

Algoritmo de Needleman & Wunsch (Preenchimento)

www.python.org

Sequência #2

0 G A A T T C A G T T A

0 0 0 0 0 0 0 0 0 0 0 0 0

G 0 1

G 0

A 0

T 0

C 0

G 0

A 0

Sequência #1

0

1

2

3

4

5

6

7

0 1 2 3 4 5 6 7 8 9 10 11

48

Aplicando-se o critério temos: M2,1 = MAXIMUM[

M1, 0 + S2,1 (coincidência ou não na diagonal da matriz),

M2,0 + w (gap na sequência #1),

M1,1 + w (gap na sequência #2)] = MAXIMUM[1,0,1], ou seja, M2,1 = 1

Algoritmo de Needleman & Wunsch (Preenchimento)

www.python.org

0 G A A T T C A G T T A

0 0 0 0 0 0 0 0 0 0 0 0 0

G 0 1

G 0 1

A 0

T 0

C 0

G 0

A 0

Sequência #1

0

1

2

3

4

5

6

7

Sequência #2

0 1 2 3 4 5 6 7 8 9 10 11

49

Aplicando-se o critério temos: M3,1 = MAXIMUM[

M2, 0 + S3,1 (coincidência ou não na diagonal da matriz),

M3,0 + w (gap na sequência #1),

M2,1 + w (gap na sequência #2)] = MAXIMUM[0,0,1], ou seja, M3,1 = 1

Algoritmo de Needleman & Wunsch (Preenchimento)

www.python.org

0 G A A T T C A G T T A

0 0 0 0 0 0 0 0 0 0 0 0 0

G 0 1

G 0 1

A 0 1

T 0

C 0

G 0

A 0

Sequência #1

0

1

2

3

4

5

6

7

Sequência #2

0 1 2 3 4 5 6 7 8 9 10 11

50

Aplicando-se o critério temos: M4,1 = MAXIMUM[

M3, 0 + S4,1 (coincidência ou não na diagonal da matriz),

M4,0 + w (gap na sequência #1),

M3,1 + w (gap na sequência #2)] = MAXIMUM[0,0,1], ou seja, M4,1 = 1

Algoritmo de Needleman & Wunsch (Preenchimento)

www.python.org

0 G A A T T C A G T T A

0 0 0 0 0 0 0 0 0 0 0 0 0

G 0 1

G 0 1

A 0 1

T 0 1

C 0

G 0

A 0

Sequência #1

0

1

2

3

4

5

6

7

Sequência #2

0 1 2 3 4 5 6 7 8 9 10 11

51

Aplicando-se o critério temos: M5,1 = MAXIMUM[

M4, 0 + S5,1 (coincidência ou não na diagonal da matriz),

M5,0 + w (gap na sequência #1),

M4,1 + w (gap na sequência #2)] = MAXIMUM[0,0,1], ou seja, M5,1 = 1

Algoritmo de Needleman & Wunsch (Preenchimento)

www.python.org

0 G A A T T C A G T T A

0 0 0 0 0 0 0 0 0 0 0 0 0

G 0 1

G 0 1

A 0 1

T 0 1

C 0 1

G 0

A 0

Sequência #1

0

1

2

3

4

5

6

7

Sequência #2

0 1 2 3 4 5 6 7 8 9 10 11

52

Aplicando-se o critério temos: M6,1 = MAXIMUM[

M5, 0 + S6,1 (coincidência ou não na diagonal da matriz),

M6,0 + w (gap na sequência #1),

M5,1 + w (gap na sequência #2)] = MAXIMUM[1,0,1], ou seja, M6,1 = 1

Algoritmo de Needleman & Wunsch (Preenchimento)

www.python.org

0 G A A T T C A G T T A

0 0 0 0 0 0 0 0 0 0 0 0 0

G 0 1

G 0 1

A 0 1

T 0 1

C 0 1

G 0 1

A 0

Sequência #1

0

1

2

3

4

5

6

7

Sequência #2

0 1 2 3 4 5 6 7 8 9 10 11

53

Aplicando-se o critério temos: M7,1 = MAXIMUM[

M6, 0 + S7,1 (coincidência ou não na diagonal da matriz),

M7,0 + w (gap na sequência #1),

M6,1 + w (gap na sequência #2)] = MAXIMUM[0,0,1], ou seja, M7,1 = 1

Algoritmo de Needleman & Wunsch (Preenchimento)

www.python.org

0 G A A T T C A G T T A

0 0 0 0 0 0 0 0 0 0 0 0 0

G 0 1

G 0 1

A 0 1

T 0 1

C 0 1

G 0 1

A 0 1

Sequência #1

0

1

2

3

4

5

6

7

Sequência #2

0 1 2 3 4 5 6 7 8 9 10 11

54

Aplicando-se o critério temos: M1,2 = MAXIMUM[

M0, 1 + S1,2 (coincidência ou não na diagonal da matriz),

M1,1 + w (gap na sequência #1),

M0,2 + w (gap na sequência #2)] = MAXIMUM[0,1,0], ou seja, M1,2 = 1

Algoritmo de Needleman & Wunsch (Preenchimento)

www.python.org

0 G A A T T C A G T T A

0 0 0 0 0 0 0 0 0 0 0 0 0

G 0 1 1

G 0 1

A 0 1

T 0 1

C 0 1

G 0 1

A 0 1

Sequência #1

0

1

2

3

4

5

6

7

Sequência #2

0 1 2 3 4 5 6 7 8 9 10 11

55

Aplicando-se o critério temos: M1,3 = MAXIMUM[

M0, 2 + S1,3 (coincidência ou não na diagonal da matriz),

M1,2 + w (gap na sequência #1),

M0,3 + w (gap na sequência #2)] = MAXIMUM[0,1,0], ou seja, M1,3 = 1

Algoritmo de Needleman & Wunsch (Preenchimento)

www.python.org

0 G A A T T C A G T T A

0 0 0 0 0 0 0 0 0 0 0 0 0

G 0 1 1 1

G 0 1

A 0 1

T 0 1

C 0 1

G 0 1

A 0 1

Sequência #1

0

1

2

3

4

5

6

7

Sequência #2

0 1 2 3 4 5 6 7 8 9 10 11

56

Aplicando-se o critério temos: M1,4 = MAXIMUM[

M0, 3 + S1,4 (coincidência ou não na diagonal da matriz),

M1,3 + w (gap na sequência #1),

M0,4 + w (gap na sequência #2)] = MAXIMUM[0,1,0], ou seja, M1,4 = 1

Algoritmo de Needleman & Wunsch (Preenchimento)

www.python.org

0 G A A T T C A G T T A

0 0 0 0 0 0 0 0 0 0 0 0 0

G 0 1 1 1 1

G 0 1

A 0 1

T 0 1

C 0 1

G 0 1

A 0 1

Sequência #1

0

1

2

3

4

5

6

7

Sequência #2

0 1 2 3 4 5 6 7 8 9 10 11

57

Aplicando-se o critério temos: M1,5 = MAXIMUM[

M0, 4 + S1,5 (coincidência ou não na diagonal da matriz),

M1,4 + w (gap na sequência #1),

M0,5 + w (gap na sequência #2)] = MAXIMUM[0,1,0], ou seja, M1,5 = 1

Algoritmo de Needleman & Wunsch (Preenchimento)

www.python.org

0 G A A T T C A G T T A

0 0 0 0 0 0 0 0 0 0 0 0 0

G 0 1 1 1 1 1

G 0 1

A 0 1

T 0 1

C 0 1

G 0 1

A 0 1

Sequência #1

0

1

2

3

4

5

6

7

Sequência #2

0 1 2 3 4 5 6 7 8 9 10 11

58

Aplicando-se o critério temos: M1,6 = MAXIMUM[

M0, 5 + S1,6 (coincidência ou não na diagonal da matriz),

M1,5 + w (gap na sequência #1),

M0,6 + w (gap na sequência #2)] = MAXIMUM[0,1,0], ou seja, M1,6 = 1

Algoritmo de Needleman & Wunsch (Preenchimento)

www.python.org

0 G A A T T C A G T T A

0 0 0 0 0 0 0 0 0 0 0 0 0

G 0 1 1 1 1 1 1

G 0 1

A 0 1

T 0 1

C 0 1

G 0 1

A 0 1

Sequência #1

0

1

2

3

4

5

6

7

Sequência #2

0 1 2 3 4 5 6 7 8 9 10 11

59

Aplicando-se o critério temos: M1,7 = MAXIMUM[

M0, 6 + S1,7 (coincidência ou não na diagonal da matriz),

M1,6 + w (gap na sequência #1),

M0,7 + w (gap na sequência #2)] = MAXIMUM[0,1,0], ou seja, M1,7 = 1

Algoritmo de Needleman & Wunsch (Preenchimento)

www.python.org

0 G A A T T C A G T T A

0 0 0 0 0 0 0 0 0 0 0 0 0

G 0 1 1 1 1 1 1 1

G 0 1

A 0 1

T 0 1

C 0 1

G 0 1

A 0 1

Sequência #1

0

1

2

3

4

5

6

7

Sequência #2

0 1 2 3 4 5 6 7 8 9 10 11

60

Aplicando-se o critério temos: M1,8 = MAXIMUM[

M0, 7 + S1,8 (coincidência ou não na diagonal da matriz),

M1,7 + w (gap na sequência #1),

M0,8 + w (gap na sequência #2)] = MAXIMUM[1,1,0], ou seja, M1,8 = 1

Algoritmo de Needleman & Wunsch (Preenchimento)

www.python.org

0 G A A T T C A G T T A

0 0 0 0 0 0 0 0 0 0 0 0 0

G 0 1 1 1 1 1 1 1 1

G 0 1

A 0 1

T 0 1

C 0 1

G 0 1

A 0 1

Sequência #1

0

1

2

3

4

5

6

7

Sequência #2

0 1 2 3 4 5 6 7 8 9 10 11

61

Aplicando-se o critério temos: M1,9 = MAXIMUM[

M0, 8 + S1,9 (coincidência ou não na diagonal da matriz),

M1,8 + w (gap na sequência #1),

M0,9 + w (gap na sequência #2)] = MAXIMUM[0,1,0], ou seja, M1,9 = 1

Algoritmo de Needleman & Wunsch (Preenchimento)

www.python.org

0 G A A T T C A G T T A

0 0 0 0 0 0 0 0 0 0 0 0 0

G 0 1 1 1 1 1 1 1 1 1

G 0 1

A 0 1

T 0 1

C 0 1

G 0 1

A 0 1

Sequência #1

0

1

2

3

4

5

6

7

Sequência #2

0 1 2 3 4 5 6 7 8 9 10 11

62

Aplicando-se o critério temos: M1,10 = MAXIMUM[

M0, 9 + S1,10 (coincidência ou não na diagonal da matriz),

M1,9 + w (gap na sequência #1),

M0,10 + w (gap na sequência #2)] = MAXIMUM[0,1,0], ou seja, M1,10 = 1

Algoritmo de Needleman & Wunsch (Preenchimento)

www.python.org

0 G A A T T C A G T T A

0 0 0 0 0 0 0 0 0 0 0 0 0

G 0 1 1 1 1 1 1 1 1 1 1

G 0 1

A 0 1

T 0 1

C 0 1

G 0 1

A 0 1

Sequência #1

0

1

2

3

4

5

6

7

Sequência #2

0 1 2 3 4 5 6 7 8 9 10 11

63

Aplicando-se o critério temos: M1,11 = MAXIMUM[

M0, 10 + S1,11 (coincidência ou não na diagonal da matriz),

M1,10 + w (gap na sequência #1),

M0,11 + w (gap na sequência #2)] = MAXIMUM[0,1,0], ou seja, M1,11 = 1

Algoritmo de Needleman & Wunsch (Preenchimento)

www.python.org

0 G A A T T C A G T T A

0 0 0 0 0 0 0 0 0 0 0 0 0

G 0 1 1 1 1 1 1 1 1 1 1 1

G 0 1

A 0 1

T 0 1

C 0 1

G 0 1

A 0 1

Sequência #1

0

1

2

3

4

5

6

7

Sequência #2

0 1 2 3 4 5 6 7 8 9 10 11

64

Aplicando-se o critério temos: M2,2 = MAXIMUM[

M1, 1 + S2,2 (coincidência ou não na diagonal da matriz),

M2,1 + w (gap na sequência #1),

M1,2 + w (gap na sequência #2)] = MAXIMUM[1,1,1], ou seja, M2,2 = 1

Algoritmo de Needleman & Wunsch (Preenchimento)

www.python.org

0 G A A T T C A G T T A

0 0 0 0 0 0 0 0 0 0 0 0 0

G 0 1 1 1 1 1 1 1 1 1 1 1

G 0 1 1

A 0 1

T 0 1

C 0 1

G 0 1

A 0 1

Sequência #1

0

1

2

3

4

5

6

7

Sequência #2

0 1 2 3 4 5 6 7 8 9 10 11

65

Aplicando-se o critério temos: M3,2 = MAXIMUM[

M2, 1 + S3,2 (coincidência ou não na diagonal da matriz),

M3,1 + w (gap na sequência #1),

M2,2 + w (gap na sequência #2)] = MAXIMUM[2,1,1], ou seja, M3,2 = 2

Algoritmo de Needleman & Wunsch (Preenchimento)

www.python.org

0 G A A T T C A G T T A

0 0 0 0 0 0 0 0 0 0 0 0 0

G 0 1 1 1 1 1 1 1 1 1 1 1

G 0 1 1

A 0 1 2

T 0 1

C 0 1

G 0 1

A 0 1

Sequência #1

0

1

2

3

4

5

6

7

Sequência #2

0 1 2 3 4 5 6 7 8 9 10 11

66

Aplicando-se o critério temos: M4,2 = MAXIMUM[

M3, 1 + S4,2 (coincidência ou não na diagonal da matriz),

M4,1 + w (gap na sequência #1),

M3,2 + w (gap na sequência #2)] = MAXIMUM[1,1,2], ou seja, M4,2 = 2

Algoritmo de Needleman & Wunsch (Preenchimento)

www.python.org

0 G A A T T C A G T T A

0 0 0 0 0 0 0 0 0 0 0 0 0

G 0 1 1 1 1 1 1 1 1 1 1 1

G 0 1 1

A 0 1 2

T 0 1 2

C 0 1

G 0 1

A 0 1

Sequência #1

0

1

2

3

4

5

6

7

Sequência #2

0 1 2 3 4 5 6 7 8 9 10 11

67

Aplicando-se o critério temos: M5,2 = MAXIMUM[

M4, 1 + S5,2 (coincidência ou não na diagonal da matriz),

M5,1 + w (gap na sequência #1),

M4,2 + w (gap na sequência #2)] = MAXIMUM[1,1,2], ou seja, M5,2 = 2

Algoritmo de Needleman & Wunsch (Preenchimento)

www.python.org

0 G A A T T C A G T T A

0 0 0 0 0 0 0 0 0 0 0 0 0

G 0 1 1 1 1 1 1 1 1 1 1 1

G 0 1 1

A 0 1 2

T 0 1 2

C 0 1 2

G 0 1

A 0 1

Sequência #1

0

1

2

3

4

5

6

7

Sequência #2

0 1 2 3 4 5 6 7 8 9 10 11

68

Aplicando-se o critério temos: M6,2 = MAXIMUM[

M5, 1 + S6,2 (coincidência ou não na diagonal da matriz),

M6,1 + w (gap na sequência #1),

M5,2 + w (gap na sequência #2)] = MAXIMUM[1,1,2], ou seja, M6,2 = 2

Algoritmo de Needleman & Wunsch (Preenchimento)

www.python.org

0 G A A T T C A G T T A

0 0 0 0 0 0 0 0 0 0 0 0 0

G 0 1 1 1 1 1 1 1 1 1 1 1

G 0 1 1

A 0 1 2

T 0 1 2

C 0 1 2

G 0 1 2

A 0 1

Sequência #1

0

1

2

3

4

5

6

7

Sequência #2

0 1 2 3 4 5 6 7 8 9 10 11

69

Aplicando-se o critério temos: M7,2 = MAXIMUM[

M6, 1 + S7,2 (coincidência ou não na diagonal da matriz),

M7,1 + w (gap na sequência #1),

M7,2 + w (gap na sequência #2)] = MAXIMUM[2,1,2], ou seja, M7,2 = 2

Algoritmo de Needleman & Wunsch (Preenchimento)

www.python.org

0 G A A T T C A G T T A

0 0 0 0 0 0 0 0 0 0 0 0 0

G 0 1 1 1 1 1 1 1 1 1 1 1

G 0 1 1

A 0 1 2

T 0 1 2

C 0 1 2

G 0 1 2

A 0 1 2

Sequência #1

0

1

2

3

4

5

6

7

Sequência #2

0 1 2 3 4 5 6 7 8 9 10 11

70

Aplicando-se o critério temos: M2,3 = MAXIMUM[

M1, 2 + S2,3 (coincidência ou não na diagonal da matriz),

M2,2 + w (gap na sequência #1),

M1,3 + w (gap na sequência #2)] = MAXIMUM[1,1,1], ou seja, M2,3 = 1

Algoritmo de Needleman & Wunsch (Preenchimento)

www.python.org

0 G A A T T C A G T T A

0 0 0 0 0 0 0 0 0 0 0 0 0

G 0 1 1 1 1 1 1 1 1 1 1 1

G 0 1 1 1

A 0 1 2

T 0 1 2

C 0 1 2

G 0 1 2

A 0 1 2

Sequência #1

0

1

2

3

4

5

6

7

Sequência #2

0 1 2 3 4 5 6 7 8 9 10 11

71

Aplicando-se o critério temos: M2,4 = MAXIMUM[

M1, 3 + S2,4 (coincidência ou não na diagonal da matriz),

M2,3 + w (gap na sequência #1),

M1,4 + w (gap na sequência #2)] = MAXIMUM[1,1,1], ou seja, M2,4 = 1

Algoritmo de Needleman & Wunsch (Preenchimento)

www.python.org

0 G A A T T C A G T T A

0 0 0 0 0 0 0 0 0 0 0 0 0

G 0 1 1 1 1 1 1 1 1 1 1 1

G 0 1 1 1 1

A 0 1 2

T 0 1 2

C 0 1 2

G 0 1 2

A 0 1 2

Sequência #1

0

1

2

3

4

5

6

7

Sequência #2

0 1 2 3 4 5 6 7 8 9 10 11

72

Aplicando-se o critério temos: M2,5 = MAXIMUM[

M1, 4 + S2,5 (coincidência ou não na diagonal da matriz),

M2,4 + w (gap na sequência #1),

M1,5 + w (gap na sequência #2)] = MAXIMUM[1,1,1], ou seja, M2,5 = 1

Algoritmo de Needleman & Wunsch (Preenchimento)

www.python.org

0 G A A T T C A G T T A

0 0 0 0 0 0 0 0 0 0 0 0 0

G 0 1 1 1 1 1 1 1 1 1 1 1

G 0 1 1 1 1 1

A 0 1 2

T 0 1 2

C 0 1 2

G 0 1 2

A 0 1 2

Sequência #1

0

1

2

3

4

5

6

7

Sequência #2

0 1 2 3 4 5 6 7 8 9 10 11

73

Aplicando-se o critério temos: M2,6 = MAXIMUM[

M1, 5 + S2,6 (coincidência ou não na diagonal da matriz),

M2,5 + w (gap na sequência #1),

M1,6 + w (gap na sequência #2)] = MAXIMUM[1,1,1], ou seja, M2,6 = 1

Algoritmo de Needleman & Wunsch (Preenchimento)

www.python.org

0 G A A T T C A G T T A

0 0 0 0 0 0 0 0 0 0 0 0 0

G 0 1 1 1 1 1 1 1 1 1 1 1

G 0 1 1 1 1 1 1

A 0 1 2

T 0 1 2

C 0 1 2

G 0 1 2

A 0 1 2

Sequência #1

0

1

2

3

4

5

6

7

Sequência #2

0 1 2 3 4 5 6 7 8 9 10 11

74

Aplicando-se o critério temos: M2,7 = MAXIMUM[

M1, 6 + S2,7 (coincidência ou não na diagonal da matriz),

M2,6 + w (gap na sequência #1),

M1,7 + w (gap na sequência #2)] = MAXIMUM[1,1,1], ou seja, M2,7 = 1

Algoritmo de Needleman & Wunsch (Preenchimento)

www.python.org

0 G A A T T C A G T T A

0 0 0 0 0 0 0 0 0 0 0 0 0

G 0 1 1 1 1 1 1 1 1 1 1 1

G 0 1 1 1 1 1 1 1

A 0 1 2

T 0 1 2

C 0 1 2

G 0 1 2

A 0 1 2

Sequência #1

0

1

2

3

4

5

6

7

Sequência #2

0 1 2 3 4 5 6 7 8 9 10 11

75

Aplicando-se o critério temos: M2,8 = MAXIMUM[

M1, 7 + S2,8 (coincidência ou não na diagonal da matriz),

M2,7 + w (gap na sequência #1),

M1,8 + w (gap na sequência #2)] = MAXIMUM[2,1,1], ou seja, M2,8 = 2

Algoritmo de Needleman & Wunsch (Preenchimento)

www.python.org

0 G A A T T C A G T T A

0 0 0 0 0 0 0 0 0 0 0 0 0

G 0 1 1 1 1 1 1 1 1 1 1 1

G 0 1 1 1 1 1 1 1 2

A 0 1 2

T 0 1 2

C 0 1 2

G 0 1 2

A 0 1 2

Sequência #1

0

1

2

3

4

5

6

7

Sequência #2

0 1 2 3 4 5 6 7 8 9 10 11

76

Aplicando-se o critério temos: M2,9 = MAXIMUM[

M1, 8 + S2,9 (coincidência ou não na diagonal da matriz),

M2,8 + w (gap na sequência #1),

M1,9 + w (gap na sequência #2)] = MAXIMUM[1,2,1], ou seja, M2,9 = 2

Algoritmo de Needleman & Wunsch (Preenchimento)

www.python.org

0 G A A T T C A G T T A

0 0 0 0 0 0 0 0 0 0 0 0 0

G 0 1 1 1 1 1 1 1 1 1 1 1

G 0 1 1 1 1 1 1 1 2 2

A 0 1 2

T 0 1 2

C 0 1 2

G 0 1 2

A 0 1 2

Sequência #1

0

1

2

3

4

5

6

7

Sequência #2

0 1 2 3 4 5 6 7 8 9 10 11

77

Aplicando-se o critério temos: M2,10 = MAXIMUM[

M1, 9 + S2,10 (coincidência ou não na diagonal da matriz),

M2,9 + w (gap na sequência #1),

M1,10 + w (gap na sequência #2)] = MAXIMUM[1,2,1], ou seja, M2,10 = 2

Algoritmo de Needleman & Wunsch (Preenchimento)

www.python.org

0 G A A T T C A G T T A

0 0 0 0 0 0 0 0 0 0 0 0 0

G 0 1 1 1 1 1 1 1 1 1 1 1

G 0 1 1 1 1 1 1 1 2 2 2

A 0 1 2

T 0 1 2

C 0 1 2

G 0 1 2

A 0 1 2

Sequência #1

0

1

2

3

4

5

6

7

Sequência #2

0 1 2 3 4 5 6 7 8 9 10 11

78

Aplicando-se o critério temos: M2,11 = MAXIMUM[

M1, 10 + S2,11 (coincidência ou não na diagonal da matriz),

M2,10 + w (gap na sequência #1),

M1,11 + w (gap na sequência #2)] = MAXIMUM[1,2,1], ou seja, M2,11 = 2

Algoritmo de Needleman & Wunsch (Preenchimento)

www.python.org

0 G A A T T C A G T T A

0 0 0 0 0 0 0 0 0 0 0 0 0

G 0 1 1 1 1 1 1 1 1 1 1 1

G 0 1 1 1 1 1 1 1 2 2 2 2

A 0 1 2

T 0 1 2

C 0 1 2

G 0 1 2

A 0 1 2

Sequência #1

0

1

2

3

4

5

6

7

Sequência #2

0 1 2 3 4 5 6 7 8 9 10 11

79

Aplicando-se o critério temos: M3,3 = MAXIMUM[

M2, 2 + S3,3 (coincidência ou não na diagonal da matriz),

M3,2 + w (gap na sequência #1),

M2,3 + w (gap na sequência #2)] = MAXIMUM[2,2,1], ou seja, M3,3 = 2

Algoritmo de Needleman & Wunsch (Preenchimento)

www.python.org

0 G A A T T C A G T T A

0 0 0 0 0 0 0 0 0 0 0 0 0

G 0 1 1 1 1 1 1 1 1 1 1 1

G 0 1 1 1 1 1 1 1 2 2 2 2

A 0 1 2 2

T 0 1 2

C 0 1 2

G 0 1 2

A 0 1 2

Sequência #1

0

1

2

3

4

5

6

7

Sequência #2

0 1 2 3 4 5 6 7 8 9 10 11

80

Aplicando-se o critério temos: M4,3 = MAXIMUM[

M3, 2 + S4,3 (coincidência ou não na diagonal da matriz),

M4,2 + w (gap na sequência #1),

M3,3 + w (gap na sequência #2)] = MAXIMUM[2,2,2], ou seja, M4,3 = 2

Algoritmo de Needleman & Wunsch (Preenchimento)

www.python.org

0 G A A T T C A G T T A

0 0 0 0 0 0 0 0 0 0 0 0 0

G 0 1 1 1 1 1 1 1 1 1 1 1

G 0 1 1 1 1 1 1 1 2 2 2 2

A 0 1 2 2

T 0 1 2 2

C 0 1 2

G 0 1 2

A 0 1 2

Sequência #1

0

1

2

3

4

5

6

7

Sequência #2

0 1 2 3 4 5 6 7 8 9 10 11

81

Aplicando-se o critério temos: M5,3 = MAXIMUM[

M4, 2 + S5,3 (coincidência ou não na diagonal da matriz),

M5,2 + w (gap na sequência #1),

M4,3 + w (gap na sequência #2)] = MAXIMUM[2,2,2], ou seja, M5,3 = 2

Algoritmo de Needleman & Wunsch (Preenchimento)

www.python.org

0 G A A T T C A G T T A

0 0 0 0 0 0 0 0 0 0 0 0 0

G 0 1 1 1 1 1 1 1 1 1 1 1

G 0 1 1 1 1 1 1 1 2 2 2 2

A 0 1 2 2

T 0 1 2 2

C 0 1 2 2

G 0 1 2

A 0 1 2

Sequência #1

0

1

2

3

4

5

6

7

Sequência #2

0 1 2 3 4 5 6 7 8 9 10 11

82

Aplicando-se o critério temos: M6,3 = MAXIMUM[

M5, 2 + S6,3 (coincidência ou não na diagonal da matriz),

M6,2 + w (gap na sequência #1),

M5,3 + w (gap na sequência #2)] = MAXIMUM[2,2,2], ou seja, M6,3 = 2

Algoritmo de Needleman & Wunsch (Preenchimento)

www.python.org

0 G A A T T C A G T T A

0 0 0 0 0 0 0 0 0 0 0 0 0

G 0 1 1 1 1 1 1 1 1 1 1 1

G 0 1 1 1 1 1 1 1 2 2 2 2

A 0 1 2 2

T 0 1 2 2

C 0 1 2 2

G 0 1 2 2

A 0 1 2

Sequência #1

0

1

2

3

4

5

6

7

Sequência #2

0 1 2 3 4 5 6 7 8 9 10 11

83

Aplicando-se o critério temos: M7,3 = MAXIMUM[

M6, 2 + S7,3 (coincidência ou não na diagonal da matriz),

M7,2 + w (gap na sequência #1),

M6,3 + w (gap na sequência #2)] = MAXIMUM[3,2,2], ou seja, M7,3 = 3

Algoritmo de Needleman & Wunsch (Preenchimento)

www.python.org

0 G A A T T C A G T T A

0 0 0 0 0 0 0 0 0 0 0 0 0

G 0 1 1 1 1 1 1 1 1 1 1 1

G 0 1 1 1 1 1 1 1 2 2 2 2

A 0 1 2 2

T 0 1 2 2

C 0 1 2 2

G 0 1 2 2

A 0 1 2 3

Sequência #1

0

1

2

3

4

5

6

7

Sequência #2

0 1 2 3 4 5 6 7 8 9 10 11

84

Aplicando-se o critério temos: M3,4 = MAXIMUM[

M2, 3 + S3,4 (coincidência ou não na diagonal da matriz),

M3,3 + w (gap na sequência #1),

M2,4 + w (gap na sequência #2)] = MAXIMUM[1,2,1], ou seja, M3,4 = 2

Algoritmo de Needleman & Wunsch (Preenchimento)

www.python.org

0 G A A T T C A G T T A

0 0 0 0 0 0 0 0 0 0 0 0 0

G 0 1 1 1 1 1 1 1 1 1 1 1

G 0 1 1 1 1 1 1 1 2 2 2 2

A 0 1 2 2 2

T 0 1 2 2

C 0 1 2 2

G 0 1 2 2

A 0 1 2 3

Sequência #1

0

1

2

3

4

5

6

7

Sequência #2

0 1 2 3 4 5 6 7 8 9 10 11

85

Aplicando-se o critério temos: M3,5 = MAXIMUM[

M2, 4 + S3,5 (coincidência ou não na diagonal da matriz),

M3,4 + w (gap na sequência #1),

M2,5 + w (gap na sequência #2)] = MAXIMUM[1,2,1], ou seja, M3,5 = 2

Algoritmo de Needleman & Wunsch (Preenchimento)

www.python.org

0 G A A T T C A G T T A

0 0 0 0 0 0 0 0 0 0 0 0 0

G 0 1 1 1 1 1 1 1 1 1 1 1

G 0 1 1 1 1 1 1 1 2 2 2 2

A 0 1 2 2 2 2

T 0 1 2 2

C 0 1 2 2

G 0 1 2 2

A 0 1 2 3

Sequência #1

0

1

2

3

4

5

6

7

Sequência #2

0 1 2 3 4 5 6 7 8 9 10 11

86

Aplicando-se o critério temos: M3,6 = MAXIMUM[

M2, 5 + S3,6 (coincidência ou não na diagonal da matriz),

M3,5 + w (gap na sequência #1),

M2,6 + w (gap na sequência #2)] = MAXIMUM[1,2,1], ou seja, M3,6 = 2

Algoritmo de Needleman & Wunsch (Preenchimento)

www.python.org

0 G A A T T C A G T T A

0 0 0 0 0 0 0 0 0 0 0 0 0

G 0 1 1 1 1 1 1 1 1 1 1 1

G 0 1 1 1 1 1 1 1 2 2 2 2

A 0 1 2 2 2 2 2

T 0 1 2 2

C 0 1 2 2

G 0 1 2 2

A 0 1 2 3

Sequência #1

0

1

2

3

4

5

6

7

Sequência #2

0 1 2 3 4 5 6 7 8 9 10 11

87

Aplicando-se o critério temos: M3,7 = MAXIMUM[

M2, 6 + S3,7 (coincidência ou não na diagonal da matriz),

M3,6 + w (gap na sequência #1),

M2,7 + w (gap na sequência #2)] = MAXIMUM[2,2,1], ou seja, M3,7 = 2

Algoritmo de Needleman & Wunsch (Preenchimento)

www.python.org

0 G A A T T C A G T T A

0 0 0 0 0 0 0 0 0 0 0 0 0

G 0 1 1 1 1 1 1 1 1 1 1 1

G 0 1 1 1 1 1 1 1 2 2 2 2

A 0 1 2 2 2 2 2 2

T 0 1 2 2

C 0 1 2 2

G 0 1 2 2

A 0 1 2 3

Sequência #1

0

1

2

3

4

5

6

7

Sequência #2

0 1 2 3 4 5 6 7 8 9 10 11

88

Aplicando-se o critério temos: M3,8 = MAXIMUM[

M2, 7 + S3,8 (coincidência ou não na diagonal da matriz),

M3,7 + w (gap na sequência #1),

M2,8 + w (gap na sequência #2)] = MAXIMUM[1,2,2], ou seja, M3,8 = 2

Algoritmo de Needleman & Wunsch (Preenchimento)

www.python.org

0 G A A T T C A G T T A

0 0 0 0 0 0 0 0 0 0 0 0 0

G 0 1 1 1 1 1 1 1 1 1 1 1

G 0 1 1 1 1 1 1 1 2 2 2 2

A 0 1 2 2 2 2 2 2 2

T 0 1 2 2

C 0 1 2 2

G 0 1 2 2

A 0 1 2 3

Sequência #1

0

1

2

3

4

5

6

7

Sequência #2

0 1 2 3 4 5 6 7 8 9 10 11

89

Aplicando-se o critério temos: M3,9 = MAXIMUM[

M2, 8 + S3,9 (coincidência ou não na diagonal da matriz),

M3,8 + w (gap na sequência #1),

M2,9 + w (gap na sequência #2)] = MAXIMUM[2,2,2], ou seja, M3,9 = 2

Algoritmo de Needleman & Wunsch (Preenchimento)

www.python.org

0 G A A T T C A G T T A

0 0 0 0 0 0 0 0 0 0 0 0 0

G 0 1 1 1 1 1 1 1 1 1 1 1

G 0 1 1 1 1 1 1 1 2 2 2 2

A 0 1 2 2 2 2 2 2 2 2

T 0 1 2 2

C 0 1 2 2

G 0 1 2 2

A 0 1 2 3

Sequência #1

0

1

2

3

4

5

6

7

Sequência #2

0 1 2 3 4 5 6 7 8 9 10 11

90

Aplicando-se o critério temos: M3,10 = MAXIMUM[

M2, 9 + S3,10 (coincidência ou não na diagonal da matriz),

M3,9 + w (gap na sequência #1),

M2,10 + w (gap na sequência #2)] = MAXIMUM[2,2,2], ou seja, M3,10 = 2

Algoritmo de Needleman & Wunsch (Preenchimento)

www.python.org

0 G A A T T C A G T T A

0 0 0 0 0 0 0 0 0 0 0 0 0

G 0 1 1 1 1 1 1 1 1 1 1 1

G 0 1 1 1 1 1 1 1 2 2 2 2

A 0 1 2 2 2 2 2 2 2 2 2

T 0 1 2 2

C 0 1 2 2

G 0 1 2 2

A 0 1 2 3

Sequência #1

0

1

2

3

4

5

6

7

Sequência #2

0 1 2 3 4 5 6 7 8 9 10 11

91

Aplicando-se o critério temos: M3,11 = MAXIMUM[

M2, 10 + S3,11 (coincidência ou não na diagonal da matriz),

M3,10 + w (gap na sequência #1),

M2,11 + w (gap na sequência #2)] = MAXIMUM[3,2,2], ou seja, M3,11 = 3

Algoritmo de Needleman & Wunsch (Preenchimento)

www.python.org

0 G A A T T C A G T T A

0 0 0 0 0 0 0 0 0 0 0 0 0

G 0 1 1 1 1 1 1 1 1 1 1 1

G 0 1 1 1 1 1 1 1 2 2 2 2

A 0 1 2 2 2 2 2 2 2 2 2 3

T 0 1 2 2

C 0 1 2 2

G 0 1 2 2

A 0 1 2 3

Sequência #1

0

1

2

3

4

5

6

7

Sequência #2

0 1 2 3 4 5 6 7 8 9 10 11

92

Aplicando-se o critério para o restante da matriz, temos o resultado abaixo.

Algoritmo de Needleman & Wunsch (Preenchimento)

www.python.org

0 G A A T T C A G T T A

0 0 0 0 0 0 0 0 0 0 0 0 0

G 0 1 1 1 1 1 1 1 1 1 1 1

G 0 1 1 1 1 1 1 1 2 2 2 2

A 0 1 2 2 2 2 2 2 2 2 2 3

T 0 1 2 2 3 3 3 3 3 3 3 3

C 0 1 2 2 3 3 4 4 4 4 4 4

G 0 1 2 2 3 3 4 4 5 5 5 5

A 0 1 2 3 3 3 4 5 5 5 5 6

Sequência #1

0

1

2

3

4

5

6

7

Sequência #2

0 1 2 3 4 5 6 7 8 9 10 11

93

No alinhamento iniciamos onde temos o maior escore, na posição 7,11, indicada pelo

círculo vermelho abaixo. Para escolher o próximo movimento, vemos as posições

anteriores, indicadas por flechas. Todas tem escore 5, assim movemos na diagonal.

Movimento na diagonal significa alinhamento das duas bases.

Algoritmo de Needleman & Wunsch (Alinhamento)

www.python.org

0 G A A T T C A G T T A

0 0 0 0 0 0 0 0 0 0 0 0 0

G 0 1 1 1 1 1 1 1 1 1 1 1

G 0 1 1 1 1 1 1 1 2 2 2 2

A 0 1 2 2 2 2 2 2 2 2 2 3

T 0 1 2 2 3 3 3 3 3 3 3 3

C 0 1 2 2 3 3 4 4 4 4 4 4

G 0 1 2 2 3 3 4 4 5 5 5 5

A 0 1 2 3 3 3 4 5 5 5 5 6

Sequência #1

0

1

2

3

4

5

6

7

Sequência #2

0 1 2 3 4 5 6 7 8 9 10 11

94

O alinhamento parcial está indicado abaixo.

Algoritmo de Needleman & Wunsch (Alinhamento)

www.python.org

0 G A A T T C A G T T A

0 0 0 0 0 0 0 0 0 0 0 0 0

G 0 1 1 1 1 1 1 1 1 1 1 1

G 0 1 1 1 1 1 1 1 2 2 2 2

A 0 1 2 2 2 2 2 2 2 2 2 3

T 0 1 2 2 3 3 3 3 3 3 3 3

C 0 1 2 2 3 3 4 4 4 4 4 4

G 0 1 2 2 3 3 4 4 5 5 5 5

A 0 1 2 3 3 3 4 5 5 5 5 6

Sequência #1

0

1

2

3

4

5

6

7

Sequência #2

0 1 2 3 4 5 6 7 8 9 10 11

Sequência #1 G - A A T T C A G T T A

| |

Sequência #2 G G A - T - C - G - - A

95

Analisando-se os escores vizinhos, vemos que o maior está à esquerda (5), o que

indica uma inserção de gap na sequência 2, como mostrado abaixo.

Algoritmo de Needleman & Wunsch (Alinhamento)

www.python.org

0 G A A T T C A G T T A

0 0 0 0 0 0 0 0 0 0 0 0 0

G 0 1 1 1 1 1 1 1 1 1 1 1

G 0 1 1 1 1 1 1 1 2 2 2 2

A 0 1 2 2 2 2 2 2 2 2 2 3

T 0 1 2 2 3 3 3 3 3 3 3 3

C 0 1 2 2 3 3 4 4 4 4 4 4

G 0 1 2 2 3 3 4 4 5 5 5 5

A 0 1 2 3 3 3 4 5 5 5 5 6

Sequência #1

0

1

2

3

4

5

6

7

Sequência #2

0 1 2 3 4 5 6 7 8 9 10 11

Sequência #1 G - A A T T C A G T T A

| |

Sequência #2 G G A - T - C - G - - A

Gap

96

Analisando-se os escores vizinhos, vemos que o maior está à esquerda (5) de novo, o

que indica uma nova inserção de gap na sequência 2, como mostrado abaixo.

Algoritmo de Needleman & Wunsch (Alinhamento)

www.python.org

0 G A A T T C A G T T A

0 0 0 0 0 0 0 0 0 0 0 0 0

G 0 1 1 1 1 1 1 1 1 1 1 1

G 0 1 1 1 1 1 1 1 2 2 2 2

A 0 1 2 2 2 2 2 2 2 2 2 3

T 0 1 2 2 3 3 3 3 3 3 3 3

C 0 1 2 2 3 3 4 4 4 4 4 4

G 0 1 2 2 3 3 4 4 5 5 5 5

A 0 1 2 3 3 3 4 5 5 5 5 6

Sequência #1

0

1

2

3

4

5

6

7

Sequência #2

0 1 2 3 4 5 6 7 8 9 10 11

Sequência #1 G - A A T T C A G T T A

| | | | |

Sequência #2 G G A - T - C - G - - A

97

Analisando-se os escores vizinhos, temos 4 em todos, assim seguimos na diagonal, o

que indica uma coincidência, como mostrado abaixo.

Algoritmo de Needleman & Wunsch (Alinhamento)

www.python.org

0 G A A T T C A G T T A

0 0 0 0 0 0 0 0 0 0 0 0 0

G 0 1 1 1 1 1 1 1 1 1 1 1

G 0 1 1 1 1 1 1 1 2 2 2 2

A 0 1 2 2 2 2 2 2 2 2 2 3

T 0 1 2 2 3 3 3 3 3 3 3 3

C 0 1 2 2 3 3 4 4 4 4 4 4

G 0 1 2 2 3 3 4 4 5 5 5 5

A 0 1 2 3 3 3 4 5 5 5 5 6

Sequência #1

0

1

2

3

4

5

6

7

Sequência #2

0 1 2 3 4 5 6 7 8 9 10 11

Sequência #1 G - A A T T C A G T T A

| | | | | |

Sequência #2 G G A - T - C - G - - A

98

O maior escore entre os vizinhos é 4, o que indica a inserção de um novo gap na

sequência 2, como mostrado abaixo.

Algoritmo de Needleman & Wunsch (Alinhamento)

www.python.org

0 G A A T T C A G T T A

0 0 0 0 0 0 0 0 0 0 0 0 0

G 0 1 1 1 1 1 1 1 1 1 1 1

G 0 1 1 1 1 1 1 1 2 2 2 2

A 0 1 2 2 2 2 2 2 2 2 2 3

T 0 1 2 2 3 3 3 3 3 3 3 3

C 0 1 2 2 3 3 4 4 4 4 4 4

G 0 1 2 2 3 3 4 4 5 5 5 5

A 0 1 2 3 3 3 4 5 5 5 5 6

Sequência #1

0

1

2

3

4

5

6

7

Sequência #2

0 1 2 3 4 5 6 7 8 9 10 11

Sequência #1 G - A A T T C A G T T A

| | | | | |

Sequência #2 G G A - T - C - G - - A

99

Novo movimento na diagonal, temos o alinhamento abaixo.

Algoritmo de Needleman & Wunsch (Alinhamento)

www.python.org

0 G A A T T C A G T T A

0 0 0 0 0 0 0 0 0 0 0 0 0

G 0 1 1 1 1 1 1 1 1 1 1 1

G 0 1 1 1 1 1 1 1 2 2 2 2

A 0 1 2 2 2 2 2 2 2 2 2 3

T 0 1 2 2 3 3 3 3 3 3 3 3

C 0 1 2 2 3 3 4 4 4 4 4 4

G 0 1 2 2 3 3 4 4 5 5 5 5

A 0 1 2 3 3 3 4 5 5 5 5 6

Sequência #1

0

1

2

3

4

5

6

7

Sequência #2

0 1 2 3 4 5 6 7 8 9 10 11

Sequência #1 G - A A T T C A G T T A

| | | || | |

Sequência #2 G G A - T - C - G - - A

100

O escore mais alto está à esquerda (3), o que representa a inserção de gap na

sequência 2, como mostrado abaixo.

Algoritmo de Needleman & Wunsch (Alinhamento)

www.python.org

0 G A A T T C A G T T A

0 0 0 0 0 0 0 0 0 0 0 0 0

G 0 1 1 1 1 1 1 1 1 1 1 1

G 0 1 1 1 1 1 1 1 2 2 2 2

A 0 1 2 2 2 2 2 2 2 2 2 3

T 0 1 2 2 3 3 3 3 3 3 3 3

C 0 1 2 2 3 3 4 4 4 4 4 4

G 0 1 2 2 3 3 4 4 5 5 5 5

A 0 1 2 3 3 3 4 5 5 5 5 6

Sequência #1

0

1

2

3

4

5

6

7

Sequência #2

0 1 2 3 4 5 6 7 8 9 10 11

Sequência #1 G - A A T T C A G T T A

| | | | | |

Sequência #2 G G A - T - C - G - - A

101

Temos agora movimento na diagonal, e coincidência, como indicado abaixo.

Algoritmo de Needleman & Wunsch (Alinhamento)

www.python.org

0 G A A T T C A G T T A

0 0 0 0 0 0 0 0 0 0 0 0 0

G 0 1 1 1 1 1 1 1 1 1 1 1

G 0 1 1 1 1 1 1 1 2 2 2 2

A 0 1 2 2 2 2 2 2 2 2 2 3

T 0 1 2 2 3 3 3 3 3 3 3 3

C 0 1 2 2 3 3 4 4 4 4 4 4

G 0 1 2 2 3 3 4 4 5 5 5 5

A 0 1 2 3 3 3 4 5 5 5 5 6

Sequência #1

0

1

2

3

4

5

6

7

Sequência #2

0 1 2 3 4 5 6 7 8 9 10 11

Sequência #1 G - A A T T C A G T T A

| | | | | |

Sequência #2 G G A - T - C - G - - A

102

O maior escore localiza-se à esquerda (2), o que representa a inserção de gap na

sequência 2, como mostrado abaixo.

Algoritmo de Needleman & Wunsch (Alinhamento)

www.python.org

0 G A A T T C A G T T A

0 0 0 0 0 0 0 0 0 0 0 0 0

G 0 1 1 1 1 1 1 1 1 1 1 1

G 0 1 1 1 1 1 1 1 2 2 2 2

A 0 1 2 2 2 2 2 2 2 2 2 3

T 0 1 2 2 3 3 3 3 3 3 3 3

C 0 1 2 2 3 3 4 4 4 4 4 4

G 0 1 2 2 3 3 4 4 5 5 5 5

A 0 1 2 3 3 3 4 5 5 5 5 6

Sequência #1

0

1

2

3

4

5

6

7

Sequência #2

0 1 2 3 4 5 6 7 8 9 10 11

Sequência #1 G - A A T T C A G T T A

| | | | | |

Sequência #2 G G A - T - C - G - - A

103

Agora temos um deslocamento na diagonal, o que leva a uma coincidência no

alinhamento, como mostrado abaixo.

Algoritmo de Needleman & Wunsch (Alinhamento)

www.python.org

0 G A A T T C A G T T A

0 0 0 0 0 0 0 0 0 0 0 0 0

G 0 1 1 1 1 1 1 1 1 1 1 1

G 0 1 1 1 1 1 1 1 2 2 2 2

A 0 1 2 2 2 2 2 2 2 2 2 3

T 0 1 2 2 3 3 3 3 3 3 3 3

C 0 1 2 2 3 3 4 4 4 4 4 4

G 0 1 2 2 3 3 4 4 5 5 5 5

A 0 1 2 3 3 3 4 5 5 5 5 6

Sequência #1

0

1

2

3

4

5

6

7

Sequência #2

0 1 2 3 4 5 6 7 8 9 10 11

Sequência #1 G - A A T T C A G T T A

| | | | | |

Sequência #2 G G A - T - C - G - - A

104

Temos o maior escore na posição acima, o que representa uma inserção de gap na

sequência 1, como indicado abaixo.

Algoritmo de Needleman & Wunsch (Alinhamento)

www.python.org

0 G A A T T C A G T T A

0 0 0 0 0 0 0 0 0 0 0 0 0

G 0 1 1 1 1 1 1 1 1 1 1 1

G 0 1 1 1 1 1 1 1 2 2 2 2

A 0 1 2 2 2 2 2 2 2 2 2 3

T 0 1 2 2 3 3 3 3 3 3 3 3

C 0 1 2 2 3 3 4 4 4 4 4 4

G 0 1 2 2 3 3 4 4 5 5 5 5

A 0 1 2 3 3 3 4 5 5 5 5 6

Sequência #1

0

1

2

3

4

5

6

7

Sequência #2

0 1 2 3 4 5 6 7 8 9 10 11

Sequência #1 G - A A T T C A G T T A

| | | | | |

Sequência #2 G G A - T - C - G - - A

105

Por último temos um deslocamento na diagonal, o que representa uma coincidência,

como indicado abaixo.

Algoritmo de Needleman & Wunsch (Alinhamento)

www.python.org

0 G A A T T C A G T T A

0 0 0 0 0 0 0 0 0 0 0 0 0

G 0 1 1 1 1 1 1 1 1 1 1 1

G 0 1 1 1 1 1 1 1 2 2 2 2

A 0 1 2 2 2 2 2 2 2 2 2 3

T 0 1 2 2 3 3 3 3 3 3 3 3

C 0 1 2 2 3 3 4 4 4 4 4 4

G 0 1 2 2 3 3 4 4 5 5 5 5

A 0 1 2 3 3 3 4 5 5 5 5 6

Sequência #1

0

1

2

3

4

5

6

7

Sequência #2

0 1 2 3 4 5 6 7 8 9 10 11

Sequência #1 G - A A T T C A G T T A

| | | | | |

Sequência #2 G G A - T - C - G - - A

106

Completamos o alinhamento. O algoritmo apresentado é uma simplificação, ficou

faltando um valor para a penalidade de gap na montagem da matriz. Programas de

alinhamento modernos, como Clustaw e outros, levam em conta as penalidades. Além

disso, é feito uso de matrizes de escore, para pontuar diferentes alinhamentos, como

no caso de aminoácidos.

Algoritmo de Needleman & Wunsch (Alinhamento)

www.python.org

Sequência #1 G - A A T T C A G T T A

| | | | | |

Sequência #2 G G A - T - C - G - - A

107

Abaixo temos o programa algo_NW1.py, que realiza o alinhamento de duas

sequências de DNA, a partir do algoritmo de Needleman & Wunsch. O programa é

relativamente longo, assim apresentaremos por partes.

Inicialmente importamos a biblioteca NumPy, que traz recursos matemáticos como

matrizes e vetores. As matrizes e vetores são implementados como arrays, que

assemelham-se a listas, mas com um tipo somente de dados.

Em seguida definimos as sequências a serem alinhadas e determinamos o tamanho

delas. Somamos 1 ao tamanho das sequências, pois estes números serão usados

para definir a matriz caminho (n1xn2), que tem uma coluna e uma linha extras.

Algoritmo de Needleman & Wunsch (Implementação)

www.python.org

# Import library

import numpy as np

# Sequences to align

seq1 = "GAATTCAGTTA"

seq2 = "GGATCGA"

# Length of sequences

n1 = len(seq1)+1

n2 = len(seq2)+1

108

Agora definimos a matriz caminho, a ser atribuída à variável M. Usamos o recurso

np.array(). Veja que as variáveis n1 e n2 definem os números de linhas e colunas da

matriz caminho.

Em seguida temos dois loops for, para mostrar as sequências na tela.

# Set up path matrix

M = np.array([[0]*n1]*n2,int) # np.array([[0]*column]*row,int)

# Show sequence

print("Sequences to be aligned:")

for i in range(n1-1):

print(seq1[i],end="")

print()

for j in range(n2-1):

print(seq2[j],end="")

Algoritmo de Needleman & Wunsch (Implementação)

www.python.org

109

Abaixo temos o trecho do código que define a matriz caminho (path matrix), com “1”

atribuído quando as bases coincidem. Esses valores serão usados posteriormente

para os elementos Si,j usados no cálculo dos elementos da matriz caminho para o

alinhamento.

# Define path matrix

# Looping through matrix

for i in range(1,n2):

for j in range(1,n1):

if seq1[j-1] == seq2[i-1]:

M[i][j] = 1

Algoritmo de Needleman & Wunsch (Implementação)

www.python.org

110

Para a construção da matriz caminho completa, usamos a condição já vista para o

alinhamento,

Mi,j = MAXIMUM[

Mi-1, j-1 + Si,j (coincidência ou não na diagonal da matriz),

Mi,j-1 + w (gap na sequência #1),

Mi-1,j + w (gap na sequência #2)]

# Build path matrix

for i in range(1,n2):

for j in range(1,n1):

my_array = [M[i-1][j-1] + M[i][j], M[i][j-1],M[i-1][j]]

M[i][j] = np.max(my_array)

Algoritmo de Needleman & Wunsch (Implementação)

www.python.org

111

Como atribuímos 1 aos elementos da matriz M quando havia coincidência, o elemento

Si,j a ser usado na soma é o elemento Mi,j.

Mi,j = MAXIMUM[

Mi-1, j-1 + Si,j (coincidência ou não na diagonal da matriz),

Mi,j-1 + w (gap na sequência #1),

Mi-1,j + w (gap na sequência #2)]

# Build path matrix

for i in range(1,n2):

for j in range(1,n1):

my_array = [M[i-1][j-1] + M[i][j], M[i][j-1],M[i-1][j]]

M[i][j] = np.max(my_array)

Algoritmo de Needleman & Wunsch (Implementação)

www.python.org

É o mesmo que o Sij da equação acima

112

Veja que montamos um array auxiliar atribuído à variável my_array. Esse array recebe

os três elementos da matriz caminho e identificamos o máximo com o método max,

como mostrado abaixo.

Mi,j = MAXIMUM[

Mi-1, j-1 + Si,j (coincidência ou não na diagonal da matriz),

Mi,j-1 + w (gap na sequência #1),

Mi-1,j + w (gap na sequência #2)]

# Build path matrix

for i in range(1,n2):

for j in range(1,n1):

my_array = [M[i-1][j-1] + M[i][j], M[i][j-1],M[i-1][j]]

M[i][j] = np.max(my_array)

Algoritmo de Needleman & Wunsch (Implementação)

www.python.org

113

Agora mostramos a matriz caminho na tela.

# Show path matrix

print("\n\nPath matrix:")

for i in range(n2):

for j in range(n1):

print(M[i][j],end=" ")

print()

Algoritmo de Needleman & Wunsch (Implementação)

www.python.org

114

Abaixo atribuímos valores para variáveis i e j que serão usadas em loops. Definimos

strings vazias para irmos montando as sequências alinhadas.

# Set up initial values for i and j

i = n2-1

j = n1-1

# Set up empty strings

s1 = ""

s2 = ""

Algoritmo de Needleman & Wunsch (Implementação)

www.python.org

115

115

Abaixo temos um loop while que monta as sequências alinhadas, que vão sendo

atribuídas às variáveis s1 e s2. Podemos pensar neste trecho de código como o

responsável pelo retorno no matriz caminho, a partir do elemento maior.

# while loop

while( i > 0 or j >0):

my_array = [M[i-1][j-1], M[i][j-1],M[i-1][j]]

m1 = np.max(my_array)

if m1 == M[i-1][j-1]:

s1 += seq1[j-1]

s2 += seq2[i-1]

i -= 1

j -= 1

elif m1 == M[i][j-1]:

s1 += seq1[j-1]

s2 += "-"

j -= 1

elif m1 == M[i-1][j]:

s1 += "-"

s2 += seq2[i-1]

i -= 1

Algoritmo de Needleman & Wunsch (Implementação)

www.python.org

116

Agora mostramos os resultados na tela. Como montamos as sequências invertidas,

temos que inverter as strings, usando-se o comando s1[::-1]. Este comando inverte a

sequência de bases atribuídas à variável s1.

print("\nAligned sequences:")

print(s1[::-1])

print(s2[::-1])

Algoritmo de Needleman & Wunsch (Implementação)

www.python.org

117

Abaixo temos o resultado para execução do código.

Algoritmo de Needleman & Wunsch (Implementação)

www.python.org

Sequences to be aligned:

GAATTCAGTTA

GGATCGA

Path matrix:

0 0 0 0 0 0 0 0 0 0 0 0

0 1 1 1 1 1 1 1 1 1 1 1

0 1 1 1 1 1 1 1 2 2 2 2

0 1 2 2 2 2 2 2 2 2 2 3

0 1 2 2 3 3 3 3 3 3 3 3

0 1 2 2 3 3 4 4 4 4 4 4

0 1 2 2 3 3 4 4 5 5 5 5

0 1 2 3 3 3 4 5 5 5 5 6

Aligned sequences:

G-AATTCAGTTA

GGA-T-C-G--A

118

Exercício de Programação

Implemente o Algoritmo de Needleman & Wunsch usando-se a abordagem de

Programação Orientada a Objeto. Considere que o programa tem um método para a

leitura das sequências a serem alinhadas a partir de dois arquivos no formato FASTA.

Chame o novo programa de algo_NW2.py.

119 119

Colophon

This material was produced in a HP Pavillon dm4 notebook with 6GB of memory, a

500 GB hard disk, and an Intel® Core® i7 M620 CPU @ 2.67 GHz running Windows

7 Professional. Text and layout were generated using PowerPoint 2007 and graphical

figures were generated by Visual Molecular Dynamics (VMD)(Humphrey W, Dalke A,

Schulten K.VMD: visual molecular dynamics. J Mol Graph. 1996; 14(1):33-8, 27-8.)

and Matplotlib. Additional figures on the slides 4-10 were taken from the book: Jones,

N. C. & Pevzner, P. A. An Introduction to Bioinformatics Algorithms. The MIT

Press,Cambridge, 2004. This material uses Arial font.

120 120

Author

I graduated in Physics (BSc in Physics) at University of Sao Paulo (USP) in 1990. I completed

a Master Degree in Applied Physics also at USP (1992), working under supervision of Prof.

Yvonne P. Mascarenhas, the founder of crystallography in Brazil. My dissertation was about X-

ray crystallography applied to organometallics compounds (De Azevedo Jr. et al.,1995). During

my PhD I worked under supervision of Prof. Sung-Hou Kim (University of California, Berkeley.

Department of Chemistry), on a split PhD program with a fellowship from Brazilian Research

Council (CNPq)(1993-1996). My PhD was about the crystallographic structure of CDK2 (Cyclin-

Dependent Kinase 2) (De Azevedo Jr. et al., 1996). In 1996, I returned to Brazil. In April 1997, I

finished my PhD and moved to Sao Jose do Rio Preto (SP, Brazil) (UNESP) and worked there

from 1997 to 2005. In 1997, I started the Laboratory of Biomolecular Systems- Department of

Physics-UNESP - São Paulo State University. In 2005, I moved to Porto Alegre/RS (Brazil),

where I am now. My current position is coordinator of the Laboratory of Computational Systems

Biology at Pontifical Catholic University of Rio Grande do Sul (PUCRS). My research interests

are focused on application of computer simulations to analyze protein-ligand interactions. I'm

also interested in the development of bioinspired computing and machine learning algorithms.

We apply these algorithms to molecular docking simulations, protein-ligand interactions and

other scientific and technological problems. I published over 160 scientific papers about protein

structures and computer simulation methods applied to the study of biological systems (H-

index: 36). These publications have over 5000 citations. I am editor for the following journals:

121 121

ALBERTS, B. et al. Biologia Molecular da Célula. 4a edição. Porto Alegre: Artmed editora, Porto Alegre, 2004.

-BRESSERT, Eli. SciPy and NumPy. Sebastopol: O’Reilly Media, Inc., 2013. 56 p.

-DAWSON, Michael. Python Programming, for the absolute beginner. 3ed. Boston: Course Technology, 2010. 455 p.

-HETLAND, Magnus Lie. Python Algorithms. Mastering Basic Algorithms in the Python Language. Nova York: Springer

Science+Business Media LLC, 2010. 316 p.

-IDRIS, Ivan. NumPy 1.5. An action-packed guide dor the easy-to-use, high performance, Python based free open source

NumPy mathematical library using real-world examples. Beginner’s Guide. Birmingham: Packt Publishing Ltd., 2011. 212 p.

-KIUSALAAS, Jaan. Numerical Methods in Engineering with Python. 2ed. Nova York: Cambridge University Press, 2010. 422

p.

-LANDAU, Rubin H. A First Course in Scientific Computing: Symbolic, Graphic, and Numeric Modeling Using Maple, Java,

Mathematica, and Fortran90. Princeton: Princeton University Press, 2005. 481p.

-LANDAU, Rubin H., PÁEZ, Manuel José, BORDEIANU, Cristian C. A Survey of Computational Physics. Introductory

Computational Physics. Princeton: Princeton University Press, 2008. 658 p.

-LUTZ, Mark. Programming Python. 4ed. Sebastopol: O’Reilly Media, Inc., 2010. 1584 p.

-MODEL, Mitchell L. Bioinformatics Programming Using Python. Sebastopol: O’Reilly Media, Inc., 2011. 1584 p.

-TOSI, Sandro. Matplotlib for Python Developers. Birmingham: Packt Publishing Ltd., 2009. 293 p.

Última atualização: 8 de dezembro de 2017.

Referências

www.python.org

122


Recommended