Por favor, explique este código simples:
public int fibonacci(int n) {
if(n == 0)
return 0;
else if(n == 1)
return 1;
else
return fibonacci(n - 1) + fibonacci(n - 2);
}
Estou confuso com a última linha, especialmente porque se n = 5, por exemplo, então fibonacci (4) + fibonacci (3) seriam chamados e assim por diante, mas eu não entendo como esse algoritmo calcula o valor no índice 5 por este método. Por favor, explique com muitos detalhes!
Respostas:
Na sequência de fibonacci, cada item é a soma dos dois anteriores. Então, você escreveu um algoritmo recursivo.
Assim,
Agora você já sabe
fibonacci(1)==1 and fibonacci(0) == 0
. Portanto, você pode calcular posteriormente os outros valores.Agora,
E a partir da sequência de fibonacci
0,1,1,2,3,5,8,13,21....
, podemos ver que, para5th element
a sequência de fibonacci, retorna5
.Veja aqui o Tutorial de Recursão .
fonte
Existem 2 problemas com o seu código:
O código
fibonacci(n - 1) + fibonacci(n - 2)
está muito errado.
O problema é que ele chama de fibonacci não 50 vezes, mas muito mais.
Inicialmente, chama fibonacci (49) + fibonacci (48),
próximo fibonacci (48) + fibonacci (47) e fibonacci (47) + fibonacci (46)
Cada vez que se torna pior, a complexidade é exponencial.
A abordagem do código não recursivo:
fonte
2*fibonacci(n+1)-1
, portanto, ele cresce com a mesma complexidade dos números de fibonacci, que é 1.618 ^ n em vez de 2 ^ nNo pseudo-código, onde n = 5, ocorre o seguinte:
Isso se divide em:
Isso se divide em:
Isso se divide em:
Isso se divide em:
Isto resulta em: 5
Dada a sequência de fibonnacci é 1 1 2 3 5 8 ... , o quinto elemento é 5. Você pode usar a mesma metodologia para descobrir as outras iterações.
fonte
A recursão pode ser difícil de entender algumas vezes. Apenas avalie-o em um pedaço de papel para um número pequeno:
Não tenho certeza de como o Java realmente avalia isso, mas o resultado será o mesmo.
fonte
Você também pode simplificar sua função, da seguinte maneira:
fonte
Um ponto importante a ser observado é que esse algoritmo é exponencial porque não armazena o resultado de números calculados anteriores. por exemplo, F (n-3) é chamado 3 vezes.
Para mais detalhes, consulte o algoritmo do capítulo 0.2 dasgupta
fonte
A maioria das respostas é boa e explica como funciona a recursão em fibonacci.
Aqui está uma análise sobre as três técnicas que também incluem recursão:
Aqui está o meu código para testar todos os três:
Aqui estão os resultados:
Portanto, podemos ver que a memorização é a melhor opção em termos de tempo e que o loop for corresponde de perto.
Mas a recursão leva mais tempo e pode ser que você deva evitar na vida real. Além disso, se você estiver usando recursão, certifique-se de otimizar a solução.
fonte
Este é o melhor vídeo que eu descobri que explica completamente a recursão e a sequência de Fibonacci em Java.
http://www.youtube.com/watch?v=dsmBRUCzS7k
Este é o código para a sequência e sua explicação é melhor do que eu jamais poderia tentar digitar.
fonte
Para uma solução recursiva de fibonacci, é importante salvar a saída de números menores de fibonacci, enquanto recupera o valor de um número maior. Isso é chamado de "Memoizing".
Aqui está um código que usa a memorização dos valores menores de fibonacci, enquanto recupera um número maior de fibonacci. Esse código é eficiente e não faz várias solicitações da mesma função.
fonte
na sequência de fibonacci , os dois primeiros itens são 0 e 1; o outro item é a soma dos dois itens anteriores. ou seja:
0 1 1 2 3 5 8 ...
portanto, o quinto item é a soma do quarto e do terceiro itens.
fonte
Michael Goodrich e cols. Fornecem um algoritmo realmente inteligente em estruturas de dados e algoritmos em Java, para resolver fibonacci recursivamente em tempo linear, retornando uma matriz de [fib (n), fib (n-1)].
Isso produz fib (n) = fibGood (n) [0].
fonte
Aqui está a solução O (1):
Fórmula de número de Fibonacci da Binet usada para implementação acima. Para entradas grandes,
long
pode ser substituído porBigDecimal
.fonte
Uma sequência de Fibbonacci é aquela que soma o resultado de um número quando adicionada ao resultado anterior, começando com 1.
Depois de entendermos o que é Fibbonacci, podemos começar a decompor o código.
A primeira, se a declaração procurar um caso base, onde o loop pode ocorrer. A declaração else if abaixo está fazendo o mesmo, mas pode ser reescrita dessa maneira ...
Agora que um caso base é estabelecido, precisamos entender a pilha de chamadas. Sua primeira chamada para "fibonacci" será a última a ser resolvida na pilha (sequência de chamadas), conforme elas serão resolvidas na ordem inversa da qual foram chamadas. O último método chamado resolve primeiro, depois o último a ser chamado antes desse e assim por diante ...
Portanto, todas as chamadas são feitas primeiro antes que qualquer coisa seja "calculada" com esses resultados. Com uma entrada de 8, esperamos uma saída de 21 (veja a tabela acima).
fibonacci (n - 1) continua sendo chamado até atingir o caso base, então fibonacci (n - 2) é chamado até atingir o caso base. Quando a pilha começar a somar o resultado na ordem inversa, o resultado será mais ou menos assim ...
Eles continuam borbulhando (resolvendo para trás) até que a soma correta seja retornada à primeira chamada na pilha e é assim que você obtém sua resposta.
Dito isto, esse algoritmo é muito ineficiente porque calcula o mesmo resultado para cada ramificação em que o código é dividido. Uma abordagem muito melhor é uma abordagem "de baixo para cima", em que não é necessária nenhuma memorização (cache) ou recursão (pilha profunda de chamadas).
Igual a...
fonte
A maioria das soluções oferecidas aqui é executada com complexidade O (2 ^ n). Recalcular nós idênticos na árvore recursiva é ineficiente e desperdiça ciclos da CPU.
Podemos usar a memorização para executar a função fibonacci em O (n) time
Se seguirmos a rota de programação dinâmica Bottom-Up, o código abaixo é simples o suficiente para calcular fibonacci:
fonte
Por que essa resposta é diferente
Todas as outras respostas também:
(à parte: nada disso é realmente eficiente; use a fórmula de Binet para calcular diretamente a enésima termo)
Fibra recursiva da cauda
Aqui está uma abordagem recursiva que evita uma chamada dupla recursiva, passando a resposta anterior E a anterior.
fonte
É uma sequência básica que exibe ou obtém uma saída de 1 1 2 3 5 8; é uma sequência em que a soma do número anterior, o número atual, será exibida a seguir.
Tente assistir ao link abaixo da sequência Java Recursive Fibonacci Tutorial
Clique aqui Assista a sequência de Fibonacci recursiva Java Tutorial para alimentação com colher
fonte
Eu acho que é uma maneira simples:
fonte
A resposta RanRag (aceita) funcionará bem, mas essa não é a solução otimizada até e a menos que seja memorizada conforme explicado na resposta Anil.
Para uma abordagem recursiva a seguir, as chamadas de método
TestFibonacci
são mínimasfonte
fonte
Usando um ConcurrentHashMap interno que teoricamente pode permitir que essa implementação recursiva opere corretamente em um ambiente multithread, implementei uma função fib que usa o BigInteger e o Recursion. Demora cerca de 53ms para calcular os primeiros 100 números de fib.
O código de teste é:
fonte
Aqui está um recursivo de uma linha de febonacci:
fonte
Tente isto
fonte
Apenas para complementar, se você quiser calcular números maiores, use o BigInteger.
Um exemplo iterativo.
fonte
http://en.wikipedia.org/wiki/Fibonacci_number em mais detalhes
Faça com que seja tão simples quanto necessário, sem necessidade de usar o loop while e outro loop
fonte
fonte
Use
while
:A vantagem desta solução é que é fácil ler e entender o código, esperando que ajude
fonte
Uma sequência de Fibbonacci é aquela que soma o resultado de um número e, em seguida, adicionamos ao resultado anterior, devemos começar a partir de 1. Eu estava tentando encontrar uma solução baseada em algoritmo, então construo o código recursivo, notei que mantenho o número anterior e eu mudei de posição. Estou pesquisando a sequência de Fibbonacci de 1 a 15.
fonte
fonte
Fibonacci simples
fonte
@chro está no local, mas ele não mostra a maneira correta de fazer isso recursivamente. Aqui está a solução:
fonte