Qual é o limite da recursão?

O que é recursão?

Exemplo de uma imagem dentro dela mesma, recursão infinita

Em resumo, recursão é o processo de se autorreferenciar. Um exemplo disso seria um espelho apontado para outro.

A recursão é utilizada em vários meios, desde o design até na linguística

Na programação a recursividade é utilizada para otimizar algumas soluções de problemas.

Como esse não é o intuito do post, não vou me aprofundar na definição de recursão.

Causos da minha vida

Recentemente eu participei da XXIV Maratona de programação e lá me deparei com alguns problemas cujo o tamanho da entrada a se calcular poderia ser até 1 000 000 000 (1 Bilhão)

Logo me lembrei das aulas de programação e das maravilhas da recursividade, mas… Sera que meu humilde Python da conta?

Spoiler: Não

Mas… POR QUE???

Na programação um código recursivo chama ele mesmo até que atinja uma condição de parada.

Exemplo:

def fibonacci(n):
  if n < 2: 
    return 1

  return self.calc(n-1) + self.calc(n-2)

Nesse caso a condição de parada é “if n < 2”

Então o quanto maior for o n mais vezes a recursão vai ser aberta e vale lembrar que isso gera um apontamento na memoria do computador

Então mesmo sendo rápido, a recursividade começa a se tornar custosa para o computador

E é claro que eu não ia perder a oportunidade de destrinchar ao máximo os limites disso :v

Demonstração

Todos os códigos estão no meu repositório no GitHub https://github.com/MatheusMuriel/ProgramacaoDinamica (Alias segue eu la <3)

Existe a sequencia de Fibonacci, um numero de fibonacci é igual a soma dos dois números anteriores.

Um caso perfeito para recursão.

Então eu criei um algorítimo puramente recursivo e fiz um benchmark de seus tempos.

Ok, está rápido, mas quando vc chega perto do 50, esse algoritmo já não funciona mais.

Erro de limite de recursão do Python
(Jaja eu falo mais sobre ele)

Uma forcinha pra recursão

Quando olhei isso eu lembrei das aulas de Inteligencia Artificial em que o professor mostrou uma técnica de programação dinâmica que evitava recalculo. Essa técnica se chamava Memoization

O memoization consiste em guardar os resultados de cada operação em uma tabela de memoria, assim quando vc precisar saber o resultado de fib(50) primeiro vc verifica na tabela se isso já foi calculado, se sim vc só consulta o valor na tabela, se não vc calcula e salva na tabela.

Combinado eu tbm aumentei o limite de recursão do python adicionando sys.setrecursionlimit(1000000000) no meu código

Assim a recursão acaba ficando mais rápida. Muito mais rápida. MUITO MAIS RÁPIDA.

Tão rápida que foi capaz de calcular o numero 16869 da sequencia de fibonacci em menos de 1 segundo

(Já não está mais cabendo na minha tela kkkk)

– E como vc sabe que isso ta certo em???

Boa pergunta! Eu validei pelo WolframAlpha

Mas nessa vida nem tudo são flores.

A partir de um valor muito grande a recursão é aberta tanto que esgota os endereços de memoria no computador e o computador mata o processo

Grrrr

E agora Muriel???

Calma lá, ainda tem mais.

(como se 16869 não fosse um numero estupidamente grande )

As vezes é preciso abrir mão

Sim sim, a recursão é muito legal, maravilhosa, fácil de entender e programar… Mas chega uma hora que é preciso esquecer os velhos conhecimentos, aqui estamos entrando no submundo da programação extrema.

Ok, memoria é um problema.

E se ao invés de guardar todos os resultados na tabela de memoria a gente limpar os resultados que não são muito usados?

Mas mesmo assim a recursão vai abrir muito e esgotar a memoria

Assim, podemos fazer um forzão raiz e partir pro abraço

Assim eu fiz, eu mantive a estrutura principal do calculo em um for e os cálculos de valores específicos dentro de um algorítimo recursivo

E até onde ele chegou?

Ate o 400000º (400 Mil) numero de Fibonacci

(Pensa em um cara que ficou feliz quando viu esse resultado)

Pra calcular isso o código demorou aproximadamente 3,26 Minutos

E é isso… Agora estou pensando em uma nova abordagem para calcular um numero ainda maior

FOCO NO 1 MILHÃO

Assim que eu tiver mais resultados eu posto aqui.

Se quiser testar em seu próprio computador basta clonar meu repositório no GitHub instalar as bibliotecas do requirements.txt e ser feliz.

Se eu tiver falado algo errado e vc tiver alguma correção sintase a vontade para comentar ou entrar em contato comigo.

Publicado por Matheus Muriel

Homo sapiens, Programador, Estudante de Ciência da Computação, Pai de gatos, Musico e Motociclista

Deixe um comentário

Crie um site como este com o WordPress.com
Comece agora