Complejidad logarítmica vs logarítmica doble

9

En las aplicaciones del mundo real, ¿hay un beneficio concreto al usar los algoritmos lugar de ?O(log(log(n))O(log(n))

Este es el caso cuando uno usa, por ejemplo, árboles de Van Emde Boas en lugar de implementaciones de árbol de búsqueda binaria más convencionales. Pero, por ejemplo, si tomamos , en el mejor de los casos, el algoritmo logarítmico doble supera al logarítmico en (aproximadamente) un factor de . Y también, en general, la implementación es más complicada y compleja.n<1065

Dado que personalmente prefiero BST a los árboles VEB, ¿qué te parece?

Se podría demostrar fácilmente que:

n<106. lognlog(log(n))<5.26146

Ghassen Hamrouni
fuente
básicamente, debe mirar las constantes involucradas en el algoritmo para un valor / tamaño de entrada más pequeño. Idealmente, nos gustaría que fueran pequeños.
singhsumit
3
Tenga en cuenta que ha habido un montón de mejoras desde los árboles VEB, lo que equivale a estructuras de datos en RAM con la complejidad de búsqueda / inserción / eliminación de sin aleatorización (determinista) y con aleatorización. Consulte Clasificación determinista en Tiempo y espacio lineal. por Han y Tiempo esperado y espacio lineal. por Han y Thorup. O(log log n)O(log log n)O(n log log n)O(log log n)
AL
En el mundo real, un factor de 5 es bastante significativo, y el número de elementos a menudo puede ser 10 ^ 9 o incluso 10 ^ 12.
RBarryYoung

Respuestas:

10

¡No olvide que todavía crece exponencialmente (en ) más rápido que !log ( n ) log ( log n )lognlog(n)log(logn)

De hecho, si observa el cociente de y , no hay mucho que ver:log ( log ( n ) )log(n)log(log(n))

log (n) / log (log (n))
[ fuente ]

Pero aún así, obtienes un factor de cinco a seis para tamaños de hasta . Tenga en cuenta que los tamaños más grandes no son infrecuentes en la práctica, ¡y una aceleración por ese factor es increíble ! Puede hacer la diferencia entre tener resultados después del almuerzo o solo mañana. Tenga en cuenta que parte de la aceleración puede ser carcomida por constantes más altas de la implementación del árbol; tendría que trazar (o analizar) y con las constantes de tiempo de ejecución reales para obtener una imagen real.c log ( n ) d log ( log ( n ) ) c , d100000clog(n)dlog(log(n))c,d

Además, lo que Dave menciona es importante: si la operación acelerada de esta manera se ejecuta, por ejemplo, linealmente a menudo, las aceleraciones constantes se convierten en aceleraciones lineales, es decir, ¡puede disminuir la constante inicial de todo su algoritmo! Como dije anteriormente, eso es increíble. Solo mira lo que sucede si ejecutas la operación veces:n

n * log (n) / (n * log (log (n)))
[ fuente ]

Ahora, si eso no vale la pena, no sé qué.

Rafael
fuente
6

Uno podría imaginar que la diferencia en la complejidad realmente no importa tanto, y que el tiempo de ejecución real es más importante. Pero si el algoritmo está en el núcleo de otro algoritmo, entonces esta diferencia puede ser importante.

Desde un propósito puramente teórico, la diferencia, por supuesto, es importante, especialmente si el algoritmo es parte de otro. Puede colocar el algoritmo más grande en una clase de complejidad diferente.

Dave Clarke
fuente
6

De hecho, he comparado el árbol de van Emde-Boas una vez. Lo comparé con un árbol AA, un hashmap y una matriz de bits.

Las pruebas realizan sizeinserciones con números aleatorios en el intervalo [0, bound], luego sizebuscan, luego sizeeliminan y luego vuelven a sizebuscar. Las eliminaciones también se realizan en números aleatorios, por lo que primero debe averiguar si están en la estructura.

Aquí están los resultados ( size= 2000000, bound= 10000000) en segundos:

AATreeLookup - O(n log n)
Inserting... 3.3652452
Searching... 5.2280724
Deleting...  7.3457427
Searching... 9.1462039
HashLookup - O(n) expected
Inserting... 0.3369505
Searching... 0.6223035
Deleting...  0.9062163
Searching... 1.1718223
VanEmdeBoasTree - O(n log log n)
Inserting... 0.7007531
Searching... 1.1775800
Deleting...  1.7257065
Searching... 2.2147703
ArrayLookup - O(n)
Inserting... 0.0681897
Searching... 0.1720300
Deleting...  0.2387776
Searching... 0.3413800

Como puede ver, los árboles de van Emde-Boas son aproximadamente dos veces más lentos que los mapas hash, diez veces más lentos que las matrices de bits y 5 veces más rápidos que los árboles de búsqueda binarios.

Por supuesto, lo anterior necesita un descargo de responsabilidad: las pruebas son artificiales, posiblemente puede mejorar el código o usar un lenguaje diferente con un compilador cuya salida es más rápida, y así sucesivamente.

Este descargo de responsabilidad es la razón principal por la que usamos el análisis asintótico en el diseño de algoritmos: como no tiene idea de cuáles son las constantes y las constantes pueden cambiar según los factores ambientales, lo mejor que podemos hacer es un análisis asintótico.

Ahora, en el caso de versus : en el ejemplo anterior, mi árbol van Emde-Boas puede contener elementos. y , que es una mejora del factor 6, que es bastante en la práctica. Además, los árboles van Emde-Boas tienen buenos factores constantes (se trata de factores constantes en la práctica para diferencias tan pequeñas) ya que no necesitan equilibrarse.log log nlognloglogn log 2 32 = 32 log 32 = 5232log232=32log32=5

Alex ten Brink
fuente
Tal vez saltar a R (o equivalente) y producir algunos gráficos bonitos (como lo hizo @Raphael).
Dave Clarke
1
Mejorará su respuesta si relacionó estos algoritmos con las nociones ylog log nlognloglogn
Dave Clarke
@DaveClarke: gracias por las sugerencias. Desafortunadamente, soy bastante malo para producir imágenes bonitas; creo que mi edición mejoró la legibilidad de mis resultados.
Alex ten Brink
Probablemente no haya suficientes datos para una imagen adecuada. No importa ... pero aprender a hacer buenas fotos es una habilidad práctica.
Dave Clarke