¿Cuál es el algoritmo de clasificación más rápido para una matriz de enteros?

55

Me he encontrado con muchos algoritmos de clasificación durante mis estudios de secundaria. Sin embargo, nunca sé cuál es el más rápido (para una matriz aleatoria de enteros). Entonces mis preguntas son:

  • ¿Cuál es el algoritmo de clasificación más rápido conocido actualmente?
  • Teóricamente, ¿es posible que haya incluso más rápidos? Entonces, ¿cuál es la menor complejidad para la clasificación?
gen
fuente
77
¿Qué quieres decir con "rápido"? ¿Qué quieres medir?
Raphael
2
¿Qué significa "matriz aleatoria de enteros"? Al azar con qué distribución? ¿distribución uniforme? Gaussiano? Dependiendo de la distribución, puede haber algoritmos de tiempo de ejecución mejor que esperados. O(nlogn)
Bakuriu
@gen Eche un vistazo a la clasificación de Radix. La implementación correcta tiene O (n) complejidad para Int32 por ejemplo.
este
Eche un vistazo al benchmark de clasificación
adrianN
1
@gen: ¿En términos de asymptotics? Entonces, es fácil: elija cualquiera de los algoritmos . Tenga en cuenta que esto podría no tener nada que ver con el rendimiento (promedio) del mundo real. Esta puede ser una lectura muy recomendable en este sentido. Θ ( n log n )ΘΘ(norteIniciar sesiónnorte)
Raphael

Respuestas:

42

En términos generales, existen los algoritmos de ordenación , como la ordenación por inserción, la ordenación por burbujas y la ordenación por selección, que normalmente debe usar solo en circunstancias especiales; Quicksort, que es el peor de los casos pero con bastante frecuencia con buenas constantes y propiedades y que puede usarse como un procedimiento de clasificación de propósito general; los algoritmos , como merge-sort y heap-sort, que también son buenos algoritmos de clasificación de propósito general; y los algoritmos de clasificación , o lineales, para listas de enteros, como radix, cubetas y tipos de conteo, que pueden ser adecuados dependiendo de la naturaleza de los enteros en sus listas.O ( n 2 ) O ( n log n ) O ( n log n ) O ( n )O(norte2)O(norte2)O(norteIniciar sesiónnorte)O(norteIniciar sesiónnorte)O(norte)

Si los elementos en su lista son tales que todo lo que sabe sobre ellos es la relación de orden total entre ellos, entonces los algoritmos de clasificación óptimos tendrán complejidad . Este es un resultado bastante bueno y uno para el que debería poder encontrar fácilmente los detalles en línea. Los algoritmos de ordenación lineal explotan más información sobre la estructura de los elementos que se ordenarán, en lugar de solo la relación de orden total entre los elementos.Ω(norteIniciar sesiónnorte)

Aún más en general, la optimización de un algoritmo de clasificación depende íntimamente de los supuestos que puede hacer sobre el tipo de listas que va a ordenar (así como el modelo de máquina en el que se ejecutará el algoritmo, lo que puede hacer una clasificación deficiente) los algoritmos son la mejor opción; considere la posibilidad de clasificar burbujas en máquinas con una cinta para almacenamiento). Cuanto más fuertes sean sus suposiciones, más esquinas podrá cortar su algoritmo. Bajo suposiciones muy débiles acerca de cuán eficientemente puede determinar la "clasificación" de una lista, la complejidad óptima en el peor de los casos puede ser incluso .Ω(norte!)

Esta respuesta solo trata las complejidades. Los tiempos de ejecución reales de las implementaciones de algoritmos dependerán de una gran cantidad de factores que son difíciles de explicar en una sola respuesta.

Patrick87
fuente
Supongo que algunos de esos deberían ser ? ΩOΩ
Raphael
1
@Raphael Meh. Creo que la mayoría de ellos son todos modos. Supongo que el límite inferior es probablemente mejor prestado Ω . Cambiaré un par de ellos que tengan más sentido. ΘΩ
Patrick87
77
Voto @Raphael obtiene un sombrero de policía : PΩ
Realz Slaw
2
@RealzSlaw: Lo usaría con orgullo. :]
Raphael
1
@gen Consulte stackoverflow.com/a/3274203 para una discusión. Básicamente, si los registros individuales son enormes, y no se almacenan de forma aleatoria, y la cantidad de datos es tal que debe hacerse en el lugar, entonces el ordenamiento de burbujas es el camino a seguir. Estas circunstancias generalmente son raras hoy en día, pero aún puede encontrarlas.
Patrick87
16

La respuesta, como suele ser el caso para tales preguntas, es "depende". Depende de cosas como (a) qué tan grandes son los enteros, (b) si la matriz de entrada contiene enteros en un orden aleatorio o en un orden casi ordenado, (c) si necesita que el algoritmo de ordenación sea estable o no, así como otros factores, (d) si la lista completa de números cabe en la memoria (clasificación en memoria frente a clasificación externa), y (e) la máquina en la que lo ejecuta.

En la práctica, el algoritmo de clasificación en la biblioteca estándar de su idioma probablemente será bastante bueno (bastante cercano al óptimo), si necesita una clasificación en memoria. Por lo tanto, en la práctica, simplemente use la función de ordenación proporcionada por la biblioteca estándar y mida el tiempo de ejecución. Solo si encuentra que (i) la clasificación es una gran fracción del tiempo de ejecución general, y (ii) el tiempo de ejecución es inaceptable, debería molestarse en perder el tiempo con el algoritmo de clasificación. Si estas dos condiciones hacen bodega, a continuación, se puede ver en los aspectos específicos de su dominio y experimento en particular con otros algoritmos de ordenación rápida.

Pero de manera realista, en la práctica, el algoritmo de clasificación rara vez es un gran cuello de botella en el rendimiento.

DW
fuente
9

Además, respondiendo tu segunda pregunta

Teóricamente, ¿es posible que haya incluso más rápidos?
Entonces, ¿cuál es la menor complejidad para la clasificación?

Para la clasificación de propósito general, la complejidad del problema de clasificación basada en la comparación es Ω (n log n) . Hay algunos algoritmos que realizan la clasificación en O (n), pero todos se basan en hacer suposiciones sobre la entrada y no son algoritmos de clasificación de propósito general.

Básicamente, la complejidad está dada por el número mínimo de comparaciones necesarias para ordenar la matriz (log n representa la altura máxima de un árbol de decisión binario construido al comparar cada elemento de la matriz).

Puede encontrar la prueba formal para ordenar la complejidad del límite inferior aquí :

rla4
fuente
3
Esta respuesta no es del todo correcta. no es un límite inferior universal para la clasificación. Ese límite inferior solo se aplica a clasificaciones basadas en comparaciones , es decir, algoritmos de clasificación que utilizan solo comparaciones. Algunos algoritmos de clasificación no se basan en la comparación. La declaración "Hay algunos algoritmos que realizan la clasificación en O (n), pero todos se basan en hacer suposiciones sobre la entrada y no son algoritmos de clasificación de propósito general". puede ser un poco engañoso, tenga cuidado. Radix-sort es un algoritmo de ordenación de propósito general (suponiendo que esté ordenando enteros de ancho fijo). Ω(norteIniciar sesiónnorte)
DW
Depende de lo que quieras decir con el problema de clasificación . Los tipos basados ​​en la comparación de propósito general no son el único tipo de problemas de clasificación que tiene la gente.
Patrick87
1
Eso es cierto, por supuesto. Debería haber sido más específico, gracias por señalarlo. Sin embargo, tenía un poco de curiosidad sobre a qué otros enfoques de clasificación (no basados ​​en comparación) se refería; Radix Sort es exactamente el tipo de algoritmo O (n) del que hablaba: debe 'asumir' algo sobre la entrada (enteros de ancho fijo). En este sentido, no es un algoritmo de clasificación de propósito general, ¿verdad?
rla4
1
@DW: La ordenación de radix no debe considerarse un algoritmo de ordenación de "propósito general", ya que requiere claves de entero de longitud fija; ¿No es útil de otra manera? Pero entiendo tu punto. :) Creo que mi error fue centrarme en ordenar algo que podría compararse, en lugar de ordenar enteros , específicamente. Son problemas diferentes y tienen un conjunto diferente de posibles soluciones. La pregunta menciona "una matriz aleatoria de enteros", pero admito que lo tomé como un ejemplo, en lugar de una restricción.
rla4
2
@DavidRicherby, mirando hacia atrás después de un año y medio, estoy de acuerdo contigo. Gracias.
DW
3

El algoritmo de clasificación de enteros más rápido en términos del peor de los casos que he encontrado es el de Andersson et al. Tiene el peor de los casos de , que por supuesto es más rápido que O ( n log n ) .O(norteIniciar sesiónIniciar sesiónnorte)O(norteIniciar sesiónnorte)

usuario39994
fuente
2
Eso es muy interesante, pero debes dar más información. Como menciona , supongo que es consciente de que la clasificación basada en comparación de enteros generales probablemente requiere tiempo Ω ( n log n ) . Cualquier cosa asintóticamente más rápida que eso tiene que hacer suposiciones sobre los datos: por ejemplo, la ordenación de radix se ejecuta en tiempo lineal, suponiendo que cada elemento de la matriz sea a lo más constante. ¿En qué condiciones se clasifica este algoritmo en O ( n log log n ) y cómo se desempeña en la práctica en comparación con otros algoritmos como quicksort y radix sort? norteIniciar sesiónnorteΩ(norteIniciar sesiónnorte)O(norteIniciar sesiónIniciar sesiónnorte)
David Richerby
1

Leí las otras dos respuestas al momento de escribir esto y no pensé que ninguna respondiera su pregunta de manera apropiada. Otras respuestas consideraron ideas extrañas sobre distribuciones aleatorias y complejidad espacial que probablemente están fuera del alcance de los estudios de secundaria. Así que aquí está mi opinión.

UNAnorte(norte-1)UNA(norte-1)Ω(norte)O(norte)Ω(norte)

Ω(norte)O(norte)norte2norte3norte-5 51norte2

bourbaki4481472
fuente
O(norte)nortelgnortenorte232O(norte)O(nortelgnorte)(para quicksort o mergesort), en la práctica la comparación no es tan clara: las constantes ocultas en la notación big-O se vuelven muy importantes, y la constante para radix-sort es más alta que la constante para quicksort o mergesort.
DW
lg(n)norte
Ω(n)
2
O(wnorte)www{0 0,...,2w-1}Iniciar sesiónnortenortew=Iniciar sesiónnortenorteIniciar sesiónnorte.
David Richerby
1

O(nortelosollosolnorte)
O(nortelosollosolU)U
el tonto
fuente
0

Iniciar sesión(norte!)

Ω(norte)

Yves Daoust
fuente
0

Como no menciona ninguna restricción en el hardware y dado que está buscando "el más rápido", diría que debe elegir uno de los algoritmos de clasificación paralela en función del hardware disponible y el tipo de entrada que tiene.

En teoría, por ejemplo, quick_sortes O(n log n). Con los pprocesadores, idealmente esto debería reducirse O(n/p log n)si lo ejecutamos en paralelo.

Para citar Wikipedia: la complejidad del tiempo de ...

La clasificación paralela óptima es O (log n)

En la práctica, para tamaños de entrada masivos sería imposible de lograr O(log n)debido a problemas de escalabilidad.

Aquí está el pseudocódigo para ordenar en paralelo . La implementación de merge()puede ser la misma que en el tipo de fusión normal:

// Sort elements lo through hi (exclusive) of array A.
algorithm mergesort(A, lo, hi) is
    if lo+1 < hi then  // Two or more elements.
        mid = ⌊(lo + hi) / 2⌋
        fork mergesort(A, lo, mid)
        mergesort(A, mid, hi)
        join
        merge(A, lo, mid, hi)

Ver también:

Kashyap
fuente
O(norte2)
@ Mal Sí. Quicksort no es adecuado para el procesamiento en paralelo. Es un ejemplo. Los que deben usarse se enumeran en los enlaces proporcionados.
Kashyap