¿Cuál es la complejidad temporal de un programa que calcula el número n de Fibonacci mediante la memorización?

Eso depende. Aquí hay tres respuestas diferentes.

La respuesta técnicamente correcta:

El programa (como se publica actualmente en los detalles de la pregunta) se ejecuta en tiempo constante porque solo declara la función fib pero nunca la llama.

Como dicen, “técnicamente correcto es el mejor tipo de correcto!” 🙂

Aún así, la respuesta anterior claramente no es lo que quería escuchar. Por lo tanto, para el resto de mi respuesta, supongo que agregamos una llamada real de la función recursiva. Por ejemplo, print( fib( int(input()) ) ) .

La respuesta general:

La parte que debería ser fácil de observar es que si ejecutamos el programa en la entrada x , ejecutará los pasos lógicos [math] \ Theta (x) [/ math]. Más precisamente, está claro que la línea memo[n] = fib(n-1) + fib(n-2) se ejecutará exactamente x- 1 veces: una vez para cada entrada de 2 a x . Por lo tanto, el número total de llamadas a funciones es lineal en x . Esa es nuestra segunda respuesta: el programa realiza pasos lógicos [matemáticos] \ Theta (x) [/ matemáticos].

La respuesta donde los detalles de implementación son importantes:

Ahora para la tercera respuesta. Claro, solo realizamos adiciones x -1. Pero, ¿es correcto afirmar que el programa se ejecuta en tiempo lineal? Realmente no.

El problema es que los números de Fibonacci crecen exponencialmente. Esto significa que los números superarán muy rápidamente el tamaño de una palabra de máquina, y más allá de ese punto, no podemos afirmar realmente que podemos agregar dos números en tiempo constante. En cambio, el tiempo necesario para sumar dos números grandes es proporcional al número de dígitos del resultado.

Por lo tanto, el tiempo total de ejecución de nuestro programa es proporcional al número total de dígitos en [math] F_2, F_3, \ dots, F_x [/ math].

El i -ésimo número de Fibonacci es proporcional a [matemática] \ phi ^ i [/ matemática], donde [matemática] \ phi = (1+ \ sqrt {5}) / 2 [/ matemática] es la proporción áurea. Por lo tanto, el número de dígitos en [math] F_i [/ ​​math] es proporcional a i. Por lo tanto, el número total de dígitos en [matemáticas] F_2, F_3, \ puntos, F_x [/ matemáticas] es cuadrático en x .

Así que esa es nuestra respuesta final: para calcular el número x de Fibonacci, la recursión memorizada debe realizar [matemáticas] \ Theta (x ^ 2) [/ matemáticas] pasos elementales de cálculo.

También tenga en cuenta que el programa realmente almacena todos los valores intermedios en el diccionario. Por lo tanto, si lo usa para calcular fib(x) , consumirá [math] \ Theta (x ^ 2) [/ math] bytes de memoria. Ese será el principal cuello de botella en la práctica.

[matemáticas] \ theta (n) [/ matemáticas]

Consideremos cuántas veces se llamará a la función fib (i) para un argumento dado [math] i [/ math]. Solo puede suceder en dos casos:

– cuando fib (i + 1) entra en la fase “memo [n] = …”

– cuando fib (i + 2) entra en la fase “memo [n] = …”.

Para cualquier argumento dado, la función (no importa cuántas veces se llame con este argumento) entrará en esta fase solo una vez. Por lo tanto, fib (i) puede llamarse (como máximo) 2 veces para cualquier i dado, por lo que hay como máximo 2n llamadas, y cada una de esas llamadas toma O (1). Entonces, es la misma complejidad que habría tenido contar los números de Fibonacci en un ciclo.

Es [matemáticas] \ Theta (n ^ 2) [/ matemáticas] porque estás caminando por un árbol binario.

More Interesting

¿Existe un equivalente al tono perfecto en matemáticas / programación de computadoras? ¿Un atributo que se considera que no se puede aprender pero que es invaluable si lo posee?

¿Cuáles son algunos de los nuevos campos en la informática teórica?

¿Cómo hago para hacer investigación de pregrado en CS?

¿Cómo se puede determinar la coincidencia más cercana de un vector dado entre un conjunto de vectores si el origen de los vectores también es importante?

¿Qué es una explicación intuitiva de los teoremas de jerarquía y sus pruebas en la teoría de la complejidad computacional?

¿Podría la funcionalidad de una computadora digital ser duplicada por una computadora mecánica (con engranajes, ruedas, palancas, etc.)?

¿Cuál es una explicación para esta ecuación de números de punto fijo con signo?

Estoy interesado en la robótica. ¿Debo aprender matemáticas si quiero ser programador?

Si tuviera la oportunidad de rediseñar el programa de cuatro años de Ciencias de la Computación de su universidad, entonces, ¿qué programa diseñaría?

Cuando los matemáticos desarrollan algoritmos, ¿están haciendo informática?

¿Cuáles son algunos conceptos en el cálculo lambda que es bueno saber antes de aprender programación funcional?

¿La operación Bitwise es importante en Python? Estoy aprendiendo esta parte en Codecademy y no entendí totalmente. ¿Qué es Base 2 y Base 10?

¿Existe algún modelo de cálculo X más débil que una máquina de Turing (pero aún no trivial) para el cual una máquina de Turing puede predecir el comportamiento de detención?

¿Qué tipo de matemáticas debo estudiar para comprender mejor la teoría detrás de la programación?

Matemática discreta: ¿Cuál es la diferencia entre ser un elemento de un conjunto o ser un subconjunto de un conjunto?