¿Cómo analizaría la complejidad temporal de fibbonacci?

Los números de Fibonacci son simplemente una suma de los dos números de Fibonacci anteriores dado que fib (0) y fib (1) = 1.

Si me piden que escriba un programa para producir términos de Fibonacci, haría lo siguiente:

fib (n)
si n = 1 o 2
volver 1
más
retorno fib (n-1) + fib (n-2)

Como puede ver, ¡el método “o función” contiene llamadas recursivas a sí mismo! Por lo tanto, se llama un método recursivo !

Para analizar cualquier método recursivo, debemos encontrar su relación de recurrencia y resolverla. Resolver la recurrencia es escribirla en su forma cerrada deshaciéndose de las llamadas recursivas. Recuerde que cualquier relación de recurrencia debe incluir llamadas a sí misma y puede incluir algunas otras operaciones. Sin embargo, nuestra recurrencia en este ejemplo incluye solo llamadas recursivas.

La recurrencia del método sería:

[matemáticas] F_n = 1 [/ matemáticas] si n = 0

[matemáticas] F_n = 1 [/ matemáticas] si n = 1

[matemáticas] F_n = F (n-1) + F (n-2) [/ matemáticas] si n> 1

Afortunadamente, este tipo de recurrencias se llama recurrencia lineal. Una recurrencia lineal La ecuación de grado k u orden k es una ecuación de recurrencia que tiene el formato [matemáticas] x_n = A_1x_ {n − 1} + A_2x_ {n − 2} + A_3x_ {n − 3} +… A_kx_ {n − k} (A_n [/ matemáticas] es una constante y [matemáticas] A_k ≠ 0) . [/ math] Su solución es la solución de su ecuación polinómica. Podemos convertirlo a su ecuación polinómica de la siguiente manera:

  • cada [matemática] F (n) [/ matemática] se convierte en [matemática] x ^ k [/ matemática] donde k es (el número de términos -1) en la ecuación.
  • [math] F (n-1) [/ math] podría convertirse en [math] x ^ {k-1} [/ math] y así sucesivamente. El último término se eleva a la potencia de 0 “[matemática] k = 0 [/ matemática]”.
  • cada constante aparece en la recurrencia también debería aparecer en la ecuación polinómica.

Según las afirmaciones anteriores: la recurrencia de Fibonacci podría convertirse a la siguiente ecuación cuadrática:

[matemáticas] x ^ 2 = x ^ 1 +1 [/ matemáticas].

Resolver la ecuación es un poco fácil. Llegaremos a la misma solución dada por Kevin Latimer que es 1.61803398875.

Por cierto, la solución a esta recurrencia se llama la proporción áurea . Tiene muchas aplicaciones. Será muy útil leer sobre esto en Wikipedia siguiendo este enlace

¡Espero que esto ayude!

Existen varios algoritmos diferentes para calcular el enésimo término de la secuencia de Fibonacci.

El primero es el método iterativo , en el que comienza con dos variables establecidas en 0 y 1 y aplica iterativamente la relación de recurrencia definitoria. Esto requiere que hagas n adiciones, y esas adiciones están en números que tienen, en promedio, dígitos [matemáticos] O (n) [/ matemáticos].

El segundo es usar la memorización para aplicar la relación de recurrencia de forma recursiva , comenzando con el enésimo término y trabajando hacia atrás. Esto es estrictamente peor que el método iterativo, ya que se deben calcular las mismas adiciones, pero se requiere mucha más memoria. No obstante, hay adiciones y búsquedas [matemáticas] O (n) [/ matemáticas] y el tamaño esperado de cada adición es [matemáticas] O (n) [/ matemáticas].

Dado que la complejidad de la suma es lineal en el número de dígitos agregados, está claro que ambos métodos son [matemática] O (n ^ 2) [/ matemática].

A continuación, tenemos la fórmula de Binet . La forma más rápida de usar este método es usar esta variante de la fórmula:

[matemática] F_n = \ text {round} (\ frac {\ phi ^ n} {2 \ phi-1}) [/ math].

Para usarlo, debemos hacer dos cosas:

  • Calcule [math] \ phi [/ math] con una precisión suficiente.
  • Elevarlo a la enésima potencia.

El resto del cálculo son solo operaciones simples en los números resultantes, cada una de las cuales requiere tiempo [matemático] O (n) [/ matemático], por lo que los pasos anteriores requieren la mayor parte del tiempo.

Calcular [matemática] \ phi [/ matemática] a los dígitos [matemáticos] O (n) [/ matemáticos] requeridos requiere [matemática] O (M (\ gamma n)) [/ matemática] usando el método de Newton, donde [matemática ] M (n) [/ math] representa la complejidad temporal de la multiplicación y [math] \ gamma n [/ math] representa el número de dígitos en [math] F_n [/ math]. ([matemáticas] \ gamma \ aproximadamente 0.69424 [/ matemáticas])

Elevar un número de dígito [matemático] O (\ gamma n) [/ matemático] a la enésima potencia requiere tiempo [matemático] O (M (\ gamma n)) [/ matemático] si utiliza los métodos más rápidos. Este es claramente el paso que llevará más tiempo.

Ahora, hay muchos algoritmos de multiplicación, pero todos toman tiempo [math] O (n ^ k) [/ math] para algunos [math] k> 1 [/ math]. Por lo tanto, la fórmula de Binet requiere tiempo [matemático] O (n ^ {k}) [/ matemático].

En la práctica, al usar la fórmula de Binet en entradas lo suficientemente pequeñas como para que no tenga sentido usar los sofisticados algoritmos de multiplicación, tiende a ser aproximadamente cinco veces más lento que usar el método entero iterativo anterior.

Por último, tenemos el producto rápido de los números de Lucas utilizando el algoritmo de cuadratura repetida .

Esto usa las recurrencias:

[matemáticas] F_ {k + 1} = \ frac {F_k + L_k} 2 [/ matemáticas]

[matemáticas] L_ {k + 1} = F_ {k + 1} + 2F_k [/ matemáticas]

[matemáticas] F_ {2k} = 2F_ {k + 1} ^ 2-3F_k ^ 2-2 (-1) ^ k [/ matemáticas]

[matemáticas] L_ {2k} = 5F_k ^ 2 + 2 (-1) ^ k [/ matemáticas]

La aplicación de estas identidades para llegar a [math] F_n [/ math] de la manera más rápida posible requiere solo [math] O (\ log (n)) [/ math] aplicaciones de las recurrencias, y toma [math] O (M (\ gamma n)) [/ math] operaciones de bit (con una constante muy pequeña). Esto es mucho más rápido que cualquiera de los métodos descritos anteriormente. Puede encontrar una implementación de pseudocódigo de este algoritmo en este documento: http://www.ii.uni.wroc.pl/~lorys

Fibonacci (n) requiere poco más que tiempo lineal … si sabes cómo.

Supongo que te refieres a la complejidad temporal para calcular el término [matemático] n ^ {th} [/ matemático] de la secuencia de Fibonacci.

Esto es lo que quien le hizo esta pregunta quiere que diga: que es [matemática] O (n) [/ matemática] porque para calcular la [matemática] n ^ {th} [/ matemática] debe calcular la [matemática] n -1 [/ math] términos antes de él. Pero esto está mal .

La relación de Fibonacci, que doy formalmente como

[matemática] F_n = F_ {n-1} + F_ {n-2} [/ matemática] con [matemática] F_0 = F_1 = 1 [/ matemática]

tiene una solución de forma cerrada de la siguiente manera:

[matemáticas] F_n = \ frac {\ phi ^ n – \ psi ^ n} {\ sqrt {5}} [/ matemáticas]

donde [matemáticas] \ phi = \ frac {1 + \ sqrt {5}} {2} [/ matemáticas] y [matemáticas] \ psi = \ frac {1 – \ sqrt {5}} {2} [/ matemáticas] .

Esto se llama fórmula de Binet y aquí se escribe una expresión equivalente [1]. Es [matemática] O (1) [/ matemática] con respecto al número de términos [matemática] n [/ matemática].

Notas al pie

[1] Fórmula del número de Fibonacci de Binet

More Interesting

¿Qué algoritmos se pueden usar para determinar si dos preguntas (como las de Quora) son de alguna manera similares?

¿Son los problemas NP completos también problemas NP difíciles? ¿Por qué?

¿Hay alguien que enseñe estructuras de datos y algoritmos aquí en Hyderabad?

¿Cómo funciona Junglee?

¿Por qué los problemas NP completos son más difíciles que los problemas NP si un problema NP puede reducirse a un problema NP completo?

Cómo aprender algoritmos y programación competitiva de manera rápida y efectiva cuando te estás haciendo viejo

¿Qué es un buen libro sobre las estructuras de datos de Java?

¿Cuál es el código más elegante que puede escribir en su lenguaje de programación favorito que imprima los números del 100 al 200?

Quiero usar una cola prioritaria en un problema. Creo que implementar una cola prioritaria usando una matriz es más fácil que usar un montón. ¿Qué piensas y por qué?

¿Cuál es el mejor algoritmo de búsqueda en programación?

¿Cómo se puede probar que la ruta única a través de un árbol de expansión mínima entre dos nodos es una ruta más corta de "cuello de botella"?

Cómo comenzar a aprender algoritmos de reconocimiento de voz

¿Qué representación gráfica es mejor para la programación competitiva en C ++: lista de adyacencia o matriz de adyacencia?

Cómo contar inversiones divididas con el algoritmo de clasificación de fusión

¿Puedes pensar en dos situaciones en las que usarías listas vinculadas?