¿Cuál es el mejor algoritmo de clasificación para matrices aproximadamente ordenadas?

Aquí, la respuesta correcta depende de muchas cosas. Uno de ellos: ¿qué quieres decir con “aproximadamente ordenados”? Hay muchas medidas diferentes de clasificación, y para casi todas y cada una de ellas puede encontrar un algoritmo que sea bueno si esa medida en particular le dice que la entrada está casi ordenada. La otra cosa: ¿busca resultados teóricos o prácticos?

En la práctica, en la mayoría de los casos la respuesta es la genérica [matemática] O (n \ log n) [/ matemática] , la que está disponible en su biblioteca estándar. El factor “extra” [matemática] \ log n [/ matemática] rara vez importa.

Cuando tiene la garantía de que cada elemento está a lo sumo [math] k [/ math] pasos de distancia de su ubicación correcta, un algoritmo de ordenación personalizado simple y rápido es hacer un solo paso sobre la matriz usando un montón para almacenar el último [ elementos matemáticos] k + 1 [/ matemática], siempre agregando el siguiente de la matriz de entrada y luego extrayendo el siguiente en la matriz de salida. Desde un punto de vista teórico, esto le da a la complejidad del tiempo [matemáticas] O (n \ log k) [/ matemáticas], y podemos demostrar que, en general, no puede hacer nada mejor que eso. En la práctica, apenas puedo imaginar situaciones en las que me gustaría usarlo. Además, los mismos factores constantes que lo empujaron a rechazar la clasificación [math] O (n \ log n) [/ math] ahora probablemente significan que

  • para lo suficientemente pequeño [math] k [/ math] una implementación simple de un tipo de inserción [math] O (nk) [/ math] superará a este gracias a su factor constante mucho más pequeño.
  • para [matemática] k [/ matemática] mediana [la matemática] O (n \ log k) [/ matemática] ya será comparable a la [matemática] O (n \ log n) [/ matemática]

En realidad, en esas raras situaciones en las que una ordenación [matemática] O (n \ log n) [/ matemática] no es suficiente (¡y esas son raras!) A menudo es una mejor solución hacer una ordenación personalizada basada en otras propiedades de tu información. Por ejemplo, su pequeño número de bits. Por ejemplo, en los detalles de la pregunta que pregunta sobre la reordenación de una matriz de puntos por su distancia euclidiana del centro. En lugar de reutilizar su orden de acuerdo con su distancia de Manhattan desde ese centro, simplemente use una ordenación de radix [matemática] O (n) [/ matemática] directamente en los cuadrados de sus distancias euclidianas y listo.

Gracias por el A2A.

Para arreglos casi ordenados, lo mejor es probablemente una buena burbuja o inserción antigua.

Aquí hay una comparación de los diversos algoritmos de clasificación y su eficacia en diferentes tipos de datos:

Algoritmo de clasificación Animaciones

Bubble es el más fácil de implementar, pero Insertion es un mejor todoterreno.

Y si está trabajando en una simulación en la que la matriz debe ser en su mayoría correcta y siempre actualizada, sugiero una sola pasada de Bubble, quizás alternando las direcciones en cada cuadro. No puedes ser mucho más rápido que eso:

La respuesta de Dale Thomas a ¿Qué tan eficiente es la clasificación de burbujas?

Diría que el algoritmo adaptativo relativamente más nuevo, Timsort, que otras respuestas parecen haber pasado por alto.

Timsort

Fue diseñado específicamente para ser eficiente para datos parcialmente ordenados (mundo real). También es el algoritmo de clasificación predeterminado para Python, Android SDK, OpenJDK, Sun’s JDK y GNU Octave.

¿Cuál es la definición precisa de aproximadamente ordenado?

Dependiendo de lo que quiera decir, la respuesta puede variar. Si no necesito devolver una matriz ordenada con precisión, pero una matriz aproximadamente ordenada, puedo devolver la matriz tal cual, y simplemente decir que está ordenada, aproximadamente …

Pero si se clasifica aproximadamente, ¿se clasifica probabilísticamente? ¿Significa que en algunos casos podría encontrar aberraciones? En ese caso, no podría usar la información que dice que está aproximadamente ordenada, por lo que debería usar el mejor algoritmo disponible:

Insertsort es mucho mejor que bubbleort.

Entonces, lo mejor es el balde de agua. No puede suponer que los elementos están algo ordenados y funcionan a partir de ahí, a menos que realmente sepa que están realmente ordenados.

La ordenación de burbujas, la ordenación por inserción y la ordenación de Shell funcionarán muy bien con datos parcialmente ordenados. Mi tipo Unshuffle, que publiqué por primera vez en 1985, en realidad está diseñado y optimizado para datos parcialmente ordenados. Se ejecuta en O (kN) donde k es un número entero pequeño correspondiente al nivel de entropía o aleatoriedad en los datos. Los datos parcialmente ordenados exhiben una entropía muy baja. Por ejemplo, el valor ‘k’ para un mazo de cartas barajado que se clasificará solo en el rango es de aproximadamente 3. Tomo entre 140 y 160 comparaciones dependiendo de qué tan bien se haya barajado el mazo. Aquí hay un enlace a un nuevo artículo que estoy preparando para publicar:

https://www.google.com/url?sa=t&…

Tipo de inserción. Es el mejor algoritmo de clasificación cuando los elementos ya están ordenados. El algoritmo se ejecuta en n * k veces. Donde k es el número de elementos que necesita ordenar (elementos que no están ordenados). La mayoría de los otros elementos incluidos se ejecutarán en n log (n) tiempo. si k

Se puede encontrar un código de muestra aquí Implementar el orden de inserción en java.

Mi creencia personal (pero en realidad es solo una creencia) es que, en la práctica, si realmente sabes con certeza que está casi resuelto, usa insertionsort.

Si no está seguro, es mejor simplemente usar quicksort. Los algoritmos con una degradación suave, como el Melsort de Skiena, son inteligentes y elegantes, pero más lentos que el rápido en la práctica quick

Si quieres ser más sofisticado que eso, mira la excelente respuesta de Michal.

Mi recomendación personal es Shell Sort – O (n-log-n), más fácil de implementar y, cuando los datos están casi ordenados, es aún más rápido que Quick y Q3.

Estoy de acuerdo con Ofek Lev en que TimSort es el mejor algoritmo para arreglos parcialmente ordenados. Básicamente es una implementación híbrida de clasificación Merge + Insertion que supera a cualquiera de esos dos algoritmos de clasificación de manera singular. Es por eso que TimSort es aparte de la biblioteca estándar para casi todos los idiomas populares.

Para este caso específico, iría con Bubble (aunque podría tener que entenderlo un poco más). Parece que los datos están muy cerca de donde deben estar, pero una cantidad masiva de todos está desactivada, pero no mucho. Si solo se tratara de unos pocos elementos (es decir, una pequeña proporción del total), entonces optaría por la inserción, pero dado que es un número grande que está un poco alejado, probablemente le daría un giro a Bubble.

La ordenación por inserción es el mejor algoritmo de ordenación para la matriz ordenada o aproximadamente ordenada.

Cuando la matriz ya está ordenada o aproximadamente ordenada, el algoritmo de inserción de clasificación tarda O (n) tiempo.

Tomemos una matriz ordenada, aquí mientras aplicamos el algoritmo de clasificación de inserción, para cada pase necesitamos cero intercambios y 1 comparación.

Como sabemos que el algoritmo de clasificación de inserción requiere n-1 pasa para ordenar toda la matriz.

Por lo tanto, para los pases n-1 requerimos cero (0) intercambios y n-1 comparaciones.

T (n) = O (n).

Para una matriz completamente ordenada, la ordenación de burbujas o de inserción es la más rápida porque solo requiere un barrido de los datos sin intercambios.

La ordenación por inserción o la ordenación por shell puede resultar más rápida que la ordenación rápida para datos ordenados “aproximadamente” si la lista de datos no es demasiado grande. Sin embargo, todavía puede haber arreglos de los datos donde esta regla no se cumple y para conjuntos de datos muy grandes, lo mejor es ir con un ordenamiento rápido o un ordenamiento no basado en comparación (como el ordenamiento por cubeta) independientemente.