Cómo entender la notación big-O

El objetivo de la notación Big-O es describir cómo el espacio y el tiempo necesarios para ejecutar un algoritmo varía con el tamaño de entrada variable. La otra persona ya te ha dado la definición matemática. Entonces te daré una intuitiva. Le dan una idea sobre cómo se escala el algoritmo.

Consideremos un caso simple. Comparación de inserción y clasificación de fusión para entradas grandes. Sus complejidades temporales se describen como [matemáticas] O (N ^ 2) [/ matemáticas] y [matemáticas] O (N \ log N) [/ matemáticas] respectivamente. ¿Qué quieren decir?

Considere ordenar una matriz de [matemáticas] 10 ^ 6 [/ matemáticas] (un millón) enteros. (Ignore las constantes por un momento. Lo consideraré más adelante). Ahora, en el peor de los casos, necesita alrededor de [matemáticas] 10 ^ {12} [/ matemáticas] operaciones en caso de fusión, sería alrededor de [matemáticas] 2 \ multiplicado por 10 ^ 7 [/ math] operaciones.

Aumentemos el tamaño de la entrada y luego ejecutemos los algoritmos en ellos. Aumentemos el tamaño de la entrada en 10 veces. La ordenación por inserción necesita operaciones [matemática] 10 ^ {14} [/ matemática] y la fusión necesita alrededor de [matemática] 2.4 \ veces 10 ^ 8 [/ matemática] operaciones.

El número de operaciones necesarias aumentó alrededor de 12 veces en caso de una fusión. En caso de inserción, es alrededor de 100 veces. (Nota: Esto puede no ser exacto ya que depende de muchos factores. Pero el orden de cambio sigue siendo el mismo).

Esto es lo que te dice la notación Big-O. Así es como puede obtener una idea aproximada sobre cómo el algoritmo se escala al aumentar el tamaño de entrada. Pero eso no es todo. En muchas implementaciones de bibliotecas, las matrices pequeñas se ordenan por orden de inserción. ¿Por qué? Aquí es donde las constantes se vuelven importantes. Por lo tanto, una menor complejidad asintótica no significa necesariamente que el tiempo de ejecución sea mejor. En otras palabras, citando la respuesta de Paul Tardy, si [math] n_0 [/ math] es demasiado grande para ser práctico, probablemente sería mejor con el de mayor complejidad si es práctico.

Algunos problemas pueden resolverse con un enfoque diferente (algoritmos de solución múltiple). Y, es una buena práctica elegir el algoritmo más eficiente, es decir, el que puede ejecutar más rápido y necesita menos espacio de memoria en su ciclo de vida.

La eficiencia de un algoritmo puede decidirse por 2 factores:

  1. Factor de tiempo (Complejidad de tiempo), y
  2. Factor espacial (Complejidad espacial).

Usamos la notación asintótica para encontrar la complejidad del tiempo de ejecución de un algoritmo.

La notación Big-Oh es una notación asintótica utilizada para medir la complejidad del tiempo en el peor de los casos, es decir, la mayor cantidad de tiempo que un algoritmo puede tardar en completarse.

Para entender la notación Big-Oh, puede consultar este artículo -> Big-Oh: en términos simples.

Y luego, para dominar Big-Oh, creo que estas notas son suficientes -> notación big-oh: teoría y cálculo.

Imagina que quieres construir un producto. Este producto puede estar hecho de dos materias primas diferentes. Esos materiales no cuestan lo mismo, y el precio varía según la cantidad que desee comprar, es decir, podemos llamar respectivamente [math] n [/ math] la cantidad de material que desea y [math] f (n) [/ matemática] el costo del primer material, [matemática] g (n) [/ matemática] el costo del segundo material.

Su objetivo ahora como emprendedor es comprar el más barato (considerando que es de igual calidad, etc.). Por lo tanto, desea encontrar si [matemáticas] f (n)

Pero la cosa es que eres súper ambicioso. ¡Quieres un objetivo a largo plazo! Puedes imaginar que tal vez un material sea barato para volúmenes bajos, pero súper costoso entonces. Esto no es lo que quieres: ¡te enfocas en grandes volúmenes!

Esta es la idea detrás de la complejidad en la informática. En otras palabras, desea averiguar cuál tiende a ser más alto, cuando [matemáticas] n [/ matemáticas] tiende al infinito.

El concepto Big-O es que si “[matemáticas] f [/ matemáticas] es Big-O de [matemáticas] g [/ matemáticas]” significa que, un día (y todos los días siguientes) [matemáticas] f [/ matemáticas] será más barato que [matemáticas] g [/ matemáticas].

O en otras palabras, usando nuestro ejemplo:

Oh amigo, debes comprar el primer material (con función de costo [matemática] f [/ matemática]), porque tiende a ser más barato ([matemática] f (n) \ leq g (n) [/ matemática]) por alto volúmenes! ([matemáticas] n> n_0 [/ matemáticas])


Mirando la fórmula:

[matemáticas] f (n) = O (g (n)) => \ exist k> 0, \ exist n_0 \; \ forall n> n_0, \; f (n) \ leq g (n) \ cdot k [/ math]

Leemos: para dos funciones de costo [matemática] f (n) [/ matemática], [matemática] g (n) [/ matemática] con [matemática] n [/ matemática], un entero positivo, [matemática] g (n ) [/ math] es al menos [math] k [/ math] veces mayor que [math] f (n) [/ math] cuando [math] n> n_0. [/ math]

Espero que ayude 🙂