si n fuera un 1,000,000entonces
(n^2 + n) / 2 = 500000500000 (5.00001E+11)
(n^2) / 2 = 500000000000 (5E+11)
(n^2) = 1000000000000 (1E+12)
1000000000000.00 ¿qué?
Si bien la complejidad nos brinda una forma de predecir un costo en el mundo real (segundos o bytes dependiendo de si estamos hablando de la complejidad del tiempo o la complejidad del espacio), no nos da una cantidad de segundos ni ninguna otra unidad en particular.
Nos da un grado de proporción.
Si un algoritmo tiene que hacer algo n² veces, entonces tomará n² × c para un valor de c que es el tiempo que toma cada iteración.
Si un algoritmo tiene que hacer algo n² ÷ 2 veces, tomará n² × c para un valor de c que sea el doble del tiempo que toma cada iteración.
De cualquier manera, el tiempo empleado sigue siendo proporcional a n².
Ahora, estos factores constantes no son algo que podamos ignorar; de hecho, puede tener el caso en el que un algoritmo con complejidad O (n²) funciona mejor que uno con complejidad O (n), porque si estamos trabajando en un pequeño número de elementos, el impacto de los factores consistentes es mayor y puede abrumar otras preocupaciones . (De hecho, incluso O (n!) Es lo mismo que O (1) para valores suficientemente bajos de n).
Pero no son de lo que nos dice la complejidad.
En la práctica, hay algunas maneras diferentes en que podemos mejorar el rendimiento de un algoritmo:
- Mejore la eficiencia de cada iteración: O (n²) todavía se ejecuta en n² × c segundos, pero c es más pequeño.
- Reduzca el número de casos vistos: O (n²) todavía se ejecuta en n² × c segundos, pero n es más pequeño.
- Reemplace el algoritmo con uno que tenga los mismos resultados, pero de menor complejidad: por ejemplo, si pudiéramos volver a convertir algo O (n²) en algo O (n log n) y, por lo tanto, cambiar de n² × c₀ segundos a (n log n) × c₁ segundos .
O, para verlo de otra manera, tenemos f(n)×csegundos tomados y puede mejorar el rendimiento reduciendo c, reduciendo no reduciendo lo que fdevuelve un determinado n.
Lo primero que podemos hacer mediante algunas microopciones dentro de un bucle, o usando un mejor hardware. Siempre dará una mejora.
Lo segundo que podemos hacer es quizás identificando un caso en el que podamos cortocircuitar el algoritmo antes de que todo sea examinado, o filtrar algunos datos que no serán significativos. No dará una mejora si el costo de hacerlo supera la ganancia, pero generalmente será una mejora mayor que el primer caso, especialmente con una n grande.
El tercero lo podemos hacer usando un algoritmo completamente diferente. Un ejemplo clásico sería reemplazar una ordenación de burbujas con una clasificación rápida. Con un número bajo de elementos, podríamos haber empeorado las cosas (si c₁ es mayor que c₀), pero generalmente permite las mayores ganancias, especialmente con n muy grande.
En el uso práctico, las medidas de complejidad nos permiten razonar sobre las diferencias entre los algoritmos precisamente porque ignoran la cuestión de cómo ayudaría reducir nc, para concentrarnos en examinar f()
ncrece, tanto las funciones 'n ^ 2' como su función, se comportan de manera similar, hay una constante diferencia en su tasa de crecimiento. Si tiene una expresión compleja, la función que crece más rápido domina.