¿Cómo puedo ordenar rápidamente una matriz de elementos que ya está ordenada, excepto por un pequeño número de elementos, por ejemplo, hasta 1/4 del total, cuyas posiciones se conocen, por ejemplo, 1,2,3,4,8,6 , 7,8,2,10,11,3,13,14,15,16. Este conjunto se ordena guardar 4,8,11?

Ninguna de estas respuestas realmente abordaba cómo identificar una pequeña cantidad de elementos fuera de orden que acababan de dar una matriz. Suponiendo que hay elementos K fuera de orden en nuestra matriz de longitud N y K es mucho más pequeño que N, entonces hay un par de formas de hacerlo.

La forma más obvia es usar el algoritmo de subsecuencia creciente más largo estándar que se ejecutará en O (N log N). Los elementos que no están en esta secuencia serán los elementos fuera de servicio y siempre terminaremos con no más de K (¡y tal vez menos!).

Sin embargo, en realidad hay otro enfoque. En cambio, podemos construir una subsecuencia creciente de elementos N-2K en el tiempo O (N). Haga esto escaneando los elementos para mantener una subsecuencia creciente de elementos. Si un elemento no es más pequeño que el final de su subsecuencia, agréguelo a la subsecuencia. De lo contrario, elimine el final de la subsecuencia (y no la agregue). Dado que cada operación de eliminación debe involucrar al menos uno de los elementos fuera de servicio, debemos terminar con al menos elementos N-2K en nuestra subsecuencia al final.

Una vez que hemos identificado los elementos 2K fuera de orden, podemos hacer lo que Anders Kaseorg dice y ordenar los elementos fuera de orden por sí mismos y luego fusionarlos. Esto le da al algoritmo general una complejidad de O (N + K log K).

En la descripción de su problema, si solo está cambiando un número realmente pequeño de elementos, podría beneficiarse utilizando una estructura de datos de árbol que le permitirá actualizar la posición de un único elemento en el tiempo O (log (N)) para que toda su operación de actualización puede ejecutarse en tiempo O (K log N), eliminando el término lineal en N por completo.

Ordene los elementos fuera de orden [math] k [/ math] usando su algoritmo favorito [math] O (k \ log k) [/ math], luego haga una fusión [math] O (n) [/ math] operación para combinar estos elementos recién ordenados [math] k [/ math] con los otros elementos [math] n – k [/ math] ya ordenados en una gran matriz ordenada.

Este tiempo de ejecución [matemática] O (n + k \ log k) [/ matemática] es demostrablemente óptimo en el modelo de comparación, incluso bajo su restricción de dirección hipotética.

(Según el comentario de su pregunta, parece que ya conoce este algoritmo, pero todas las otras respuestas parecían sugerir un tipo de inserción, que tiene un tiempo de ejecución estrictamente peor [matemáticas] O (nk + k ^ 2) [/ matemáticas]. Vamos chicos , CS 101: todos deberían saber que los algoritmos de clasificación cuadrática apestan. No puedo creer que los desarrolladores sigan cometiendo este error, pero lo están haciendo).

Utilice la selección de reemplazo bidireccional ya que conserva el orden de clasificación cuando los lotes ordenados tienen un orden, sin importar si son hacia adelante o hacia atrás, y todavía hay algunos elementos sin clasificar. Este fue un trabajo realizado por Data Management Group. DAMA-UPC

Aquí hay algunos pensamientos más.

1. ¿Sus datos son dinámicos? ¿Aparece como una secuencia? En este caso, la ordenación por inserción funciona mejor como un algoritmo en línea. Como señaló Prateek Sharma, la ordenación por inserción funciona bien en matrices casi ordenadas. Generalmente, la ordenación por inserción y la ordenación rápida se combinan para obtener mejores resultados. Cuando la recursividad de ordenación rápida alcanza un tamaño de matriz menor que el tamaño M predefinido, optamos por la ordenación por inserción, ya que es más eficiente. En promedio, la ordenación por inserción toma [matemática] O (N ^ 2/4) [/ matemática].

2. Basado en búsqueda binaria y clasificación de inserción.

A) Busque en la matriz de izquierda a derecha para encontrar el “primer elemento que es mayor que el siguiente” A [x]> A [x + 1].

B) Nuevamente, busque la matriz de derecha a izquierda para encontrar “el primer elemento que es más pequeño que el anterior” A [y]

C) Encuentre los elementos máximos y mínimos en la matriz secundaria A [x … y].

D) Obtenga el límite de ‘min’ en el rango A [0… x] (búsqueda binaria), digamos que la ubicación del límite es i .

E) Obtenga el piso de ‘max’ en el rango A [y … r] (búsqueda binaria, r es el extremo derecho), la ubicación del piso de la vela es j .

F) Clasifique (clasificación de inserción o cualquier clasificación aritmética lineal basada en la longitud) el subconjunto A [i … j] que clasifica todo el conjunto.

3. Dado que sus datos son moderadamente grandes, Shell Sort también se puede considerar.

1. Si insiste en que debe usar una matriz, no un árbol, entonces combine como señala Anders.

Así que no los guardes en una matriz. Guárdelos directamente en un árbol e insértelos directamente en él. No se desequilibrará mucho

Si usó un árbol (equilibrado) con N elementos y, por lo tanto, la profundidad promedio D = log2 (N) y Dmax = ⌈log2 (N) ⌉, y había M elementos fuera de lugar para insertar, esperaría O ( MD), eso es NlogN. (Aproximadamente de primer orden, descuidando que las inserciones lo desequilibran y la profundidad promedio un poco más; pero también algunas inserciones no necesitan ir a D.)
El montón de latidos de árbol en este caso porque como sabes que ya tienes 3/4 de la estructura construida, no quieres burbujear mucho durante las inserciones.

2. ¿Sería más fácil el problema si los elementos fuera de orden estuvieran fuera de orden en la misma dirección, por ejemplo, demasiado temprano en la secuencia?

Para el caso del árbol, no tendría mucho sentido ajustar el algoritmo ya que si se extendieran al azar, esperaría ahorrar solo ~ una profundidad por inserción. Eso es un ahorro de O (M).

> La aplicación práctica es esta: tengo una matriz en la que ocasionalmente cambian los valores de una fracción de los elementos.

¿Tiene algún conocimiento a priori sobre qué elementos pueden cambiar y cuánto pueden cambiar sus valores? Si lo hiciera, podríamos llegar a una estructura de datos más especializada.

En 1985 desarrollé y publiqué un algoritmo de clasificación único que denominé UnShuffle Sort. Se puede demostrar que UnShuffle es la forma más eficiente de ordenar una lista que contiene elementos ordenados. El rendimiento es lineal en el tamaño de la lista y proporcional a la entropía (o aleatoriedad) en los datos (el orden es: O (kN) donde k es la constante del factor de entropía). Para una lista completamente ordenada, funciona en O (1N)

Aquí hay un enlace a un nuevo artículo que he escrito y estoy planeando publicar sobre una versión actualizada del algoritmo: http://www.askdbmgt.com/uploads/

El método de inserción es el algoritmo más eficiente para ordenar arreglos parcialmente ordenados .

Insertion Sort exhibe muy poca sobrecarga, ordena una matriz ya ordenada en un solo barrido y es fácil de codificar.

Puede consultar: http://stackoverflow.com/questio

Dado que su matriz está casi ordenada, normalmente le recomendaría que pruebe Insertar Clasificación, ya que casi obtendrá el mejor comportamiento del algoritmo de clasificación.

Pero ha mencionado que el tamaño de su matriz puede extenderse hasta 200k elementos, donde usar Insertion Sort puede no parecer una idea factible. En su lugar, puede intentar usar la búsqueda binaria en el orden de inserción en lugar de usar la búsqueda lineal tradicional. O si todo falla, puede intentar usar algunos algoritmos de clasificación O (n lg n) como Merge Sort, Quick Sort u Heap Sort

Use una matriz de memoria empaquetada.

More Interesting

¿Cuánto de aprender un lenguaje de programación de computadoras (como C ++) tiene sus raíces en las matemáticas, es decir, ¿necesito tener un cerebro matemáticamente competente para escribir programas?

¿Cuánto CS se enseña en matemáticas y la rama de computación en ISM y BHU?

¿Qué es la combinatoria en matemáticas discretas?

¿Qué es un algoritmo eficiente para encontrar los primeros cinco números primos de diez dígitos?

Cómo identificar problemas del mundo real que podemos resolver mediante el uso de la informática y las matemáticas

Si el Universo se restableciera al estado en el que acaba de comenzar, ¿podría el mundo ser diferente después de exactamente la misma cantidad de tiempo que la edad del Universo ahora? ¿O sería exactamente lo mismo?

¿Cuándo son dos algoritmos isomorfos?

¿Por qué se le dio al F-117 Nighthawk un prefijo F?

Suponiendo que uno tenga una experiencia limitada en programación, matemáticas y neurociencia, ¿cómo se ingresa a un programa de posgrado para inteligencia artificial o neurociencia computacional?

¿Puede una inteligencia computacional observar una ley física incontestable?

¿Cómo ayuda el conocimiento matemático en la programación? ¿Puedes describir algunos ejemplos?

¿Qué pasaría si se definiera la multiplicación para tener 0 como identidad en lugar de 1?

¿Cuál es su consejo para alguien que comienza su doctorado en informática teórica?

¿Cuántas veces es más rápida la búsqueda binaria que la búsqueda secuencial cuando se busca el elemento 592 en una lista de 1024 elementos?

¿Qué innovaciones en la teoría de CS de los últimos 10 años han tenido un impacto fuera de la academia? Si iba a hacer un doctorado en CS, ¿debería hacer teoría en lugar de aprendizaje automático?