Está en la página 1de 10

ING Diego Parraga Menchaca

TRABAJO DE INVESTIGACIÓN

- Gnome Sort
- Sleep Sort – The King of Laziness / Sorting
while Sleeping

NOMBRE: Amparo Acarapi Mamani

FECHA: 15/06/2020
Gnome sort (o "ordenamiento del duende del
jardín")
HISTORIA DEL ALGORITMO

El algoritmo de ordenación conocido como gNome_sort tiene una historia de


invención cuasi paralela. Durante un tiempo existió la polémica sobre su invención,
finalmente atribuida a Hamid Sarbazi-Azad quien lo desarrolló en el año 2000 y al
que llamó Stupid sort (Ordenamiento estúpido).
Cuando Dick Grune lo inventó (más apropiadamente, lo reinventó) y documentó,1
no halló evidencias de que existiera y en palabras suyas, dijo de él "the simplest
sort algorithm"2 (es el algoritmo más simple) y quizás tenga razón, pues lo
describió en sólo cuatro líneas de código. Dick Grune se basó en los gnomos de
jardín holandés y la manera en que se colocan dentro de los maceteros (ver la
referencia anterior) y de ahí también el nombre que le dio.
Netamente es un algoritmo de burbuja con una clara particularidad: recorre el
array a ordenar como una cremallera, en un vaivén, o bien puede ser definido
como un ordenamiento de burbuja bidireccional, que a su vez son llamados
también cocktail shaker (agitador de cócteles), por la forma en que trabaja...
Cumple estrictamente hablando con la complejidad
EXPLICACIÓN DEL ALGORITMO
La idea de este algoritmo es imaginarse un duende del jardín ordenando macetas.
Los únicos intercambios que puede hacer son dos macetas una al lado de la otra.

El duende empieza por el principio de la lista y termina cuando llega al final:

 si está mirando al primer elemento de la lista (a0), o si el elemento que mira


es mayor o igual al elemento que está justo a la izquierda (ai >  = ai − 1),
entonces hace un paso a la derecha
 si el elemento que está mirando es menor al que está justo a la izquierda
(ai < ai − 1), entonces los intercambia, y hace un paso a la izquierda.

El duende repite este proceso hasta que llegue al final de la lista.

EJEMPLO DE APLICACIÓN DEL ALGORITMO

Este método de ordenamiento se basa en la conocida técnica “divide y vencerás”,


en aquella ocasión había muchos libros a ordenar por eso decidimos que cada uno
de nosotros agarrara un puñado de libros; más o menos la misma cantidad y
ordenarla.
function
mergeSort(arr
){
/* Metodo recursivo */
if (arr.length === 1) {
/* recursividad termina cuando la longitud del arreglo es 1
(Ya no hay nada que ordenar)
*/
return arr
}

const mitad = Math.floor(arr.length / 2) // obtenemos la mitad del


arreglo redondeando hacia abajo.
const izquierda = arr.slice(0, mitad) // Elementos del lado izquierdo
const derecha = arr.slice(mitad) // Elementos del lado derecho

return merge(
mergeSort(izquierda),
mergeSort(derecha)
)
}

// compara ambos arreglos y devuelve la union de los resultados


function merge (left, right) {

let result = []
let indexLeft = 0
let indexRight = 0

while (indexLeft < left.length && indexRight < right.length) {

if (left[indexLeft] < right[indexRight]) {


result.push(left[indexLeft])
indexLeft++
} else {
result.push(right[indexRight])
indexRight++
}
}

return
result.concat(left.slice(indexLeft)).concat(right.slice(indexRight))
}

CAPTURA O CODIGO DEL ALGORITMO

Sleep Sort - The King of Pereza / Clasificación mientras


duerme
HISTORIA DEL ALGORITMO

EXPLICACIÓN DEL ALGORITMO


En este algoritmo creamos diferentes subprocesos para cada uno de los
elementos en la matriz de entrada y luego cada subproceso duerme durante una
cantidad de tiempo que es proporcional al valor del elemento de matriz
correspondiente.
Por lo tanto, el hilo que tiene la menor cantidad de tiempo para dormir se despierta
primero y el número se imprime y luego el segundo elemento menos y así
sucesivamente. El elemento más grande se despierta después de mucho tiempo y
luego el elemento se imprime al final. Por lo tanto, la salida es ordenada.
Todo este proceso de subprocesamiento múltiple ocurre en segundo plano y en el
núcleo del sistema operativo. No llegamos a saber nada sobre lo que sucede en
segundo plano, por lo tanto, este es un algoritmo de clasificación "misterioso".

Ejemplo: Supongamos (por conveniencia) que tenemos una computadora que es


tan lenta que lleva 3 segundos procesar cada elemento:
ENTRADA: 8 2 9

3s: dormir 8
6s: dormir 2
8s: "2" (2 se despierta así que imprímalo)
9s: dormir 9
11s: "8" (8 se despierta así que imprímalo)
18s: "9" (9 se despierta así que imprímalo)

SALIDA: 2 8 9
Implementación
Para implementar la ordenación del sueño, necesitamos funciones de
subprocesos múltiples, como _beginthread () y WaitForMultipleObjects () . Por
lo tanto, debemos incluir windows.h para usar estas funciones. Esto no se
compilará en IDE en línea . Debemos ejecutarlo en su PC (tenga en cuenta que
este código es para WINDOWS y no para LINUX).
Para realizar una ordenación del sueño, necesitamos crear subprocesos para
cada uno de los valores en la matriz de entrada. Hacemos esto usando la
función _beginthread ().
En cada uno de los hilos asignamos dos instrucciones:
1) Suspender : suspender este subproceso hasta arr [i] milisegundos (donde arr [i]
es el elemento de matriz al que está asociado este subproceso). Hacemos esto
usando la función Sleep (). La función Sleep (n) suspende la actividad asociada
con este hilo hasta 'n' milisegundos. Por lo tanto, si escribimos Suspender (1000),
significa que el hilo dormirá durante 1 segundo (1000 milisegundos = 1 segundo)

2) Imprimir: cuando el hilo 'se despierta' después de la suspensión, imprima el


elemento de matriz - arr [i] al que está asociado este hilo.
Después de crear los hilos, procesamos estos hilos. Hacemos esto
usando WaitForMultipleObjects ().

Limitaciones

1) Este algoritmo no funcionará para números negativos ya que un hilo no puede


dormir durante un período de tiempo negativo.
2) Dado que este algoritmo depende de los elementos de entrada, un gran número
en la matriz de entrada hace que este algoritmo se ralentice drásticamente (ya que
el hilo asociado con ese número tiene que dormir durante mucho
tiempo). Entonces, incluso si el elemento de matriz de entrada contiene solo 2
elementos, como- {1, 100000000}, entonces también tenemos que esperar una
duración mucho más larga para ordenar.

3) Este algoritmo no produce una salida ordenada correcta cada vez. Esto


generalmente ocurre cuando hay un número muy pequeño a la izquierda de un
número muy grande en la matriz de entrada.
Por ejemplo: {34, 23, 1, 12253, 9}.
La salida después de la ordenación del sueño es {9, 1, 23, 34, 1223}
También se produce una salida incorrecta cuando la matriz de entrada se ordena
inicialmente de forma inversa, como- {10, 9, 8, 7, 6, 5}.
La razón de una salida tan inesperada es porque se toma un tiempo entre el
escaneo a través de cada elemento, así como algunas otras operaciones del
sistema operativo (como insertar cada subproceso en una cola de prioridad para la
programación). No podemos simplemente ignorar el tiempo que tardan todas estas
cosas.
La salida anterior es solo un ejemplo.
Obviamente, las computadoras modernas no son tan lentas (tomar 3 segundos
para explorar cada elemento).
En realidad, ejecutar el modo de suspensión en una computadora moderna en la
matriz anterior proporciona la salida: {9, 5, 7, 10, 8, 6}

Ejercicio para los lectores


1) El algoritmo anterior intenta ordenarlo en orden ascendente. ¿Puede ordenar
una matriz de entrada en orden descendente utilizando la ordenación de
suspensión? Piensa en ello.
2) ¿Es un algoritmo de clasificación basado en comparación? ¿Cuántas
comparaciones hace este algoritmo?
[Respuesta: No, hace cero comparaciones]
3) ¿Podemos hacer una ordenación de sueño sin usar el encabezado windows.h y
sin usar la función Sleep ()?
[Una idea puede ser crear una cola prioritaria donde los elementos estén
organizados de acuerdo con el tiempo restante antes de despertarse e
imprimirse. El elemento al frente de la cola de prioridad será el primero en
despertarse. Sin embargo, la implementación no parece fácil. Piensa en eso.]

Espacio auxiliar
Todas las cosas se hacen mediante la cola de prioridad interna del sistema
operativo. Por lo tanto, el espacio auxiliar puede ser ignorado.

EJEMPLO DE APLICACIÓN DEL ALGORITMO

1.-C , 127 caracteres, una solución bastante obvia:

main(int c,char**v){
#pragma omp parallel for num_threads(c)
for(int i=1;i<c;++i){int x=atoi(v[i]);sleep(x);printf("%d ",x);}}
(Compilado gcc -std=c99 -fopenmp sort.ce ignorando todas las advertencias).

2.-Este algoritmo no produce una salida ordenada correcta cada vez. Esto


generalmente ocurre cuando hay un número muy pequeño a la izquierda de un
número muy grande en la matriz de entrada.
Por ejemplo: {34, 23, 1, 12253, 9}.
La salida después de la ordenación del sueño es {9, 1, 23, 34, 1223}
También se produce una salida incorrecta cuando la matriz de entrada se ordena
inicialmente de forma inversa, como- {10, 9, 8, 7, 6, 5}.
La razón de una salida tan inesperada es porque se toma un tiempo entre el
escaneo a través de cada elemento, así como algunas otras operaciones del
sistema operativo (como insertar cada subproceso en una cola de prioridad para la
programación). No podemos simplemente ignorar el tiempo que tardan todas estas
cosas.
Describimos esto usando el siguiente ejemplo:
Supongamos (por conveniencia) que tenemos una computadora que es
tan lento que toma 3 segundos para trabajar a través de cada
elemento:
ENTRADA: 10 9 8 7 6 5

3s: dormir 10
6s: dormir 9
9s: dormir 8
12s: dormir 7
13s: "10" (10 se despierta así que imprímalo)
15s: dormir 6
15s: "9" (9 se despierta así que imprímalo)
17s: "8" (8 se despierta así que imprímalo)
18s: dormir 5
19s: "7" (7 se despierta así que imprímalo)
21s: "6" (6 se despierta, así que imprímelo)
23s: "5" (5 se despierta así que imprímelo)

SALIDA: 10 9 8 7 6 5
La salida anterior es solo un ejemplo.
Obviamente, las computadoras modernas no son tan lentas (tomar 3 segundos
para explorar cada elemento).
En realidad, ejecutar el modo de suspensión en una computadora moderna en la
matriz anterior proporciona la salida: {9, 5, 7, 10, 8, 6}

CAPTURA O CODIGO DEL ALGORITMO

JAVA

/**
* @author Lakshmi
*/
class MyThread extends Thread
{
int id ;
Thread t;
String s;
MyThread(int id)
{
this.id = id;
this.start();
}
public MyThread(String string)
{
this.id = string.length();
s = string;
this.start();
}
public void run()
{
try {
Thread.sleep(id);
if(s!= "")
System.out.println(s);
else
System.out.println(id);
}
catch (InterruptedException e)
{
e.printStackTrace();
}
}
}
public class SleepSort
{
/**
* @param args
*/
public static void main(String[] args) {
//int a[]= {9,8,7,6};
//char a[] = {'c','v','a','d','b'};
String a[] = {"abc","def","aa"};
for(int i=0;i < a.length;i++) {
new MyThread(a[i]);
}
}
}
Java
Copy

Conclusión
La ordenación del sueño está más relacionada con el sistema operativo que
cualquier otro algoritmo de ordenación. Este algoritmo de clasificación es una
demostración perfecta de subprocesamiento múltiple y programación realizada por
el sistema operativo.
La frase "Ordenar mientras duerme" en sí misma suena muy singular. En general,
es un algoritmo divertido, vago y extraño. Pero como bien dijo alguien: "Si
funciona, entonces no es perezoso".

También podría gustarte