Programación II Práctico 4 Práctico 4 Grupo 103 Fecha: 09/10/2009 Documentación Programación II Práctico 4 Introducción Este práctico consiste en analizar diferentes métodos de clasificación. Los mismos deberán ser comparados bajo diferentes condiciones como ser distintas cantidades de elementos y distintos ordenaciones prefijadas. Se deberá desarrollar el programa de manera tal que los errores en las mediciones sean menores al 1%, utilizando estrategias dadas para aumentar la precisión de las corridas, y para independizar los tiempos de las máquinas en las cuales se miden los resultados. Los datos obtenidos serán luego analizados en planillas de cálculo y graficados para un mejor análisis. Presentación de Algoritmos Shell sort: Es una mejora a los algoritmos de selección directa que se obtiene al hacer intercambios en grandes intervalos y luego reduciendo estos intervalos. De esta manera se aprovecha el hecho de que los algoritmos de selección trabajan mejor con datos semi-ordenados. El orden de ejecución de este algoritmo es O(nlog2(n)) ordenarPorShellSort COM incrementos = {3223, 350, 51, 10, 3, 1} DESDE (posIncrActual = 0 HASTA incrementos.largo) HACER inc <-- incrementos[posIncrActual] SI(inc < (datosParaClasificar.largo)/2) ENTONCES DESDE (i = inc i HASTA datosParaClasificar.largo) HACER j <-- i - inc MIENTRAS (j>=0) HACER SI (aux[j]> datosParaClasificar [j + inc]) ENTONCES intercambiar(datosParaClasificar, j, j + inc) j <-- j-1 FINSI FINMIENTRAS FINDESDE FINSI FINDESDE DEVOLVER datosParaClasificar FIN La ordenación por inserción es una ordenación sencilla que compara cada dato con los demás y lo inserta en el lugar correcto. El orden de este algoritmo es O(n2) ordenarPorInsercion COM SI(datosParaClasificar<>NULO) HACER DESDE(i=1 HASTA datosParaClasificar.largo) HACER j <-- i-1 MIENTRAS((j>=0) AND (aux[j] > datosParaClasificar [j+1])) HACER intercambiar(datosParaClasificar, j, j+1) j <-- j-1 FINMIENTRAS FINDESDE DEVOLVER datosParaClasificar Documentación Programación II Práctico 4 FINSI DEVOLVER NULO FIN CuentaPorComparacion COM DESDE(i=1 HASTA datosParaClasificar.largo - 1) HACER cuenta[i]=0 FINDESDE DESDE(i=datosParaClasificar.largo - 1 HASTA 1) HACER DESDE(j = i-1 HASTA 0) HACER SI(datosParaClasificar[i] < datosParaClasificar[j]) ENTONCES incrementar(cuenta, j) SINO incrementar(cuenta, i) FINSI FINDESDE DESDE(i=0 HASTA datosParaClasificar.largo) HACER ordenado[cuenta[i]] = datosParaClasificar[i] FINDESDE DEVOLVER ordenado FINDESDE FIN La ordenación por inserción es una ordenación sencilla que compara datos de a pares y los intercambia si están en orden incorrecto. El orden de este algoritmo es O(n2) ordenarPorBurbuja COM DESDE(i=0 HASTA datosParaClasificar.largo-1) HACER DESDE (j= datosParaClasificar.largo-1 HASTA i+1) HACER SI (datosParaClasificar [j]< datosParaClasificar [j-1]) ENTONCES intercambiar(datosParaClasificar, j, j-1) FINSI FINDESDE FINDESDE DEVOLVER datosParaClasificar FIN ordenarPorSeleccionDirecta COM DESDE(i=0 HASTA aux.largo-1) HACER menor = datosParaClasificar [i] indiceMenor = i DESDE(j=i+1 HASTA datosParaClasificar.largo) HACER SI(datosParaClasificar [j]<menor) ENTONCES menor <-- datosParaClasificar [j] indiceMenor <-- j FINSI FINDESDE intercambiar(datosParaClasificar, i, indiceMenor) FINDESDE DEVOLVER datosParaClasificar FIN Documentación Programación II Práctico 4 El algoritmo de quick sort ordena los datos utilizando un dato como pivote y luego particionando el array en dos partes. De un lado coloca los datos menores al pivote y del otro lado los demás datos. Esto se repite hasta que el array está ordenado. El orden de ejecución de este algoritmo es O(nlog(n)) ordenarPorQuickSort COM izquierda = i derecha = j posPivote = encuentraPivote(izquierda, derecha, datosParaClasificar) SI (posPivote >= 0) MIENTRAS (izquierda <= derecha) HACER MIENTRAS ((datosParaClasificar[izquierda] < pivote)AND(izquierda < j)) HACER izquierda <-- izquierda +1 MIENTRAS((pivote < datosParaClasificar[derecha])AND(derecha > i)) HACER derecha <-- derecha -1 FINMIENTRAS SI (izquierda <= derecha) ENTONCES intercambiar(datosParaClasificar, izquierda, derecha) izquierda <-- izquierda +1 derecha <-- derecha -1 FINSI FINMIENTRAS FINMIENTRAS SI(i < derecha) ENTONCES quickSort(datosParaClasificar, i, derecha) FINSI SI (izquierda < j) ENTONCES quickSort(datosParaClasificar, izquierda, j) FINSI FINSI FIN encuentraPivote COM int min, max, medio, aux min <-- l max <-- r medio <-- (l+r)/2 SI (datosParaClasificar[medio] < datosParaClasificar[min]) ENTONCES aux <-- medio medio <-- min min <-- medio FINSI SI (datosParaClasificar[max] < datosParaClasificar[min]) ENTONCES aux <-- max max <-- min min <-- aux FINSI SI (datosParaClasificar[medio] < datosParaClasificar[max]) ENTONCES DEVOLVER medio SINO DEVOLVER max FINSI FIN Documentación Programación II Práctico 4 La ordenación por Heapsort primero coloca los datos en un árbol parcialmente ordenado y luego los ordena. De esta manera se obtiene un algoritmo de orden O(nlog(n)) ordenarPorHeapSort COM DESDE(i = (datosParaClasificar.largo - 1) / 2 HASTA 0) HACER armaHeap(datosParaClasificar, i, datosParaClasificar.largo - 1) FINDESDE DESDE (i = datosParaClasificar.largo - 1 HASTA 1) HACER intercambiar(datosParaClasificar,0,i) armaHeap(datosParaClasificar, 0, i-1) FINDESDE DEVOLVER datosParaClasificar FIN armaHeap COM SI (primero < ultimo)ENTONCES r <-- primero MIENTRAS(r <= ultimo / 2) HACER SI(ultimo = 2*r)ENTONCES SI (datosParaClasificar[r] < datosParaClasificar[r*2]) intercambiar(datosParaClasificar, r, 2 * r) r <-- 2 * r SINO r <-- ultimo FINSI SINO posicionIntercambio <-- 0 SI(datosParaClasificar[2*r] > datosParaClasificar[2*r + 1]) ENTONCES posicionIntercambio <-- 2 * r SINO posicionIntercambio <-- 2 * r + 1 FINSI SI (datosParaClasificar[r] < datosParaClasificar[posicionIntercambio]) ENTONCES intercambiar(datosParaClasificar,r,posicionIntercambio) r <-- posicionIntercambio SINO r <-- ultimo FINSI FINSI FINMIENTRAS FINSI FIN Análisis de los datos de entrada El programa está diseñado de manera de ejecutar 20 veces cada clasificación, generando un total de 180 resultados por cada algoritmo: (20 𝑒𝑗𝑒𝑐𝑢𝑐𝑖𝑜𝑛𝑒𝑠) × ((3 𝑡𝑎𝑚𝑎ñ𝑜𝑠 𝑑𝑒 𝑎𝑟𝑟𝑎𝑦) × (3 𝑡𝑖𝑝𝑜𝑠 𝑑𝑒 𝑜𝑟𝑑𝑒𝑛) = 180 Estos datos son insertados en un archivo de texto con los datos separados por “;”. De esta manera se Documentación Programación II Práctico 4 facilita la importación de los mismos a Excel. Una vez importados a Excel los mismos son analizados utilizando funciones de suma lógica. En el archivo se separan los datos en tres hojas. La primera con los datos obtenidos del archivo de texto, la segunda con los datos analizados y la tercera con gráficos de comparación de los algoritmos. Análisis del proceso de medición El método elegido para medir los tiempos es el currentTimeMillis. El mismo bajo el sistema operativo Windows tiene una resolución de 10ms, por lo tanto para poder obtener una precisión del 1% el tiempo medido debe ser al menos 1000 ms. El algoritmo de medición de tiempos desarrollado por el grupo toma como tiempo mínimo de ejecución 2000 ms de manera que el tiempo agregado por la “cáscara” pueda ser descontado con seguridad sin afectar la precisión. Obtención y Normalización de los datos Los datos, una vez obtenidos, son normalizados de manera de independizar los resultados de la máquina en la cual se obtuvieron. Para ello en cada tamaño de array y para cada tipo de orden se busca el menor valor registrado y se dividen todas las mediciones por ese valor. Resultados de las mediciones Ver archivo Excel adjunto para los resultados de los análisis. Los datos obtenidos muestran claramente que el algoritmo de QuickSort es el de menor tiempo de ejecución en la mayoría de los casos. Se producen excepciones cuando los datos se encuentran ordenados. De esto se deduce que si los datos se encuentran parcialmente ordenados, el algoritmo de inserción directa podría llegar a ser más rápido que el QuickSort. En los resultados también se puede ver que la diferencia entre las mediciones de los array de diferentes tamaños coincide con el orden de ejecución de cada algoritmo. Esto se ve claramente en el algoritmo de ordenación por Burbuja en donde la diferencia entre las mediciones es claramente del tipo 𝑛2 . De la misma forma se puede ver como la diferencia entre las medidas del QuickSort se corresponden al orden 𝑛𝑙og(𝑛) Muestra de las mediciones ; ; ;Burbuja; ; ; ;Inserción Directa; ; ; ;Shellsort; ; ; ;Quicksort; ; ; ;Heapsort; ; ; ; Corrida;Tamaño Array;Orden Array;Tiempo;Ejecuciones;Total;Cascara;Tiempo;Ejecuciones;Total;Cascara;Tiempo;Ejecuciones;Total;Cascara;Tiempo;Ejecuciones;Total;Cascara;T iempo;Ejecuciones;Total;Cascara; 0;300;Aleatorios;1514;4120;0,3682;3;1495;15111;0,0993;5;1495;21832;0,0687;5;1486;45204;0,0332;14;1491;25936;0,0578;9; 0;300;Ascendentes;1495;8936;0,1680;6;1312;706843;0,0021;188;1450;186725;0,0080;50;1468;121173;0,0124;32;1489;32026;0,0468;11; 0;300;Descendentes;1498;8068;0,1859;2;1498;8119;0,1848;2;1491;11882;0,1262;9;1471;116049;0,0129;29;1492;34299;0,0437;8; 0;3000;Aleatorios;1515;51;29,7059;0;1506;170;8,8588;0;1502;259;5,8031;1;1494;3367;0,4455;6;1497;2011;0,7459;3; Ver archivo de texto adjunto. Documentación