¿Hay algún algoritmo de clasificación peor que Bogosort (también conocido como Monkey Sort)? [cerrado]


178

Mis compañeros de trabajo me llevaron al pasado a mis días de universidad con una discusión sobre algoritmos de clasificación esta mañana. Recordamos nuestros favoritos como StupidSort , y uno de nosotros estaba seguro de haber visto un algoritmo de clasificación O(n!). Eso me hizo comenzar a buscar los "peores" algoritmos de clasificación que pude encontrar.

Postulamos que una ordenación completamente aleatoria sería bastante mala (es decir, aleatorizar los elementos, ¿está en orden? ¿No? Aleatorizar de nuevo), y miré a mi alrededor y descubrí que aparentemente se llama BogoSort, o Monkey Sort, o, a veces, simplemente Random Sort .

Monkey Sort parece tener un rendimiento en el peor de los casos O(∞), un rendimiento en el mejor de los casos O(n)y un rendimiento promedio de O(n·n!).

¿Cuál es el algoritmo de clasificación oficialmente aceptado actualmente con el peor rendimiento promedio de clasificación (y por lo tanto, peor que O(n·n!))?


10
¿Cuántos bogomips por bogosort? Las mentes curiosas quieren saber.
zombat

13
Para aclarar, ¿está excluyendo el caso trivial donde el mejor rendimiento del caso es O (∞)?
tloflin


66
Escuché que el tipo de mono también se conoce como "tipo de hombre borracho", un nombre que encuentro mucho más evocador.
Matteo Italia

66
@Matteo Italia, o podría llamarse "Clasificación de niños pequeños" como puede atestiguar cualquier persona con 2 años.
Martin Capodici

Respuestas:


442

De la página de Algoritmos Esotéricos de David Morgan-Mar : Clasificación de diseño inteligente

Introducción

El diseño inteligente es un algoritmo de clasificación basado en la teoría del diseño inteligente.

Descripción del algoritmo

La probabilidad de que la lista de entrada original esté en el orden exacto es 1 / (n!). Hay una probabilidad tan pequeña de esto que es claramente absurdo decir que esto sucedió por casualidad, por lo que debe haber sido puesto conscientemente en ese orden por un clasificador inteligente. Por lo tanto, es seguro asumir que ya está Óptimamente ordenado de alguna manera que trasciende nuestra ingenua comprensión mortal del "orden ascendente". Cualquier intento de cambiar ese orden para cumplir con nuestras propias ideas preconcebidas en realidad lo haría menos ordenado.

Análisis

Este algoritmo es constante en el tiempo y clasifica la lista en el lugar, sin necesidad de memoria adicional. De hecho, ni siquiera requiere ninguno de esos elementos informáticos tecnológicos sospechosos. ¡Alabado sea el clasificador!

Realimentación

Gary Rogers escribe:

Hacer que la ordenación sea constante en el tiempo niega el poder de The Sorter. El Clasificador existe fuera del tiempo, por lo tanto, el tipo es atemporal. Para requerir tiempo para validar la ordenación, disminuye la función del Clasificador. Por lo tanto ... este tipo particular es defectuoso y no se puede atribuir a 'The Sorter'.

¡Herejía!


94
También conocido como "Clasificación de supuestos": suponga que la lista está ordenada, ¡regrese!
BioGeek

42
+100: esta respuesta está hecha con una ganancia 100% pura.
womp

11
¡Oye! No olvide "Clasificación indecisa" (también conocida como "Clasificación de Schrodinger" o "Clasificación cuántica"), donde la lista puede o no clasificarse, sin embargo, al verificarla se revelará o no. Aquí está mi implementación de ejemplo: void quantum_sort (void *b, size_t n, size_t s, int (*c)(const void *, const void*)) { if (rand () % 2) qsort (b, n, s, c); }.
Joe D

66
Debemos copiar este Candide Ordenar :"This is the best of all posibble worlds because it is the world that is, and so in the best possible world the array would already be sorted!"
echochamber

2
Yo, por mi parte, doy la bienvenida a nuestro nuevo señor de la clasificación. ¡Todos saludan al clasificador!
Bryson

299

Hace muchos años, inventé (pero nunca implementé) MiracleSort.

Start with an array in memory.
loop:
    Check to see whether it's sorted.
    Yes? We're done.
    No? Wait a while and check again.
end loop

Eventualmente, las partículas alfa volteando bits en los chips de memoria deberían resultar en una clasificación exitosa.

Para una mayor confiabilidad, copie la matriz en una ubicación protegida y verifique las matrices potencialmente ordenadas con el original.

Entonces, ¿cómo se compara la matriz potencialmente ordenada con la original? Simplemente ordena cada matriz y comprueba si coinciden. MiracleSort es el algoritmo obvio para usar en este paso.

EDITAR: Estrictamente hablando, esto no es un algoritmo, ya que no se garantiza que termine. ¿"No un algoritmo" califica como "un algoritmo peor"?


39
Supongo que uno puede usar rayos cósmicos para probar la corrección de este algoritmo.
ghord

1
¿Cuál es el gran O de esto? O(2^N)?
Mooing Duck

12
@MooingDuck: No creo que realmente tenga una gran O.
Keith Thompson

55
@MooingDuck: Estrictamente hablando, si no termina no es un algoritmo, de acuerdo con lo que me enseñaron en la universidad y el artículo de Wikipedia .
Keith Thompson

77
@Olathe: El problema de detención dice que no podemos determinar para todos los programas si se detienen, pero hay muchos programas para los que podemos tomar esa determinación. Nosotros sabemos ordenación rápida y Bubblesoft alto, y sabemos que son algoritmos.
Keith Thompson el

133

Quantum Bogosort

Un algoritmo de clasificación que asume que la interpretación de la mecánica cuántica en muchos mundos es correcta:

  1. Verifique que la lista esté ordenada. Si no, destruye el universo.

Al finalizar el algoritmo, la lista se ordenará en el único universo que quede en pie. Este algoritmo toma el tiempo de O (N) en el peor de los casos y el tiempo promedio de O (1). De hecho, el número promedio de comparaciones realizadas es 2: hay un 50% de posibilidades de que el universo se destruya en el segundo elemento, un 25% de posibilidades de que se destruya en el tercero, y así sucesivamente.


42
Pero el tiempo deja de existir en el universo que acabas de destruir. Por lo tanto, un observador en un universo que aún no ha verificado no podrá saber qué parte del algoritmo se ha ejecutado. Por lo tanto, este algoritmo siempre toma O (1) tiempo, ya que las destrucciones de universo anteriores ya no existen.
Barry Brown

12
Sí, en el único universo que observa la lista ordenada, le tomó a O (n) tiempo ejecutarlo; el tiempo que tardó en otros universos es irrelevante.
Nick Johnson

19
Sin embargo, este algoritmo tiene un problema mucho mayor. Suponga que una de cada 10 mil millones de veces concluirá erróneamente que una lista está ordenada cuando no lo está. Hay 20! formas de ordenar una lista de 20 elementos. Después de la clasificación, los universos restantes serán aquellos en los que la lista se ordenó correctamente, y los 2.4 millones de universos en los que el algoritmo concluyó erróneamente que la lista se ordenó correctamente. Entonces, lo que tiene aquí es un algoritmo para aumentar enormemente la tasa de error de una pieza de maquinaria.
Nick Johnson

10
Obviamente, este es el mejor algoritmo de clasificación, no el peor.
Boann el

11
No seguir los consejos de Beetle puede provocar la destrucción de todos los universos.
CrashCodes

60

Me sorprende que nadie haya mencionado Sleepsort todavía ... ¿O no lo he notado? De todas formas:

#!/bin/bash
function f() {
    sleep "$1"
    echo "$1"
}
while [ -n "$1" ]
do
    f "$1" &
    shift
done
wait

ejemplo de uso:

./sleepsort.sh 5 3 6 3 6 3 1 4 7
./sleepsort.sh 8864569 7

En términos de rendimiento es terrible (especialmente el segundo ejemplo). Esperar casi 3.5 meses para ordenar 2 números es algo malo.


3
Esto parece ser una O(N)especie, pero en realidad está limitado por el sistema operativo que implementa los temporizadores.
Mooing Duck

77
De cualquier forma que lo corte, esto probablemente exhibe un mejor crecimiento que el bogosort.
Mooing Duck

8
Veo una condición de carrera allí.

55
Puede cambiar sleep "$1"a sleep "0.$(printf "%010d" $1)"para mejorar notablemente el rendimiento. time ./sleepsort.sh 8864569 7luego se ejecuta en 0.009s en mi computadora portátil.
Sam Kellett

1
Esto se ejecuta en complejidad O (N) (dependiendo, por supuesto, de la implementación del temporizador), es un tipo de cubo simple en forma diferente.
Qwerty01

60

Jingle Sort, como se describe aquí .

Usted le da cada valor en su lista a un niño diferente en Navidad. Los niños, al ser seres humanos horribles, compararán el valor de sus dones y se clasificarán de acuerdo con ellos.


50

Tuve un profesor que una vez sugirió generar una matriz aleatoria, verificar si estaba ordenada y luego verificar si los datos eran los mismos que la matriz a ordenar.

Mejor caso O (N) (¡primera vez bebé!) Peor caso O (Nunca)


44
Más interesante de analizar es el caso promedio , que es ...?
Mooing Duck

44
Como dicen todos los mejores libros de texto, ¡esto se deja como un ejercicio para el lector!
Daniel

40
Mooing Duck: O (a veces)
Ilya O.

1
@MooingDuck, entonces necesitamos saber la cardinalidad del tipo de elemento y la distribución utilizada para generar elementos aleatorios en matrices aleatorias.
Nombre para mostrar

55
La complejidad es O (N! * Z ^ N) donde Z es el tamaño del conjunto de valores posibles y N es la longitud de la matriz.
jakubiszon

30

Si mantiene el algoritmo significativo de alguna manera, O(n!)es el peor límite superior que puede lograr.

Dado que la comprobación de cada posibilidad de permutaciones de un conjunto que se ordenará tomará n!medidas, no puede ser peor que eso.

Si está haciendo más pasos que eso, entonces el algoritmo no tiene un propósito útil real. Sin mencionar el siguiente algoritmo de clasificación simple con O(infinity):

list = someList
while (list not sorted):
    doNothing

14
Pero se necesita O (n) para verificar si está ordenado, para que pueda obtener O (n * n!)
erikkallen

3
@erikkallen: Ciertamente, podemos encontrar un algoritmo para verificar la clasificación que es peor que O (n). Por ejemplo, para cada elemento de la matriz, verifique que sea mayor que todos los anteriores, al igual que funciona la ordenación por inserción. Ese es un algoritmo O (n ^ 2), y estoy seguro de que podría pensar en algo peor si lo pienso un poco.
David Thornley

77
@David Thornley: el siguiente algoritmo de verificación tal vez muestre el mismo espíritu que el bogosort: elija dos elementos aleatorios, verifique que el que tiene el índice más pequeño sea más pequeño o igual al que tiene el índice más grande, luego repita. Mantenga una matriz de bits cuadrados para ver qué combinaciones ya se han verificado. Por supuesto, verificar esta matriz también se podría hacer en una caminata aleatoria ...
Svante

19

Bogobogosort. Si, es una cosa. a Bogobogosort, Bogosort, el primer elemento. Verifique si ese elemento está ordenado. Siendo un elemento, lo será. Luego agrega el segundo elemento, y Bogosort esos dos hasta que esté ordenado. Luego agrega un elemento más, luego Bogosort. Continúa agregando elementos y Bogosorting hasta que finalmente hayas hecho cada elemento. Esto fue diseñado para nunca tener éxito con ninguna lista considerable antes de la muerte por calor del universo.


55
Santa madre del código. Creo que incluso podemos hacer un corto de Bogolplex.
MrKekson

19

Debería investigar un poco sobre el apasionante campo de los Algoritmos pesimales y el Análisis de simpleza . Estos autores trabajan en el problema de desarrollar una especie con un mejor caso pesimista (el mejor caso de su bogosort es Omega (n), mientras que slowsort (ver artículo) tiene una complejidad de tiempo de mejor caso no polinómica).


19

Hay un tipo que se llama bogobogosort. Primero, verifica los primeros 2 elementos y los bogos clasifica. A continuación, verifica los primeros 3, los bogos los ordena, y así sucesivamente.

Si la lista está fuera de servicio en cualquier momento, se reinicia al ordenar de nuevo los primeros 2. El bogosort regular tiene una complejidad promedio de O(N!), este algoritmo tiene una complejidad promedio deO(N!1!2!3!...N!)

Editar : para darle una idea de qué tan grande es este número, para los 20elementos, este algoritmo lleva un promedio de 3.930093*10^158 años , muy por encima de la muerte por calor propuesta del universo (si sucede) de 10^100 años ,

mientras que la ordenación por fusión toma alrededor de .0000004 segundos , la ordenación por burbuja .0000016 segundos y el bogosort lleva 308 años , 139 días , 19 horas , 35 minutos , 22.306 segundos , suponiendo que un año sea 365,242 días y una computadora realiza 250,000,000 de operaciones de 32 bits por segundo.

Edit2 : este algoritmo no es tan lento como el milagro del "algoritmo", que probablemente, como este tipo, absorberá la computadora en el agujero negro antes de que clasifique con éxito 20 elementos, pero si lo hiciera, estimaría una complejidad promedio de 2^(32(the number of bits in a 32 bit integer)*N)(the number of elements)*(a number <=10^40) años ,

dado que la gravedad acelera el movimiento alfa de las fichas, y hay 2 ^ N estados, que son 2^640*10^40, o aproximadamente , 5.783*10^216.762162762 años , aunque si la lista comenzara ordenada, su complejidad solo sería O(N), más rápida que la fusión, que es solo N log N incluso En el peor de los casos.

Edit3 : este algoritmo es en realidad más lento que el tipo milagroso ya que el tamaño se hace muy grande, digamos 1000, ya que mi algoritmo tendría un tiempo de ejecución de 2.83*10^1175546 años , mientras que el algoritmo de tipo milagroso tendría un tiempo de ejecución de 1.156*10^9657 años .


1
Gran respuesta trabajada. triste no tiene visibilidad
swyx

16

Aquí hay 2 tipos que se me ocurrió con mi compañero de cuarto en la universidad

1) Verifique el orden 2) Tal vez ocurrió un milagro, vaya a 1

y

1) compruebe si está en orden, si no 2) coloque cada elemento en un paquete y devuélvalo a un servidor distante. Algunos de esos paquetes volverán en un orden diferente, así que vaya a 1


El segundo es casi el equivalente de una especie de bozo. Sin embargo, primero es inteligente.
Mooing Duck

1
El primero es Miracle Sort.
Charles

14

Siempre está el Bogobogosort (¡Bogoception!). Realiza Bogosort en subconjuntos cada vez más grandes de la lista, y luego comienza de nuevo si la lista no se ordena.

for (int n=1; n<sizeof(list); ++n) {
  while (!isInOrder(list, 0, n)) {
    shuffle(list, 0, n);
  }
  if (!isInOrder(list, 0, n+1)) { n=0; }
}

55
Me gusta la idea de que este algoritmo está diseñado para nunca terminar "antes de la muerte por calor del universo para una lista considerable"
A.Grandt

10

1 Ponga sus artículos para clasificarlos en fichas
2 Tírelos al aire en un día ventoso, a una milla de su casa.
2 Tíralos a una hoguera y confirma que están completamente destruidos.
3 Verifique el piso de su cocina para saber si está ordenado correctamente.
4 Repita si no es el orden correcto.

El mejor escenario es O (∞)

Edite arriba según la observación astuta de KennyTM.


9
No, esto es peor porque no hay posibilidad de que tenga éxito. ¿Cómo llegarían las fichas a tu cocina? Están soplando afuera. Se llama, uh, pero la cabeza.
Patrick Karcher

Creo que quiere decir tirar las cartas al aire afuera , y luego revisar su piso adentro , donde se garantiza que no habrá cartas. Aunque no es un algoritmo "con nombre" ... ¡sin duda es peor!
womp

10
@Patrick Tunelización cuántica.
kennytm

8
@KennyTM. Eso realmente se me había ocurrido. Existe una posibilidad extremadamente pequeña pero no nula de que cualquier objeto pueda desaparecer y reaparecer en cualquier otro punto del universo. Supongo que podría sucederle a mil fichas. . . Oi Dangit, mi algoritmo es defectuoso . Lo arreglaré . . .
Patrick Karcher

3
Es como tomar té y no té al mismo tiempo. O viajes espaciales utilizando una unidad de improbabilidad infinita.
Barry Brown el

9

El "¿qué te gustaría que fuera?" ordenar

  1. Tenga en cuenta la hora del sistema.
  2. Ordene usando Quicksort (o cualquier otra cosa razonablemente razonable), omitiendo el último intercambio.
  3. Tenga en cuenta la hora del sistema.
  4. Calcule el tiempo requerido. La aritmética de precisión extendida es un requisito.
  5. Espera el tiempo requerido.
  6. Realiza el último intercambio.

No solo puede implementar cualquier valor de O (x) concebible por debajo del infinito, sino que el tiempo necesario es probablemente correcto (si puede esperar tanto).


8

Nada puede ser peor que el infinito.


38
Infinito + 1. Jinx, sin devoluciones.
zombat

24
No para valores extremadamente grandes de 1;)
zombat

8
Lo que realmente me sorprende sobre el concepto de infinito es que puedes tener diferentes "tamaños" de infinito. Por ejemplo, considere el conjunto de todos los enteros: tiene un tamaño infinito. Ahora considere el conjunto de todos los enteros pares : también es de tamaño infinito, pero también es claramente la mitad del tamaño del primer conjunto. Ambos infinitos, pero de diferentes tamaños. Tan genial. El concepto de "tamaño" simplemente no funciona en el contexto del infinito.
zombat

44
@zombat: Estás hablando de cardinalidad, no de infinito como símbolo que indica una tendencia en la línea real / plano complejo.
kennytm

18
@zombat. El tamaño del conjunto de enteros pares es el mismo que el tamaño del conjunto de enteros, como lo demuestra el hecho de que puede colocarlos en correspondencia uno a uno. Ahora, hay más números reales que enteros, como lo mostró Cantor por primera vez.
David Thornley

5

Bozo sort es un algoritmo relacionado que verifica si la lista está ordenada y, si no, intercambia dos elementos al azar. Tiene el mismo rendimiento en los mejores y peores casos, pero intuitivamente esperaría que el caso promedio sea más largo que Bogosort. Es difícil encontrar (o producir) datos sobre el rendimiento de este algoritmo.


5

Segmentos de π

Suponga que π contiene todas las combinaciones posibles de números finitos. Ver la pregunta de intercambio de matemáticas.

  1. Determine el número de dígitos necesarios a partir del tamaño de la matriz.
  2. Use segmentos de π lugares como índices para determinar cómo reordenar la matriz. Si un segmento excede los límites de tamaño para esta matriz, ajuste el desplazamiento decimal π y comience de nuevo.
  3. Compruebe si la matriz reordenada está ordenada. Si es woot, ajuste el desplazamiento y comience de nuevo.

4

Un rendimiento en el peor de los casos de O (∞) podría ni siquiera convertirlo en un algoritmo según algunos .

Un algoritmo es solo una serie de pasos y siempre se puede hacer peor al ajustarlo un poco para obtener el resultado deseado en más pasos de los que estaba tomando anteriormente. Uno podría poner a propósito el conocimiento del número de pasos dados en el algoritmo y hacerlo terminar y producir la salida correcta solo después Xde haber realizado el número de pasos. Eso Xpodría muy bien ser del orden de O (n 2 ) u O (n n! ) O lo que sea que el algoritmo deseara hacer. Eso aumentaría efectivamente los límites de su mejor caso y de los casos promedio.

Pero su peor de los casos no puede ser superado :)


3

Mi algoritmo de clasificación lenta favorito es el tipo de títere:

void stooges(long *begin, long *end) {
   if( (end-begin) <= 1 ) return;
   if( begin[0] < end[-1] ) swap(begin, end-1);
   if( (end-begin) > 1 ) {
      int one_third = (end-begin)/3;
      stooges(begin, end-one_third);
      stooges(begin+one_third, end);
      stooges(begin, end-one_third);
   }
}

La peor complejidad del caso es O(n^(log(3) / log(1.5))) = O(n^2.7095...) .

¡Otro algoritmo de clasificación lenta en realidad se llama slowsort!

void slow(long *start, long *end) {
   if( (end-start) <= 1 ) return;
   long *middle = start + (end-start)/2;
   slow(start, middle);
   slow(middle, end);
   if( middle[-1] > end[-1] ) swap(middle-1, end-1);
   slow(start, end-1);
}

Este toma O(n ^ (log n))en el mejor de los casos ... incluso más lento que el stoogesort.


3
Recursive Bogosort (probably still O(n!){
if (list not sorted)
list1 = first half of list.
list 2 = second half of list.
Recursive bogosort (list1);
Recursive bogosort (list2);
list = list1 + list2
while(list not sorted)
    shuffle(list);
}

2

Esta página es una lectura interesante sobre el tema: http://home.tiac.net/~cri_d/cri/2001/badsort.html

Mi favorito personal es el sillysort de Tom Duff:

/*
 * The time complexity of this thing is O(n^(a log n))
 * for some constant a. This is a multiply and surrender
 * algorithm: one that continues multiplying subproblems
 * as long as possible until their solution can no longer
 * be postponed.
 */
void sillysort(int a[], int i, int j){
        int t, m;
        for(;i!=j;--j){
                m=(i+j)/2;
                sillysort(a, i, m);
                sillysort(a, m+1, j);
                if(a[m]>a[j]){ t=a[m]; a[m]=a[j]; a[j]=t; }
        }
}

2

Doble bogosort

Bogosort dos veces y compara los resultados (solo para asegurarte de que esté ordenado) si no lo vuelves a hacer


1

Puede hacer que cualquier algoritmo de ordenación sea más lento ejecutando su paso "está ordenado" al azar. Algo como:

  1. Cree una matriz de booleanos del mismo tamaño que la matriz que está ordenando. Ponlos a todos en falso.
  2. Ejecutar una iteración de bogosort
  3. Elige dos elementos al azar.
  4. Si los dos elementos se ordenan entre sí (i <j && array [i] <array [j]), marque los índices de ambos en la matriz booleana como verdaderos. De lo contrario, comience de nuevo.
  5. Compruebe si todos los booleanos en la matriz son verdaderos. Si no, regrese a 3.
  6. Hecho.

1

Sí, SimpleSort, en teoría se ejecuta, O(-1)sin embargo, esto es equivalente a loO(...9999) que a su vez es equivalente a O (∞ - 1), que también es equivalente a O (∞). Aquí está mi implementación de muestra:

/* element sizes are uneeded, they are assumed */
void
simplesort (const void* begin, const void* end)
{
  for (;;);
}

1

Uno en el que estaba trabajando implica elegir dos puntos aleatorios, y si están en el orden incorrecto, invertir todo el subrango entre ellos. Encontré el algoritmo en http://richardhartersworld.com/cri_d/cri/2001/badsort.html , que dice que el caso promedio es probablemente en algún lugar alrededor de O (n ^ 3) u O (n ^ 2 log n) ( él no está realmente seguro).

Creo que podría ser posible hacerlo de manera más eficiente, porque creo que podría ser posible realizar la operación de inversión en el tiempo O (1).

En realidad, me di cuenta de que hacer eso haría todo lo que digo tal vez porque me di cuenta de que la estructura de datos que tenía en mente pondría el acceso a los elementos aleatorios en O (log n) y determinaría si necesita revertirse en O (n )


1

Randomsubsetsort.

Dada una matriz de n elementos, elija cada elemento con probabilidad 1 / n, aleatorice estos elementos y verifique si la matriz está ordenada. Repita hasta que esté ordenado.

El tiempo esperado se deja como ejercicio para el lector.

Al usar nuestro sitio, usted reconoce que ha leído y comprende nuestra Política de Cookies y Política de Privacidad.
Licensed under cc by-sa 3.0 with attribution required.