O (N log N) Complejidad-Similar a lineal?


Así que creo que voy a ser enterrado por hacer una pregunta tan trivial, pero estoy un poco confundido acerca de algo.

He implementado quicksort en Java y C y estaba haciendo algunas comparaciones básicas. El gráfico salió como dos líneas rectas, con la C siendo 4ms más rápido que la contraparte de Java sobre 100,000 enteros aleatorios.

Resultado

El código para mis pruebas se puede encontrar aquí;

Android-benchmarks

No estaba seguro de lo que an (n log n) la línea se vería así, pero no pensé que sería recta. Solo quería comprobar que este es el resultado esperado y que no debería tratar de encontrar un error en mi código.

Metí la fórmula en excel y para la base 10 parece ser una línea recta con una torcedura al principio. ¿Es esto porque la diferencia entre log(n) y log(n+1) aumenta linealmente?

Gracias,

Gav

Author: Community, 2009-06-07

7 answers

Haz el gráfico más grande y verás que O(n logn) no es una línea recta. Pero sí, está bastante cerca del comportamiento lineal. Para ver por qué, basta con tomar el logaritmo de unos pocos números muy grandes.

Por ejemplo (base 10):

log(1000000) = 6
log(1000000000) = 9
…

Por lo tanto, para ordenar 1.000.000 números, una ordenación O(n logn) agrega un mísero factor 6 (o solo un poco más, ya que la mayoría de los algoritmos de ordenación dependerán de logaritmos de base 2). No mucho.

De hecho, este factor logarítmico es así que extraordinariamente pequeño que para la mayoría de los órdenes de magnitud, los algoritmos O(n logn) establecidos superan a los algoritmos de tiempo lineal. Un ejemplo destacado es la creación de una estructura de datos de matriz de sufijos.

Un caso simple me ha mordido recientemente cuando traté de mejorar una clasificación quicksort de cadenas cortas mediante el empleo de radix sort. Resulta que, para cuerdas cortas, este tipo de radix (tiempo lineal) era más rápido que quicksort, pero había un punto de inflexión para cuerdas aún relativamente cortas, ya que radix sort depende crucialmente de la longitud de las cuerdas que clasifiques.

 76
Author: Konrad Rudolph,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2017-05-23 12:34:12

Para su información, quicksort es en realidad O (n^2), pero con un caso promedio de O(nlogn)

Para su información, hay una diferencia bastante grande entre O(n) y O(nlogn). Es por eso que no es enlazable por O(n) para cualquier constante.

Para una demostración gráfica ver:

O (n) vs O (nlogn)

 11
Author: groundhog,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2014-12-22 14:48:58

Para aún más diversión en una vena similar, intente trazar el tiempo tomado por n operaciones en el estándar disjoint set data structure. Se ha demostrado para ser asintóticamente n α(n) donde α(n) es la inversa de la Ackermann función (a pesar de su habitual algoritmos de libros de texto probablemente sólo mostrar un límite de n log log n o, posiblemente, n registro de* n). Para cualquier tipo de número que usted será probable para encontrar como tamaño de entrada, α (n) ≤ 5 (y de hecho log* n ≤ 5), aunque se acerca al infinito asintóticamente.

Lo que supongo que se puede aprender de esto es que si bien la complejidad asintótica es una herramienta muy útil para pensar en algoritmos, no es exactamente lo mismo que la eficiencia práctica.

 5
Author: Jouni K. Seppänen,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2009-06-08 05:35:50
  1. Normalmente los algoritmos O( n*log(n) ) tienen una implementación logarítmica de 2 bases.
  2. Para n = 1024, log(1024) = 10, por lo que n*log(n) = 1024*10 = 10240 cálculos, un aumento en un orden de magnitud.

Entonces, O(n*log(n)) es similar a lineal solo para una pequeña cantidad de datos.

Consejo: no olvides que quicksort se comporta muy bien en datos aleatorios y que no es un algoritmo O(n*log(n)).

 3
Author: Nick Dandoulakis,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2015-11-19 08:33:37

Cualquier dato se puede trazar en una línea si los ejes se eligen correctamente: -)

Wikipedia dice que Big-O es el peor caso(es decir, f(x) es O(N) significa que f (x) está "delimitado por encima" por N) https://en.wikipedia.org/wiki/Big_O_notation

Aquí hay un buen conjunto de gráficos que representan las diferencias entre varias funciones comunes: http://science.slc.edu / ~jmarshall / courses / 2002 / spring / cs50 / BigO /

La derivada de log (x) es 1 / x. Esta es la rapidez con la que log (x) aumenta como x aumentar. No es lineal, aunque puede parecer una línea recta porque se dobla muy lentamente. Cuando pienso en O (log (n)), pienso en ella como O(N^0+), es decir, la potencia más pequeña de N que no es una constante, ya que cualquier potencia constante positiva de N la superará eventualmente. No es 100% exacto, así que los profesores se enojarán contigo si lo explicas de esa manera.

La diferencia entre los registros de dos bases diferentes es un multiplicador constante. Busque la fórmula para convertir registros entre dos base: (bajo "cambio de base" aquí: https://en.wikipedia.org/wiki/Logarithm ) El truco es tratar k y b como constantes.

En la práctica, normalmente va a haber algunos contratiempos en cualquier dato que trace. Habrá diferencias en las cosas fuera de su programa (algo que se intercambia en la cpu antes de su programa, errores de caché, etc.). Se necesitan muchas carreras para obtener datos confiables. Las constantes son el mayor enemigo de tratar de aplicar la notación Big O al tiempo de ejecución real. An O (N) el algoritmo con una constante alta puede ser más lento que un algoritmo O(N^2) para N.

 2
Author: nobodyImportant,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2013-06-17 23:19:48

Log (N) es (muy) aproximadamente el número de dígitos en N. Por lo tanto, en su mayor parte, hay poca diferencia entre log(n) y log(n+1)

 1
Author: James Curran,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2009-06-07 19:05:35

Intente trazar una línea lineal real encima de ella y verá el pequeño aumento. Tenga en cuenta que el valor Y en 50,0000 es menor que el valor 1/2 Y en 100,000.

Está ahí, pero es pequeño. Por eso O(nlog(n)) es tan bueno!

 0
Author: Chris Harris,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2009-06-07 19:06:04