Introdução à programação e aos algoritmos

João Araujo Ribeiro · Capítulo 88 de 103

Páginas do PDF

Introdução à programação e aos algoritmos

7.4 Coelhos de Fibonacci

Entre suas contribuições mais importantes está o “algoritmo de Dijkstra” sobre o

“problema do caminho mínimo”. Atualmente, o prêmio Dijkstra é concedido a artigos

de relevância no campo da computação distribuída.

 

Figura 7.8 Edsger W. Dijkstra. Fonte: Hamilton Richards | Wikimedia.org.

 

7.4 COELHOS DE FIBONACCI

Um problema clássico resolvido recursivamente é o de calcular a série de Fibonacci.

A série surgiu de uma questão de criação de coelhos: em 12 meses, quantos pares de coelhos haverá em uma criação se admitirmos as seguintes regras simplificadoras:

1. Começamos com um casal de coelhos.

2. Cada casal demora um mês para amadurecer sexualmente.

3. Depois de um mês, a partir do amadurecimento, um casal

gera um novo casal de coelhinhos.

4. Pelo menos durante o experimento, os coelhos não morrem.

Usando essas regras:

1. Ao final do primeiro mês temos um único par de coelhos.

2. Ao final do segundo mês, nasce mais um casal. Temos agora

2 pares.

3. Ao final do mês 3, nasce mais um par do casal original. O

casal que nasceu no mês 2 amadurece e temos 3 casais.

4. Ao final do mês 4, nascem mais 2 casais: um do par original e

outro do casal que nasceu no mês 2. Temos 5 casais.

5. E o processo continua...

Assim, o número total de pares é sempre a soma dos pares

existentes nos dois últimos meses.

 

Figura 7.9 Coelhos de Fibonacci. A cada mês o número de pares de

coelhos é igual à soma dos dois últimos meses.

 

A partir deste problema, Fibonacci, no século XIII, definiu a

sequência que depois levou seu nome: Se n = 0, então o número de Fibonacci é igual a 0. Se n é igual a 1, o número de Fibonacci é igual a 1; senão, ele é igual à soma dos dois números anteriores. Na realidade, a série original de Fibonacci começa com 1, pois na sua época o zero nem era considerado um algarismo, mas usar o zero como início da série facilita nosso propósito. Matematicamente:

 

Então, a série é a sequência: 0 1 1 2 3 5 8 13.

O mais fácil desta série é que sua própria definição já é recursiva. A simplicidade de Python permite que uma função que forneça o n-ésimo termo da série seja praticamente uma tradução direta da definição:

def fib(n):

“““Calcula n-

ésimo termo da série de Fibonacci.”””

if n == 0:

return 0

elif n == 1:

return 1

else:

return fib(n-1) + fib(n-2)

 

print(fib(9))

 

■ Programa 7.2: Cálculo do n-ésimo termo da série de

Fibonacci.

 

O Programa 7.2 foi escrito para ser a tradução exata da definição, mas podemos fazer um pouco melhor, percebendo que poderíamos colocar uma condição composta no teste inicial e retornando n:

if n == 0 or n == 1:

return n

que pode ser simplificado ainda mais em:

def fib(n):

“““Calcula n-

ésimo termo da série de Fibonacci.”””

if n < 2:

return n

return fib(n-1) + fib(n-2)

 

print(fib(8))

 

■ Programa 7.3: Cálculo do n-ésimo termo da série de

Fibonacci (Nova versão).

 

Nessa última versão, além de testar se o número é menor que 2,

em vez de fazer dois testes, também foi simplificado o else, que não é necessário, pois a execução somente chega a esse ponto se o teste do if não for executado. De toda maneira, qualquer das opções não fará muita diferença em termos de desempenho. Você escolhe se quer usar a definição diretamente, ou fazer menos testes.

O Programa 7.4 acrescenta impressões da evolução do

programa para você acompanhar o que está acontecendo.

def fib(n):

“““Calcula n-

ésimo termo da série de Fibonacci.”””

print(‘Função chamada com’,n);

if n < 2:

print(‘Retornando’,n)

return n

resul = fib(n-1) + fib(n-2)

print(‘Retornando soma’,resul);

return resul

 

print(‘fib(4) :’,fib(4))

■ Programa 7.4: Cálculo do n-ésimo termo da série de

Fibonacci com impressão dos passos.

 

O resultado é:

Função chamada com 4

Função chamada com 3

Função chamada com 2

Função chamada com 1

Retornando 1

Função chamada com 0

Retornando 0

Retornando soma 1

Função chamada com 1

Retornando 1

Retornando soma 2

Função chamada com 2

Função chamada com 1

Retornando 1

Função chamada com 0

Retornando 0

Retornando soma 1

Retornando soma 3

3

Repare que há 9 chamadas à função. Deve haver, consequentemente, 9 retornos. Cada chamada salva seu estado na pilha e cada retorno tira o estado da função da pilha.

 

EXERCÍCIO 7.4

 

Escreva uma função que calcule o fatorial de um número. O fatorial pode ser

de nido como: