Autor Tema: Algoritmos de ordenación de datos.  (Leído 5042 veces)

0 Usuarios y 1 Visitante están viendo este tema.

Desconectado Picuino

  • Moderadores
  • DsPIC33
  • *****
  • Mensajes: 5892
    • Picuino
Algoritmos de ordenación de datos.
« en: 30 de Marzo de 2014, 07:09:45 »
ALGORITMOS DE ORDENACIÓN DE DATOS

Estos algoritmos resuelven el problema de ordenar una lista de datos de menor a mayor.
Por ejemplo, si tenemos la siguiente lista de datos:
   nombres = ["Ignacio", "David", "Paula" , "Gabriel", "Sara", "Ana"]

El resultado que se busca es ordenar la lista de menor a mayor (en orden alfabético):
   nombres = ["Ana", "David",  "Gabriel", "Ignacio", "Paula", "Sara"]


Ordenación en lenguaje C:
El lenguaje C suele tener implementada la función qsort() que realiza la ordenación de datos con el algoritmo Quicksort.
Este algoritmo es consiederado el algoritmo de propósito general más rápido y la implementación que ofrecen las librerías suele ser muy eficaz.
Sin embargo utilizar la librería estandar de C puede tener varios inconvenientes que se enumeran en el siguiente apartado.


Inconvenientes de utilizar librerías de ordenación:
Las librerías precompiladas suelen utilizar el método Quicksort y tienen los siguientes inconvenientes.
   1. El método Quicksort es recursivo y utiliza memoria RAM extra para ordenar una lista.
   2. El método Quicksort es más complejo que otros y necesita más memoria de programa (Flash).
   3. La función de ordenación dada por las librerías es secuencial y no retorna hasta que ha
       terminado de ordenar todos los datos.
       En sistemas de multitarea cooperativa (como un RTOS), este tiempo puede ser demasiado alto
       y es preferible implementar el algoritmo de ordenación de manera que devuelva el control al
       sistema cada poco tiempo.
   4. Para un número reducido de datos (hasta 10) Quicksort tiene un rendimiento semejante a otros
       algoritmos y consume mas memoria.
   5. En el caso de datos de acceso lento (memoria SD, Disco Duro) o de acceso secuencial (lista
       de datos enlazados), el algoritmo Mergesort puede ser más rápido que el algoritmo Quicksort.
       De hecho Perl 5.8 implementa el algoritmo Mergesort por defecto.
       Tambien el lenguaje Java utiliza Mergesort para ciertos tipos de datos.


Algoritmos analizados:
A continuación se presentan los algoritmos de ordenación que se van a analizar. Se han separado según su velocidad de ejecución.



Algoritmos lentos:
Los algoritmos lentos tienen una complejidad O(n^2), que significa que el número de operaciones que necesitan para ordenar la lista depende del cuadrado del número de elementos de la lista.
Para una lista de 500 elementos, los algoritmos lentos necesitan un número de operaciones proporcional a 500^2 = 250000.


Método de burbuja:  
En general es demasiado lento. Puede ser util para listas de datos casi ordenadas, caso en el que es bastante rápido, pero el algoritmo de selección directa será mejor en este caso.


Selección directa:
Se basa en buscar el elemento más pequeño dentro de la lista de elementos no ordenados y moverlo al final de una lista de datos ya ordenados.
La ventaja del método de selección es que siempre tarda lo mismo, independientemente de cómo estén ordenados los elementos en la lista. De hecho en ocasiones puede ser más lento que el algoritmo de burbuja (en el caso de elementos casi ordenados).


Inserción directa:
Se basa en tomar el primer elemento de una lista de datos no ordenados, buscar su lugar dentro de la lista de datos ya ordenados y moverlo a su lugar.
Es muy rápido cuando la lista de datos está casi ordenada, pero lento cuando la lista de datos está desordenada (igual que el método de burbuja).


Inserción binaria:
Es una variación del método anterior que mejora su velocidad. A la hora de buscar el sitio que le corresponde a un elemento dentro de la lista de elementos ya ordenados, puedo ir mirando uno a uno o hacerlo de forma binaria:
Miro en el medio de la lista de elementos ordenados. Si el elemento es mayor, descarto la mitad más pequeña de elementos y me quedo con la otra mitad de elementos. Repito el proceso hasta encontrar su sitio. Como la lista se divide por la mitad en cada búsqueda, es mucho más rápido que buscar de uno en uno.



Algoritmo Shellsort:
Este algoritmo está a medio camino entre los lentos y los rápidos. Es una mejora del algoritmo de inserción directa que pretende conseguir más velocidad en el caso de que los elementos estén desordenados comparando elementos que estén separados en varias posiciones. La separación se va haciendo más pequeña hasta que se ordena la lista por completo.
Al igual que el algoritmo de inserción, su tiempo de ejecución depende de la ordenación de los elementos de la lista.
Es muy dificil analizar su tiempo de ejecución, que depende de la implementación del algoritmo y de la ordenación de los datos. En cualquier caso mejora notablemente los algoritmos de ordenación lentos, sin llegar a la velocidad de los algoritmos rápidos.
La desventaja que presenta consiste en que resulta más difícil de implementar que los métodos anteriores.



Algoritmos rápidos:
Estos métodos tienen una complejidad computacional O(n·Log n). Esto significa que el número de operaciones necesarias para ordenar los elementos de la lista, es proporcional al número de elementos de la lista multiplicado por el logaritmo del número de elementos.
En el caso de querer ordenar 500 elementos, el número de operaciones necesarias para ordenar la lista será proporcional a  500·Log 500 = 3107 operaciones.


Algoritmo HeapSort:
Este método es bastante rápido y tiene una velocidad de ordenación constante, independientemente de cómo estén desordenados los datos.
Se basa en realizar dos tipos de operaciones. Primero se ordenan los datos en una estructura de montículo. A continuación se ordena la estructura en montículo en una lista ordenada.
Este método no es recursivo.


Algoritmo MergeSort:
Este es un algoritmo rápido un tanto especial. Su desventaja consiste en que necesita almacenar datos extras al ser recursivo. Como ventaja, es un algoritmo que se adapta muy bien y es más rápido que otros cuando hay que ordenar datos de acceso lento o acceso secuencial. Por ejemplo es un buen algoritmo para ordenar un fichero almacenado en el disco duro o una lista de datos enlazados.
Este algoritmo puede mejorarse añadiendo memoria intermedia o "memoria caché" en el proceso de mezcla de datos. Cuanto mayor sea esta memoria, más rápido será el algoritmo.


Algoritmo QuickSort:
Este es el que se considera método más rápido de ordenación de datos en memoria (sin necesidad de utilizar una memoria externa)
Para datos aleatorios tiene la mayor velocidad de todos los métodos comentados. Como inconveniente se puede comentar que la velocidad puede bajar mucho en ciertos casos particulares.
Otro inconveniente que presenta es que este es un algoritmo recursivo, por lo que será necesario guardar información extra sobre el punto en el que estamos trabajando. En microcontroladores con poca memoria esto puede ser una desventaja.

« Última modificación: 31 de Marzo de 2014, 13:40:06 por Picuino »

Desconectado Picuino

  • Moderadores
  • DsPIC33
  • *****
  • Mensajes: 5892
    • Picuino
Re: Algoritmos de ordenación de datos.
« Respuesta #1 en: 30 de Marzo de 2014, 19:27:02 »
Medida de la velocidad de ordenación:
Para poder comparar los algoritmos entre sí, independientemente de la implementación, se ha considerado que las operaciones que más pesan son las comparaciones entre elementos de la tabla y el movimiento de los datos. En la práctica la velocidad real del algoritmo dependerá de la implementación y de la carga computacional de cada una de esas operaciones. Si se intentan ordenar números de un byte, tanto la comparación como el movimiento de datos será muy rápido. En este caso las operaciones auxiliares con los índices pueden llevar más tiempo que el movimiento y comparación de datos.
En el caso de ordenar cadenas de texto enlazadas por punteros, la comparación puede ser lenta de manera que será esta operación la que lleve el mayor tiempo de ejecución. Por su parte, el movimiento de datos a través de punteros sera rápido.
Igualmente existen casos en los que el movimiento de datos es la operación más lenta que se lleva el mayor tiempo de ejecución.

Por estas razones la medida de la velocidad se ha realizado contando por separado:
     comparaciones
     movimientos de datos
     suma total de comparaciones y movimientos


Parámetros de la lista de datos:
La velocidad de ordenación depende de varios parámetros de la lista de datos. En las pruebas se han tenido en cuenta los siguientes:

Tamaño de la lista de datos:
Se han escogido tres tamaños. La lista de 10 elementos es suficientementes pequeña para que los algoritmos rápidos y lentos se confundan y presenten tiempos semejantes. La lista de 100 datos diferencia con claridad los algoritmos lentos y rápidos.
La lista de 1000 elementos tiene un tiempo de ejecución prohibitivo para algoritmos lentos.

Desorden de la lista de datos:
Se expresa en porcentaje y representa el número de elementos descolocados en la lista de datos.
100% significa que la lista de datos está ordenada de forma completamente aleatoria.
2% es el caso más ordenado y significa que sólo el 2% de los datos de la lista están fuera de su sitio. Por ejemplo en una lista de 1000 datos, 20 datos estarán fuera de su ubicación correcta. Esta lista se crea partiendo de una lista de números aleatorios ordenados, en la que se intercambian entre sí pares de números de ubicaciones aleatorias.

Se puede comprobar cómo, para ciertas combinaciones, los algoritmos de ordenación lentos pueden llegar a ser más rápidos que los algoritmos rápidos. Esto ocurre sobre todo en el caso de que los datos estén casi ordenados. En este caso el método de inserción binaria tiene un rendimiento excelente.


Programa para probar los métodos de ordenación:

El siguiente programa genera automáticamente listas de números aleatorios y de números semi-ordenados. A continuación ordena varias veces diferentes listas para calcular el tiempo medio de ordenación de cada algoritmo.

Código: Python
  1. # -*- coding: cp1252 -*-
  2. import random
  3. import copy
  4. import math
  5.  
  6.  
  7. ##################################################################
  8. #   ALGORITMOS DE ORDENACIÓN
  9. ##################################################################
  10.  
  11. def burbuja(datos):
  12.    """Algoritmo de ordenacion de datos Burbuja doble"""
  13.    global n_comps, n_moves
  14.    n_comps = n_moves = 0
  15.  
  16.    tam = len(datos)
  17.    for i in range(tam, 1, -1):
  18.       fin = 1
  19.       for j in range(1, i):
  20.          n_comps += 1
  21.          if datos[j-1] > datos[j]:
  22.             n_moves += 3
  23.             temp = datos[j]
  24.             datos[j] = datos[j-1]
  25.             datos[j-1] = temp
  26.             fin = 0
  27.       if fin:
  28.          break
  29.    return n_comps, n_moves
  30.  
  31.  
  32. def burbuja_doble(datos):
  33.    """Algoritmo de ordenacion de datos Burbuja doble"""
  34.    global n_comps, n_moves
  35.    n_comps = n_moves = 0
  36.  
  37.    tam = len(datos)
  38.    min_i = 1
  39.    max_i = tam
  40.    fin = 0
  41.    while(fin == 0 and min_i < max_i):
  42.       fin = 1
  43.       j = min_i
  44.       while(j < max_i):
  45.          n_comps += 1
  46.          if datos[j-1] > datos[j]:
  47.             n_moves += 3
  48.             temp = datos[j]
  49.             datos[j] = datos[j-1]
  50.             datos[j-1] = temp
  51.             fin = 0
  52.          j += 1
  53.       max_i -= 1
  54.       j = max_i
  55.       while(j >= min_i):
  56.          n_comps += 1
  57.          if datos[j-1] > datos[j]:
  58.             n_moves += 3
  59.             temp = datos[j]
  60.             datos[j] = datos[j-1]
  61.             datos[j-1] = temp
  62.             fin = 0
  63.          j -= 1
  64.       min_i += 1
  65.    return n_comps, n_moves
  66.  
  67.  
  68. def seleccion_directa(datos):
  69.    """Algoritmo de ordenacion de datos por Seleccion Directa"""
  70.    global n_comps, n_moves
  71.    n_comps = n_moves = 0
  72.    for i in range(0, len(datos)-1):
  73.       min_data = i
  74.       for j in range(i+1, len(datos)):
  75.          n_comps += 1
  76.          if datos[j] < datos[min_data]:
  77.             min_data = j
  78.       n_moves += 3
  79.       temp = datos[i]
  80.       datos[i] = datos[min_data]
  81.       datos[min_data] = temp
  82.    return n_comps, n_moves
  83.  
  84.  
  85. def insercion_binaria(data):
  86.    """Algoritmo de ordenacion de datos por insercion binaria"""
  87.    global n_comps, n_moves
  88.    n_comps = n_moves = 0
  89.  
  90.    for i in range(1, len(data)):
  91.       n_moves += 1
  92.       temp = data[i]
  93.      
  94.       pos1 = 0
  95.       pos2 = i-1
  96.       while(pos1 <= pos2):
  97.          medio = (pos1 + pos2) // 2
  98.          n_comps += 1
  99.          if temp < data[medio]:
  100.             pos2 = medio - 1
  101.          else:
  102.             pos1 = medio + 1
  103.       j = i - 1
  104.       while (j >= pos1):
  105.           n_moves += 1
  106.           data[j+1] = data[j]
  107.           j -= 1
  108.       n_moves += 1
  109.       data[pos1] = temp
  110.    return n_comps, n_moves
  111.  
  112.  
  113. def shellsort(datos):
  114.    """Algoritmo de ordenacion de datos Shellsort"""
  115.    global n_comps, n_moves
  116.    n_comps = n_moves = 0
  117.  
  118.    p = len(datos) // 2
  119.    while(p>0):
  120.       for i in range(p, len(datos)):
  121.          n_moves += 1
  122.          temp = datos[i]
  123.          j = i
  124.  
  125.          while (j >= p and temp < datos[j-p]):
  126.             n_comps += 1
  127.             n_moves += 1
  128.             datos[j] = datos[j - p]
  129.             j -= p
  130.          n_comps += 1
  131.          n_moves += 1
  132.          datos[j] = temp
  133.          
  134.       if (p == 2):
  135.          p = 1
  136.       else:
  137.          p = int(p / 2.2)
  138.  
  139.    return n_comps, n_moves
  140.  
  141.  
  142. def heapsort(datos):
  143.    """Algoritmo de ordenacion de datos Heapsort"""
  144.    global n_comps, n_moves
  145.    n_comps = n_moves = 0
  146.  
  147.    # Crea la estructura de monticulo
  148.    tam = len(datos)
  149.    puntero = int((len(datos)-1)/2)
  150.    while puntero>=0:
  151.       cribar(datos, puntero, tam-1)
  152.       puntero -= 1
  153.  
  154.    # Ordena monticulo
  155.    puntero = len(datos)-1
  156.    while puntero>0:
  157.       n_moves += 3
  158.       temp = datos[puntero]
  159.       datos[puntero] = datos[0]
  160.       datos[0] = temp
  161.       puntero -= 1
  162.       cribar(datos, 0, puntero)
  163.    return n_comps, n_moves
  164.    
  165.  
  166. def cribar(datos, datos_min, datos_max):
  167.    global n_comps, n_moves
  168.    down = datos_min * 2 + 1
  169.    if (down > datos_max):
  170.       return
  171.    n_moves += 1
  172.    temp = datos[datos_min]
  173.    while down <= datos_max:
  174.       if down < datos_max:
  175.          n_comps += 1
  176.          if datos[down+1] > datos[down]:
  177.             down += 1
  178.       n_comps += 1
  179.       if temp > datos[down]:
  180.          break
  181.       n_moves += 1
  182.       datos[datos_min] = datos[down]
  183.       datos_min = down
  184.       down = down * 2 + 1
  185.    n_moves += 1
  186.    datos[datos_min] = temp
  187.  
  188.  
  189. def quicksort(datos):
  190.    """Algoritmo de ordenacion de datos Quicksort"""
  191.    global n_comps, n_moves
  192.    n_comps = n_moves = 0
  193.    quicksort_2(datos, 0, len(datos)-1)
  194.    return n_comps, n_moves
  195.  
  196.  
  197. def quicksort_2(datos, min_pos, max_pos):
  198.    """Funcion auxiliar del algoritmo de ordenacion Quicksort"""
  199.    global n_comps, n_moves
  200.  
  201.    # Condicion de salida recusiva
  202.    if min_pos >= max_pos:
  203.       return
  204.  
  205.    imin_pos = min_pos
  206.    imax_pos = max_pos
  207.    mid = datos[int((min_pos+max_pos)/2)]
  208.  
  209.    while imin_pos <= imax_pos:
  210.       while datos[imin_pos] < mid:
  211.          n_comps += 1
  212.          imin_pos += 1
  213.       n_comps += 1
  214.  
  215.       while datos[imax_pos] > mid:
  216.          n_comps += 1
  217.          imax_pos -=1
  218.       n_comps += 1
  219.  
  220.       if imin_pos == imax_pos:
  221.          imin_pos += 1
  222.          imax_pos -= 1
  223.          break
  224.  
  225.       if imin_pos < imax_pos:
  226.          n_moves +=3
  227.          temp = datos[imin_pos]
  228.          datos[imin_pos] = datos[imax_pos]
  229.          datos[imax_pos] = temp
  230.          imin_pos += 1
  231.          imax_pos -=1
  232.  
  233.    # Ordena primero el subconjunto mas pequenio para ahorrar saltos recursivos
  234.    if imax_pos-min_pos < max_pos-imin_pos:
  235.       quicksort_2(datos, min_pos, imax_pos)
  236.       quicksort_2(datos, imin_pos, max_pos)
  237.    else:
  238.       quicksort_2(datos, imin_pos, max_pos)
  239.       quicksort_2(datos, min_pos, imax_pos)
  240.  
  241.  
  242. def mergesort(datos, cache):
  243.    "Algoritmo de ordenacion Mergesort"
  244.    global n_comps, n_moves, cache_tam
  245.    n_comps = n_moves = 0
  246.    cache_tam = cache
  247.    m_sort(datos, 0, len(datos)-1)
  248.    return n_comps, n_moves
  249.  
  250.  
  251. #  Algoritmo de ordenacion Mergesort
  252. def m_sort(datos, inicio, fin):
  253.    global n_comps, n_moves
  254.    
  255.    # Condición de salida recursiva
  256.    if fin <= inicio + 1:
  257.       n_comps += 1
  258.       if datos[fin] < datos[inicio]:
  259.           n_moves += 3
  260.           temp = datos[fin]
  261.           datos[fin] = datos[inicio]
  262.           datos[inicio] = temp
  263.       return
  264.    mid = int((inicio+fin)/2)
  265.    m_sort(datos, inicio, mid)
  266.    m_sort(datos, mid+1, fin)
  267.    merge_temp(datos, inicio, mid+1, fin)
  268.    
  269.  
  270. #  Funcion auxiliar merge con pequeña memoria extra
  271. def merge_temp(datos, init1, init2, fin2):
  272.    global n_comps, n_moves
  273.    
  274.    memo_temp = cache_tam       # Memoria extra para realizar mezcla
  275.    temp = range(memo_temp)
  276.    fin1 = init2 - 1
  277.    i = 0
  278.    while init1 <= fin1 and init2 <= fin2:
  279.       n_comps += 1
  280.       n_moves += 1
  281.       if datos[init2] < datos[init1]:
  282.          temp[i] = datos[init2]
  283.          init2 += 1
  284.       else:
  285.          temp[i] = datos[init1]
  286.          init1 += 1
  287.       i += 1
  288.       if i >= memo_temp:
  289.          inserta(datos, temp, i, init1, fin1, init2, fin2)
  290.          init1 = init1 + (init2 - 1 - fin1)
  291.          fin1 = init2 - 1
  292.          i = 0
  293.    inserta(datos, temp, i, init1, fin1, init2, fin2)
  294.  
  295.  
  296. # Funcion que inserta la datos temp de longitud len
  297. # al comienzo de dos listas semiordenadas
  298. def inserta(datos, temp, leng, init1, fin1, init2, fin2):
  299.    global n_comp, n_moves
  300.    init_copy = init1 + (init2 - fin1 - 1) - leng
  301.    j = init2 - 1
  302.    while fin1 >= init1:
  303.       n_moves += 1
  304.       datos[j] = datos[fin1]
  305.       j -= 1
  306.       fin1 -= 1
  307.    
  308.    init1 = init_copy + leng
  309.    j = 0
  310.    while init_copy < init1:
  311.       n_moves += 1
  312.       datos[init_copy] = temp[j]
  313.       init_copy += 1
  314.       j += 1
  315.      
  316.  
  317. ##################################################################
  318. #   FUNCIONES AUXILIARES
  319. ##################################################################
  320.  
  321.  
  322. def desordena(datos, pares, seed=None):
  323.    """Intercambia entre si las posiciones de num parejas de
  324.      elementos de forma aleatoria dentro de la lista de datos"""
  325.    tam = len(datos)-1
  326.    if seed:
  327.       random.seed(seed)
  328.    for i in range(pares):
  329.        n1 = n2 = 0
  330.        while(n1 == n2):
  331.           n1 = int(random.uniform(0, tam) + 0.5)
  332.           n2 = int(random.uniform(0, tam) + 0.5)
  333.        temp = datos[n1]
  334.        datos[n1] = datos[n2]
  335.        datos[n2] = temp
  336.  
  337.  
  338. def datos_aleatorios(tam, rango=9999):
  339.    """Genera una lista de numeros enteros aleatorios en el
  340.      rango [0, rango]"""
  341.    return [int(random.uniform(0, rango) + 0.5) for i in range(tam)]
  342.  
  343.  
  344. def is_sorted(datos):
  345.    """Comprueba si la lista de datos se encuentra ordenada
  346.      de menor a mayor. Devuelve True en caso afirmativo"""
  347.    tam = len(datos)
  348.    old = datos[0]
  349.    for i in datos:
  350.       if i < old:
  351.          raise Exception("NOT SORTED")
  352.       i = old
  353.    return True
  354.  
  355.  
  356. def average_stats(sort, tam, sorted_percent, loops):
  357.    """Tiempo medio de ejecución de un algoritmo de ordenación de datos"""
  358.    n_comps_avg = n_moves_avg = total_avg = 0
  359.    loops = int(loops)
  360.    for i in range(loops):
  361.       datos = datos_aleatorios(tam)
  362.       if sorted_percent < 100:
  363.          quicksort(datos)
  364.          pares = tam * sorted_percent/200
  365.          desordena(datos, pares)
  366.       n_comps, n_moves = sort(datos)
  367.       if not is_sorted(datos):
  368.          print "ERROR DE ORDENACION"
  369.       n_comps_avg += n_comps
  370.       n_moves_avg += n_moves
  371.       total_avg += n_comps + n_moves
  372.    return n_comps_avg/loops, n_moves_avg/loops, total_avg/loops,
  373.  
  374.  
  375. def report_1():
  376.    loops = 100
  377.    for tam in [10, 100, 1000]:
  378.       for unsorted_percent in [2, 10, 20, 50, 100]:
  379.          if tam * unsorted_percent/200 < 1:
  380.             continue
  381.          print "\n[hr]\n"
  382.          print "[b]Número de elementos en la lista  =", tam, "[/b]"
  383.          print "[b]Porcentaje de datos desordenados = %d%%[/b]" % unsorted_percent
  384.          print "\n[table]"
  385.          print "[tr][td][b]Método  [/b][/td][td][b]  Comparaciones  [/b][/td][td][b]  Movimientos  [/b][/td][td][b]  Total  [/b][/td][td][b]     Total/n  [/b][/td][/tr]"
  386.          for sort, name in sort_types:
  387.             n_comps, n_moves, total = average_stats(sort, tam, unsorted_percent, loops=loops)
  388.             print "[tr][td]%-20s[/td][td]  %8d[/td][td]  %8d[/td][td]%8d[/td][td]      %4.2f[/td][/tr]" % (name, n_comps, n_moves, total, float(total)/tam)
  389.          print "[/table]"
  390.    
  391.    
  392. def report_2():
  393.    loops = 100
  394.    for sort, name in sort_types:
  395.       print "\n[hr]\n"
  396.       print "[b]Método de ordenación :", name, "[/b]"
  397.       print "\n[table]"
  398.       print "[tr][td][b]Elementos  [/b][/td][td][b]Desorden [/b][/td][td][b]  Comparaciones  [/b][/td][td][b]  Movimientos  [/b][/td][td][b]  Total  [/b][/td][td][b]     Total/n  [/b][/td][/tr]"
  399.       for tam in [10, 100, 1000]:
  400.          for unsorted_percent in [2, 10, 20, 50, 100]:
  401.             if tam * unsorted_percent/200 < 1:
  402.                continue
  403.             n_comps, n_moves, total = average_stats(sort, tam, unsorted_percent, loops=loops)
  404.             print "[tr][td]%5d[/td][td]  %3d%%[/td][td]  %8d[/td][td]  %8d[/td][td]%8d[/td][td]      %4.2f[/td][/tr]" % (tam, unsorted_percent, n_comps, n_moves, total, float(total)/tam)
  405.       print "[/table]"
  406.  
  407. ##################################################################
  408. #   PROGRAMA PRINCIPAL
  409. ##################################################################
  410.  
  411. sort_types = [
  412.     [burbuja,           "Burbuja"],
  413.     [burbuja_doble,     "Burbuja doble"],
  414.     [seleccion_directa, "Selección Directa"],
  415.     [insercion_binaria, "Inserción Binaria"],
  416.     [shellsort,         "Shellsort"],
  417.     [heapsort,          "Heapsort"],
  418.     [lambda(d): mergesort(d, cache=10),"MergeSort (cache=10)"],
  419.     [lambda(d): mergesort(d, cache=30),"MergeSort (cache=30)"],
  420.     [quicksort,         "QuickSort"],
  421. ]
  422.  
  423. random.seed(1)
  424. report_1()
  425. report_2()

Saludos.
« Última modificación: 31 de Marzo de 2014, 15:26:43 por Picuino »

Desconectado Picuino

  • Moderadores
  • DsPIC33
  • *****
  • Mensajes: 5892
    • Picuino
Re: Algoritmos de ordenación de datos.
« Respuesta #2 en: 30 de Marzo de 2014, 19:33:07 »
Resultados:



Número de elementos en la lista  = 10
Porcentaje de datos desordenados = 20%

Método    Comparaciones    Movimientos    Total       Total/n 
Burbuja                     30        17      47      4.70
Burbuja doble               32        17      49      4.90
Selección Directa           45        27      72      7.20
Inserción Binaria           24        23      47      4.70
Shellsort                   25        47      73      7.30
Heapsort                    40        73     114      11.40
MergeSort cache=10           23        38      61      6.10
MergeSort cache=30           22        37      60      6.00
QuickSort                   31         3      34      3.40



Número de elementos en la lista  = 10
Porcentaje de datos desordenados = 50%

Método    Comparaciones    Movimientos    Total       Total/n 
Burbuja                     34        29      63      6.30
Burbuja doble               35        28      64      6.40
Selección Directa           45        27      72      7.20
Inserción Binaria           24        27      51      5.10
Shellsort                   27        49      77      7.70
Heapsort                    40        73     113      11.30
MergeSort cache=10           24        41      65      6.50
MergeSort cache=30           23        41      64      6.40
QuickSort                   33         6      39      3.90



Número de elementos en la lista  = 10
Porcentaje de datos desordenados = 100%

Método    Comparaciones    Movimientos    Total       Total/n 
Burbuja                     42        68     110      11.00
Burbuja doble               46        64     110      11.00
Selección Directa           45        27      72      7.20
Inserción Binaria           22        40      62      6.20
Shellsort                   33        55      89      8.90
Heapsort                    38        70     109      10.90
MergeSort cache=10           24        48      72      7.20
MergeSort cache=30           24        48      72      7.20
QuickSort                   41        23      65      6.50



Número de elementos en la lista  = 100
Porcentaje de datos desordenados = 2%

Método    Comparaciones    Movimientos    Total       Total/n 
Burbuja                   2692       209    2901      29.01
Burbuja doble              392       215     607      6.07
Selección Directa         4950       297    5247      52.47
Inserción Binaria          572       255     828      8.28
Shellsort                  469       882    1352      13.52
Heapsort                  1080      1131    2212      22.12
MergeSort cache=10          414       863    1278      12.78
MergeSort cache=30          419       737    1156      11.56
QuickSort                  607         4     612      6.12



Número de elementos en la lista  = 100
Porcentaje de datos desordenados = 10%

Método    Comparaciones    Movimientos    Total       Total/n 
Burbuja                   4225       958    5183      51.83
Burbuja doble              858       929    1787      17.87
Selección Directa         4950       297    5247      52.47
Inserción Binaria          548       515    1063      10.63
Shellsort                  572       985    1558      15.58
Heapsort                  1078      1126    2204      22.04
MergeSort cache=10          481      1036    1518      15.18
MergeSort cache=30          480       881    1362      13.62
QuickSort                  614        22     636      6.36



Número de elementos en la lista  = 100
Porcentaje de datos desordenados = 20%

Método    Comparaciones    Movimientos    Total       Total/n 
Burbuja                   4450      1659    6110      61.10
Burbuja doble             1285      1773    3058      30.58
Selección Directa         4950       297    5247      52.47
Inserción Binaria          537       758    1296      12.96
Shellsort                  643      1056    1699      16.99
Heapsort                  1074      1121    2195      21.95
MergeSort cache=10          516      1143    1659      16.59
MergeSort cache=30          517       978    1495      14.95
QuickSort                  623        55     678      6.78



Número de elementos en la lista  = 100
Porcentaje de datos desordenados = 50%

Método    Comparaciones    Movimientos    Total       Total/n 
Burbuja                   4726      3528    8255      82.55
Burbuja doble             2154      3506    5660      56.60
Selección Directa         4950       297    5247      52.47
Inserción Binaria          536      1345    1881      18.81
Shellsort                  739      1152    1892      18.92
Heapsort                  1059      1107    2167      21.67
MergeSort cache=10          548      1291    1840      18.40
MergeSort cache=30          550      1088    1638      16.38
QuickSort                  674       149     823      8.23



Número de elementos en la lista  = 100
Porcentaje de datos desordenados = 100%

Método    Comparaciones    Movimientos    Total       Total/n 
Burbuja                   4883      7345   12228      122.28
Burbuja doble             3974      7371   11345      113.45
Selección Directa         4950       297    5247      52.47
Inserción Binaria          531      2668    3200      32.00
Shellsort                  842      1255    2097      20.97
Heapsort                  1027      1075    2103      21.03
MergeSort cache=10          569      1499    2068      20.68
MergeSort cache=30          570      1203    1774      17.74
QuickSort                  877       468    1346      13.46



Número de elementos en la lista  = 1000
Porcentaje de datos desordenados = 2%

Método    Comparaciones    Movimientos    Total       Total/n 
Burbuja                 447704     19444  467148      467.15
Burbuja doble            14943     20043   34986      34.99
Selección Directa       499500      2997  502497      502.50
Inserción Binaria         8705      8197   16903      16.90
Shellsort                 9379     16469   25849      25.85
Heapsort                 17552     14681   32234      32.23
MergeSort cache=10         6590     36074   42664      42.66
MergeSort cache=30         6604     19324   25928      25.93
QuickSort                 9163       198    9362      9.36



Número de elementos en la lista  = 1000
Porcentaje de datos desordenados = 10%

Método    Comparaciones    Movimientos    Total       Total/n 
Burbuja                 489915     92511  582427      582.43
Burbuja doble            53474     93141  146616      146.62
Selección Directa       499500      2997  502497      502.50
Inserción Binaria         8617     33073   41691      41.69
Shellsort                11136     18226   29362      29.36
Heapsort                 17475     14637   32112      32.11
MergeSort cache=10         7661     40772   48433      48.43
MergeSort cache=30         7672     22429   30102      30.10
QuickSort                 9380       589    9970      9.97



Número de elementos en la lista  = 1000
Porcentaje de datos desordenados = 20%

Método    Comparaciones    Movimientos    Total       Total/n 
Burbuja                 494591    171787  666378      666.38
Burbuja doble            94950    174906  269857      269.86
Selección Directa       499500      2997  502497      502.50
Inserción Binaria         8605     59879   68484      68.48
Shellsort                11937     19027   30964      30.96
Heapsort                 17401     14581   31983      31.98
MergeSort cache=10         8069     44414   52484      52.48
MergeSort cache=30         8076     24250   32326      32.33
QuickSort                 9727      1118   10846      10.85



Número de elementos en la lista  = 1000
Porcentaje de datos desordenados = 50%

Método    Comparaciones    Movimientos    Total       Total/n 
Burbuja                 497105    356976  854081      854.08
Burbuja doble           185651    356375  542026      542.03
Selección Directa       499500      2997  502497      502.50
Inserción Binaria         8597    120512  129109      129.11
Shellsort                12831     19921   32753      32.75
Heapsort                 17235     14439   31675      31.68
MergeSort cache=10         8491     51510   60001      60.00
MergeSort cache=30         8485     27311   35796      35.80
QuickSort                10447      2571   13019      13.02



Número de elementos en la lista  = 1000
Porcentaje de datos desordenados = 100%

Método    Comparaciones    Movimientos    Total       Total/n 
Burbuja                 498442    748549 1246991      1246.99
Burbuja doble           379724    747818 1127542      1127.54
Selección Directa       499500      2997  502497      502.50
Inserción Binaria         8588    250930  259519      259.52
Shellsort                13705     20795   34500      34.50
Heapsort                 16858     14079   30937      30.94
MergeSort cache=10         8732     65522   74254      74.25
MergeSort cache=30         8731     32521   41253      41.25
QuickSort                13402      6987   20390      20.39
« Última modificación: 30 de Marzo de 2014, 20:02:53 por Picuino »

Desconectado Picuino

  • Moderadores
  • DsPIC33
  • *****
  • Mensajes: 5892
    • Picuino
Re: Algoritmos de ordenación de datos.
« Respuesta #3 en: 30 de Marzo de 2014, 20:04:40 »
Resultados:



Método de ordenación  = Burbuja

Elementos  Desorden  Comparaciones    Movimientos    Total       Total/n  
 10   20%        30        17      47      4.70
 10   50%        33        27      60      6.00
 10  100%        42        69     111      11.10
100    2%      2559       197    2757      27.57
100   10%      4188       901    5090      50.90
100   20%      4502      1732    6235      62.35
100   50%      4748      3486    8234      82.34
100  100%      4887      7535   12422      124.22
1000    2%    459833     20628  480461      480.46
1000   10%    490240     92790  583030      583.03
1000   20%    494403    173111  667515      667.51
1000   50%    497181    354243  851425      851.42
1000  100%    498597    748970 1247568      1247.57



Método de ordenación  = Burbuja doble

Elementos  Desorden  Comparaciones    Movimientos    Total       Total/n  
 10   20%        32        15      47      4.70
 10   50%        35        28      64      6.40
 10  100%        45        63     109      10.90
100    2%       392       172     564      5.64
100   10%       839       955    1795      17.95
100   20%      1301      1767    3068      30.68
100   50%      2221      3529    5750      57.50
100  100%      4012      7500   11513      115.13
1000    2%     14982     20184   35167      35.17
1000   10%     54225     92782  147008      147.01
1000   20%     94035    172369  266405      266.40
1000   50%    184938    354263  539202      539.20
1000  100%    380921    751009 1131931      1131.93



Método de ordenación  = Selección Directa

Elementos  Desorden  Comparaciones    Movimientos    Total       Total/n  
 10   20%        45        27      72      7.20
 10   50%        45        27      72      7.20
 10  100%        45        27      72      7.20
100    2%      4950       297    5247      52.47
100   10%      4950       297    5247      52.47
100   20%      4950       297    5247      52.47
100   50%      4950       297    5247      52.47
100  100%      4950       297    5247      52.47
1000    2%    499500      2997  502497      502.50
1000   10%    499500      2997  502497      502.50
1000   20%    499500      2997  502497      502.50
1000   50%    499500      2997  502497      502.50
1000  100%    499500      2997  502497      502.50



Método de ordenación  = Inserción Binaria

Elementos  Desorden  Comparaciones    Movimientos    Total       Total/n  
 10   20%        24        23      48      4.80
 10   50%        23        28      52      5.20
 10  100%        22        39      62      6.20
100    2%       572       265     838      8.38
100   10%       547       508    1055      10.55
100   20%       537       768    1306      13.06
100   50%       535      1374    1910      19.10
100  100%       531      2654    3185      31.85
1000    2%      8696      8396   17092      17.09
1000   10%      8616     33142   41759      41.76
1000   20%      8604     58935   67539      67.54
1000   50%      8596    119673  128270      128.27
1000  100%      8586    251738  260324      260.32



Método de ordenación  = Shellsort

Elementos  Desorden  Comparaciones    Movimientos    Total       Total/n  
 10   20%        25        47      72      7.20
 10   50%        28        50      78      7.80
 10  100%        33        55      89      8.90
100    2%       462       875    1337      13.37
100   10%       576       989    1565      15.65
100   20%       646      1059    1706      17.06
100   50%       740      1153    1894      18.94
100  100%       838      1251    2090      20.90
1000    2%      9386     16476   25862      25.86
1000   10%     11176     18266   29443      29.44
1000   20%     11914     19004   30918      30.92
1000   50%     12833     19923   32757      32.76
1000  100%     13697     20787   34484      34.48



Método de ordenación  = Heapsort

Elementos  Desorden  Comparaciones    Movimientos    Total       Total/n  
 10   20%        40        73     114      11.40
 10   50%        40        72     113      11.30
 10  100%        38        70     109      10.90
100    2%      1080      1131    2212      22.12
100   10%      1078      1126    2205      22.05
100   20%      1073      1120    2194      21.94
100   50%      1061      1109    2170      21.70
100  100%      1027      1075    2102      21.02
1000    2%     17551     14679   32230      32.23
1000   10%     17478     14641   32119      32.12
1000   20%     17403     14581   31984      31.98
1000   50%     17235     14440   31676      31.68
1000  100%     16850     14076   30927      30.93



Método de ordenación : MergeSort (cache=10)    

Elementos  Desorden  Comparaciones    Movimientos    Total       Total/n  
 10   20%        23        37      60      6.00
 10   50%        24        41      65      6.50
 10  100%        24        47      72      7.20
100    2%       421       879    1301      13.01
100   10%       483      1039    1523      15.23
100   20%       514      1139    1653      16.53
100   50%       549      1295    1845      18.45
100  100%       569      1499    2069      20.69
1000    2%      6577     36052   42630      42.63
1000   10%      7657     40727   48384      48.38
1000   20%      8075     44414   52490      52.49
1000   50%      8485     51511   59996      60.00
1000  100%      8729     65438   74168      74.17



Método de ordenación : MergeSort (cache=30)    

Elementos  Desorden  Comparaciones    Movimientos    Total       Total/n  
 10   20%        23        37      61      6.10
 10   50%        23        41      64      6.40
 10  100%        24        47      71      7.10
100    2%       414       727    1142      11.42
100   10%       479       878    1357      13.57
100   20%       515       973    1488      14.88
100   50%       549      1087    1637      16.37
100  100%       569      1204    1773      17.73
1000    2%      6627     19377   26005      26.00
1000   10%      7659     22393   30052      30.05
1000   20%      8073     24231   32305      32.30
1000   50%      8493     27346   35839      35.84
1000  100%      8732     32502   41234      41.23



Método de ordenación  = QuickSort

Elementos  Desorden  Comparaciones    Movimientos    Total       Total/n  
 10   20%        31         3      34      3.40
 10   50%        32         6      39      3.90
 10  100%        40        22      63      6.30
100    2%       607         4     611      6.11
100   10%       614        23     638      6.38
100   20%       621        54     676      6.76
100   50%       676       151     828      8.28
100  100%       885       462    1348      13.48
1000    2%      9175       198    9373      9.37
1000   10%      9417       577    9994      9.99
1000   20%      9730      1128   10858      10.86
1000   50%     10444      2572   13017      13.02
1000  100%     13324      7009   20334      20.33



Saludos.
« Última modificación: 30 de Marzo de 2014, 20:11:12 por Picuino »

Desconectado Picuino

  • Moderadores
  • DsPIC33
  • *****
  • Mensajes: 5892
    • Picuino
Re: Algoritmos de ordenación de datos.
« Respuesta #4 en: 31 de Marzo de 2014, 09:31:20 »
Métodos de ordenación no comparativos:
Existen algoritmos que permiten ordenar los datos de forma más rápida aún, si se cumplen ciertas condiciones:
   1. Los datos deben estar uniformemente distribuidos y se deben poder clasificar en grupos con facilidad.
   2. Se debe disponer de memoria extra.
El algoritmo de ordenación por casilleros es una generalización del algoritmo Pigeonhole sort.
Está basado en clasificar los datos a ordenar en grupos que se encuentren dentro de un rango. Posteriormente los rangos se ordenan con otro algorimo.
Un ejemplo cotidiano sería ordenar una baraja separando primero oros, copas, espadas y bastos (o picas, corazones, diamantes y tréboles) para ordenar posteriormente cada uno de los 4 montones por separado.

En el caso de ordenar palabras, se puede utilizar la primera letra como distintivo de grupo.
A la hora de ordenar números del 0 al 9999, se puede utilizar la cifra decimal de mayor valor (o los bits más altos en binario) para hacer una clasificacion rápida.
« Última modificación: 31 de Marzo de 2014, 09:35:00 por Picuino »

Desconectado fabianjsm

  • PIC18
  • ****
  • Mensajes: 255
    • fabianjsm is on twitter
Re: Algoritmos de ordenación de datos.
« Respuesta #5 en: 13 de Junio de 2014, 04:19:42 »
Gracias Picuino, un gran aporte que ahorra mucho tiempo de pruebas!
@fabianjsm is on twitter

Desconectado manutek

  • Colaborador
  • PIC24F
  • *****
  • Mensajes: 555
Re: Algoritmos de ordenación de datos.
« Respuesta #6 en: 13 de Junio de 2014, 18:53:24 »
Muy interesante gracias ¡¡¡¡
No es la conciencia del hombre la que determina su ser, sino, por el contrario, es su ser social el que determina su conciencia

Conectado RedPic

  • Administrador
  • DsPIC33
  • *******
  • Mensajes: 5552
    • Picmania by Redraven
Re: Algoritmos de ordenación de datos.
« Respuesta #7 en: 13 de Junio de 2014, 19:04:56 »
¡¡¡Guau!!! Te felicito Picuino por este magnífico trabajo  :mrgreen:
Contra la estupidez los propios dioses luchan en vano. Schiller
Mi Güeb : Picmania


 

anything