Estoy acostumbrado a buscar la notación de Landau (Big O, Theta ...) de mis algoritmos a mano para asegurarme de que estén tan optimizados como sea posible, pero cuando las funciones se vuelven realmente grandes y complejas, está tomando forma demasiado tiempo para hacerlo a mano. También es propenso a errores humanos.
Pasé un tiempo en Codility (ejercicios de codificación / algo), y noté que le darán la notación de Landau para su solución presentada (tanto en el uso del tiempo como de la memoria).
Me preguntaba cómo lo hacen ... ¿Cómo lo harías?
¿Hay otra forma además del análisis léxico o el análisis del código?
Esta pregunta se refiere principalmente a PHP y / o JavaScript, pero estoy abierto a cualquier lenguaje y teoría.
algorithms
complexity
big-o
static-analysis
big-theta
Julien L
fuente
fuente
Respuestas:
Me imagino que en realidad están estimando las medidas Big O ... ejecutando el programa para diferentes tamaños de problemas, midiendo el tiempo y el uso del espacio, y ajustando curvas a los resultados.
El problema con este enfoque es que puede equivocarse si las funciones de costo cambian de forma a medida que N aumenta; por ej
1000 N + N^1.5
.El análisis léxico y el análisis no son suficientes. También debe razonar sobre el comportamiento del algoritmo. Y hacer eso automáticamente para un algoritmo previamente desconocido es difícil.
fuente
No pueden sin analizar el código.
Los ejemplos a continuación con "inflación / deflación" artificial de complejidad prueban que simplemente medir el tiempo de ejecución del programa no es suficiente para estimar confiablemente Big-O
La estimación del tiempo de ejecución para lo anterior sería susceptible de dar estimaciones falsas: tiempo constante para valores de
n
donde hay una solución precalculada y tiempo cúbico para valores dondeunfair slow-down
entra en acción, en lugar del tiempo cuadrático "justo".fuente
Creo que esto no es posible.
Si ejecuta algunas pruebas con un número fijo de diferentes tamaños de entrada, puede calcular fácilmente un polinomio, que se aproximará a los tiempos de ejecución que ha medido muy bien. Entonces terminas con un polinomio para cada programa posible, lo que significaría
P = NP
(¡sí!;)).Si intentas hacerlo con manipulación simbólica, terminas en el
halting problem
. Como no puede decidir si su programa se detendrá, no puede decidir qué complejidad de tiempo de ejecución tendrá.Sin embargo, puede haber casos muy especiales, donde el método posterior es posible. Pero estos casos pueden ser tan pequeños, que es cuestionable si alguna vez se paga el esfuerzo.
fuente
¿Cómo lo haría? La forma en que resuelvo casi cualquier problema no quiero sentarme y resolver . Simulo
Para muchos problemas, puede ser suficiente ejecutar su algoritmo muchas veces usando una variedad de tamaños y luego ajustar una curva de regresión a esos resultados. Eso identificaría rápidamente algunos costos generales "fijos" particulares de su algoritmo (la intersección de la curva) y cómo se escala a medida que aumenta el tamaño de su problema.
Se necesitarán algunos ajustes para capturar soluciones particularmente complicadas, pero especialmente si solo está buscando una estimación aproximada, debería poder obtenerla de esa manera, y ver cómo su estimación difiere de sus resultados reales y decidir si es Una aproximación aceptable.
La mayor debilidad en mi mente con este método es que si su algoritmo se escala muy mal, ese paso inicial de "ejecutarlo un montón de veces" se volverá feo. Pero, francamente, ese es el caso, eso solo debería ser un indicador de que tal vez desee retroceder y reconsiderar las cosas.
fuente
Mi intuición es que una solución general a este problema es imposible; afirmando, como lo hace, hechos a priori sobre el tiempo de ejecución de los algoritmos sin ejecutarlos (alude al análisis léxico). Dicho esto, es posible que algún algoritmo heurístico para una clase (probablemente grande) de algoritmos (ya que lo hacemos todo el tiempo), pero un algoritmo general para hacer esto sería equivalente a resolver el problema Entscheidungs que es bien sabido que no es posible (cf. Church, Turing, et al.). Estoy ~ 99.9% seguro de esto ahora que lo pienso ...
fuente