diff --git a/doc/Informe.tex b/doc/Informe.tex index 4420efb..2a56e85 100644 --- a/doc/Informe.tex +++ b/doc/Informe.tex @@ -67,10 +67,12 @@ Xavier Canales \pagenumbering{arabic} \section{Pseudo código} \subsection{Merge Sort} +\lstinputlisting{pseudo/mergesort.txt} \newpage \subsection{Quick Sort} \lstinputlisting{pseudo/quicksort.txt} + \newpage \subsection{Bubble Sort} \lstinputlisting{pseudo/bubblesort.txt} @@ -78,73 +80,82 @@ Xavier Canales \newpage \subsection{Bitonic Sort} \lstinputlisting{pseudo/bitonicsort.txt} -\newpage -\subsection{Ordenamiento por conteo} \newpage -\subsection{Ordenamiento por selección} +\subsection{Counting Sort} +\lstinputlisting{pseudo/countingsort.txt} + +\newpage +\subsection{Selection Sort} \lstinputlisting{pseudo/selectionsort.txt} + \newpage \section{Resultados} \subsection{Análisis temporal} \subsubsection{Merge Sort} -Caso Promedio: $ \Theta (n log n)) $ \\ -en.wikipedia.org/wiki/Merge\_sort\#Analysis +\underline{Caso Promedio:} $ \Theta(n log n)) $ \\ +El caso promedio de merge sort es lo mismo que su peor caso. \\ -Peor Caso: $ O(n log n) $ \\ +\underline{Peor Caso:} $ O(n log n) $ \\ +En el peor de los casos, el merge sort hace aproximadamente un 39\% menos de comparaciones que el quick sort en su caso promedio. En términos de movimientos, la complejidad del peor de los casos de merge sort es $ O(n log n) $ la misma complejidad que el mejor de Quick sort, y el mejor de la clasificación de merge sort toma aproximadamente la mitad de las iteraciones que en el peor de los casos. \\ - -Mejor Caso: $ \Omega (n log n)$ \\ +\underline{Mejor Caso:} $ \Omega(n log n)$ \\ +En el caso mejor de merge sort, el merge sort funciona mejor cuando los datos son secuencial. \\ \subsubsection{Quick Sort} -Caso Promedio: $ \Theta (n(log n)) $ \\ -El tiempo de ejecución que tendrá el algoritmo dependerá de como se realice la partición de el arreglo entrada, es decir, depende de la selección del pivote +\underline{Caso Promedio:} $ \Theta(n(log n)) $ \\ +El tiempo de ejecución que tendrá el algoritmo dependerá de como se realice la partición de el arreglo entrada, es decir, depende de la selección del pivote. \\ -Peor Caso: $ O(n^2) $ \\ -El peor de los casos para el quicksort resultará cuando la elección del pivote sea el valor más pequeño del arreglo o el más grande de este mismo. +\underline{Peor Caso:} $ O(n^2) $ \\ +El peor de los casos para el quick sort resultará cuando la elección del pivote sea el valor más pequeño del arreglo o el más grande de este mismo. \\ + +\underline{Mejor Caso:} $ \Omega(n log(n)) $ \\ +Para obtener el mejor caso posible será cuando el pivote se encuentre exactamente al medio del arreglo, porque lo dividirá en dos obteniendo n/2 elementos en ambas divisiones del arreglo. \\ -Mejor Caso: $ \Omega $(n log(n)) \\ -Para obtener el mejor caso posible será cuando el pivote se encuentre exactamente al medio del arreglo, porque lo dividirá en dos obteniendo n/2 elementos en ambas divisiones del arreglo \subsubsection{Bubble Sort} -Caso Promedio: $ \Theta (n^2)) $ \\ -El caso promedio compara la complejidad temporal con el peor caso, donde n es el numero de valores a ordenar, esto es producto de la forma en la cual Bubble transporta los valores dentro de su ordenamiento +\underline{Caso Promedio:} $ \Theta(n^2)) $ \\ +El caso promedio compara la complejidad temporal con el peor caso, donde n es el numero de valores a ordenar, esto es producto de la forma en la cual \textit{bubble} transporta los valores dentro de su ordenamiento. \\ -Peor Caso: $ O(n^2) $ \\ +\underline{Peor Caso:} $ O(n^2) $ \\ +En el peor caso el arreglo a ordenar va a estar ordenado en forma descendente previamente. \\ - -Mejor Caso: $ \Omega (n)$ \\ -El mejor caso para el Bubble sort será cuando el arreglo de entrada venga previamente ordenado de menor a mayor. +\underline{Mejor Caso:} $ \Omega(n)$ \\ +El mejor caso para el bubble sort será cuando el arreglo de entrada venga previamente ordenado de menor a mayor. \\ \subsubsection{Bitonic Sort} -Caso Promedio: $\Theta(log^2(n))$ \\ -El ordenamiento bitonico responde igual a todos los casos porque siempre antes de empezar a ordenarlos realiza las mismas comparaciones para dejarlos en la secuencia bitonica +\underline{Caso Promedio:} $\Theta(log^2(n))$ \\ +El ordenamiento bitonico responde igual a todos los casos porque siempre antes de empezar a ordenarlos realiza las mismas comparaciones para dejarlos en la secuencia bitonica. \\ -Peor Caso: $O(log^2(n))$ \\ +\underline{Peor Caso:} $ O(log^2(n)) $ \\ +Su caso peor es lo mismo que su caso promedio. \\ -Mejor Caso: $\Omega(log^2(n))$ \\ +\underline{Mejor Caso:} $ \Omega(log^2(n)) $ \\ +Su caso mejor es lo mismo que su caso promedio. \\ -\subsubsection{Ordenamiento por conteo} -Caso Promedio: $ \Theta (n + k)) $ \\ -La complejidad total es igual para todos los casos, porque el algoritmo usa sólo ciclos simples, sin recursividad o sub-funciones, va directamente al analisis +\subsubsection{Counting Sort} +\underline{Caso Promedio:} $ \Theta(\frac{n^2}{2}) $ \\ +La complejidad total es igual para todos los casos, porque el algoritmo usa sólo ciclos simples, sin recursividad o sub-funciones, va directamente al análisis. \\ -Peor Caso: $ O(n + k) $ \\ +\underline{Peor Caso:} $ O(\frac{n^2}{2}) $ \\ +Su caso pero es lo mismo que su caso promedio. \\ +\underline{Mejor Caso:} $ \Omega(\frac{n^2}{2}) $ \\ +Su caso mejor es lo mismo que su caso promedio. \\ -Mejor Caso: $ \Omega (n + k)$ \\ +\subsubsection{Selection Sort} +\underline{Caso Promedio:} $ \Theta(n^2) $ \\ +El ordenamiento por selección no es un algoritmo de ordenamiento adaptable, realiza el mismo numero de comparaciones de elementos en el mejor caso, el caso promedio y el peor de los casos, esto se debe a que no utiliza el orden existente de las entradas del arreglo para ordenar. \\ -\subsubsection{Ordenamiento por selección} -Caso Promedio: $\Theta(n^2)$ \\ -El ordenamiento por selección no es un algoritmo de ordenamiento adaptable, realiza el mismo numero de comparaciones de elementos en el mejor caso, el caso promedio y el peor de los casos, esto se debe a que no utiliza el orden existente de las entradas de el arreglo para ordenar. - -Peor Caso: $O(n^2)$ \\ - -Mejor Caso: $\Omega(n^2)$ +\underline{Peor Caso:} $ O(n^2) $ \\ +Su caso peor es lo mismo que su caso promedio. \\ +\underline{Mejor Caso:} $ \Omega(n^2) $ \\ +Su caso mejor es lo mismo que su caso promedio. \\ \newpage \subsection{Datos} -La siguiente tabla contiene los resultados de las pruebas de los 6 algoritmos medidos en segundos. Para las pruebas usábamos un computador que tiene un procesador AMD A12 con 4 núcleos de 2.7Ghz y 16GB de memoria RAM. +La siguiente tabla contiene los resultados de las pruebas de los 6 algoritmos medidos en segundos. Para las pruebas usábamos un computador que tiene 4 nucleos de 3.2GHz y 16GB de memoria RAM. \begin{center} \begin{tabular}{|c|c|c|c|c|c|c|} \hline @@ -156,11 +167,11 @@ La siguiente tabla contiene los resultados de las pruebas de los 6 algoritmos me \hline \rule[-1ex]{0pt}{3.5ex} 100.000 & 0.170[s] & 0.300[s] & 0.124[s] & 11.645[s] & 30.269[s] & 32.347[s] \\ \hline - \rule[-1ex]{0pt}{3.5ex} 1.000.000 & 0.173[s] & 0.304[s] & 1.405[s] & 1,262.000[s] & 3,026.900[s] & 3,234.700[s] \\ + \rule[-1ex]{0pt}{3.5ex} 1.000.000 & 0.173[s] & 0.304[s] & 1.405[s] & 3,144.000[s] & 6,717.674[s] & 7,248.000[s] \\ \hline - \rule[-1ex]{0pt}{3.5ex} 5.000.000 & 2.000[s] & 1.577[s] & 7.421[s] & 31,550.000[s] & 75,672.500[s] & 80,867.500[s] \\ + \rule[-1ex]{0pt}{3.5ex} 5.000.000 & 2.000[s] & 1.577[s] & 7.421[s] & 60,951.000[s] & 139,273.286[s] & 153,273.539[s] \\ \hline - \rule[-1ex]{0pt}{3.5ex} 10.000.000 & 2.400[s] & 3.236[s] & 18.365[s] & 126,200.000[s] & 302,690.000[s] & 323,470.000[s] \\ + \rule[-1ex]{0pt}{3.5ex} 10.000.000 & 2.400[s] & 3.236[s] & 18.365[s] & 243,804.000[s] & 557,093.1440[s] & 613,094.156[s] \\ \hline \end{tabular} \end{center} @@ -174,6 +185,18 @@ La siguiente tabla contiene los resultados de las pruebas de los 6 algoritmos me \newpage \section{Conclusiones} +Basados en los resultados obtenido podemos poner los algoritmos en orden de mas rápido a menos rápido en la siguiente forma: +\begin{itemize} + \setlength\itemsep{0.1em} + \item Quick Sort + \item Merge Sort + \item Bitonic Sort + \item Selection Sort + \item Counting Sort + \item Bubble Sort +\end{itemize} +Al final resulta que el mas rápido algoritmo de ordenamiento que probamos fue Quick Sort mientras que el mas lento fue el Bubble Sort. +Los resultados de tiempo de ejecución estaban de lo que esperábamos dado el complejidad de los algoritmos. \end{document} diff --git a/doc/graph.png b/doc/graph.png index 730f77d..63e2cd9 100644 Binary files a/doc/graph.png and b/doc/graph.png differ diff --git a/doc/pseudo/bitonicsort.txt b/doc/pseudo/bitonicsort.txt index ec4468c..ceb64ae 100644 --- a/doc/pseudo/bitonicsort.txt +++ b/doc/pseudo/bitonicsort.txt @@ -1,126 +1,81 @@ -entrada: array: arreglo de n datos: n: tamaño del arreglo +entrada: array: arreglo de n datos; n: tamaño del arreglo salida: arreglo ordenado -funcion potencia_de_dos(inicio n) - - si(n = 0) entonces - - retornar 0 - - fin si - - mientras(n distinto 1) hacer - si (n % 2 distinto 0) hacer - - retornar 0 - - fin si - fin mientras - - retornar 1 - +funcion ordenamientobitonico(array, n) + orden(array, n, 1) + return array fin funcion -inicio funcion mejor_potencia_de_2_menos_a_n(inicio n) - - inicio k = 1 - - mientras(k > 0 y k < n) hacer +funcion potencia_de_dos(n) + si n = 0 entonces + retornar 0 + fin si + mientras n distinto 1 hacer + si n es modulo de 2 entonces + retornar 0 + fin si + fin mientras + retornar 1 +fin funcion +funcion mejor_potencia_de_2_menos_a_n(n) + k = 1 + mientras k > 0 y k < n hacer busca el numero potencia de dos mas proximo hacia abajo en n - - fin mientras - - retorna k + fin mientras + retorna k fin funcion -funcion comparar(inicio i, inicio j, inicio dir, inicio arreglo) - - temp = array[i]; - array[i] = array[j]; - array[j] = temp; - +funcion comparar(i, j, dir, array) + temp = array[i] + array[i] = array[j] + array[j] = temp fin funcion -funcion unionbitonica(inicio low, inicio n, inicio dir, inicio arreglo) - - inicio i - inicio k - - si(n > 1) entonces - - k = n/2 - - para i = low hasta i < low + k con paso i = i+1 - - comparar(, i + k, di, arreglo) - fin para - - unionbitonica(low, k, dir, arreglo) - unionbitonica(low + k, k, dir, arreglo) - - fin si - +funcion unionbitonica(low, n, dir, array) + si n > 1 entonces + k = n / 2 + para i = low hasta i < low + k con paso i = i + 1 + comparar(i + k, di, array) + fin para + unionbitonica(low, k, dir, array) + unionbitonica(low + k, k, dir, array) + fin si fin funcion -funcion unionbitonico2(inicio low, inicio n, inicio dir, inicio arreglo) - - inicio i - inicio k - - si(n > 1) entonces - - k = mejor_potencia_de_2_menos_a_n - - para i = low hasta i < low + n - k con paso i = i + 1 hacer - - comparar(i, i + k, dir, arreglo) - - fin para - - ordenamientobitonico2(low, k, dir, arreglo) - ordenamientobitonico2(low + k, n - k, dir, arreglo) +funcion unionbitonico2(low, n, dir, array) + si n > 1 entonces + k = mejor_potencia_de_2_menos_a_n + para i = low hasta i < low + n - k con paso i = i + 1 hacer + comparar(i, i + k, dir, array) + fin para + ordenamientobitonico2(low, k, dir, array) + ordenamientobitonico2(low + k, n - k, dir, array) fin funcion -funcion recorrerbitonico(int low, int n, int dir, int arreglo) - - inicio k - si(n > 1) entonces - - k = n / 2 - recorrerbitonico(low, k, 1, arreglo) - recorrerbitonico(low + k, k, 0, arreglo) - unionbitonica(low, n, dir, array) - - fin si +funcion recorrerbitonico(low, n, dir, array) + si n > 1 entonces + k = n / 2 + recorrerbitonico(low, k, 1, array) + recorrerbitonico(low + k, k, 0, array) + unionbitonica(low, n, dir, array) + fin si fin funcion -funcion recorrerbitonico2(int low, int n, int dir, int arreglo) - - inicio k - - si(n > 1) entonces - k = n / 2 - recorrerbitonico2(low, k, !di, arreglo) - recorrerbitonico2(low + k, n - k, dir, arreglo) - unionbitonico2(low, n, dir, arreglo) - fin si +funcion recorrerbitonico2(low, n, dir, array) + si n > 1 entonces + k = n / 2 + recorrerbitonico2(low, k, !di, array) + recorrerbitonico2(low + k, n - k, dir, array) + unionbitonico2(low, n, dir, array) + fin si fin funcion -funcion orden(int arreglo, int n, int dir) - - si(potencia_de_dos(n)) entonces - - recorrerbitonico(0,n,dir,arreglo) - - fin si - - sino - recorrerbitonico2(0, n, dir, arreglo) - fin sino +funcion orden(array, n, dir) + si potencia_de_dos(n) entonces + recorrerbitonico(0, n, dir, array) + fin si + sino + recorrerbitonico2(0, n, dir, array) + fin sino fin funcion - -funcion ordenamientobitonico(inicio arreglo, inicio n) - - orden(arreglo, n, 1) -fin funcion \ No newline at end of file diff --git a/doc/pseudo/bubblesort.txt b/doc/pseudo/bubblesort.txt index 915635c..10169d2 100644 --- a/doc/pseudo/bubblesort.txt +++ b/doc/pseudo/bubblesort.txt @@ -1,13 +1,19 @@ entrada: array: arreglo de elementos enteros; n: tamaño del arreglo -salida: arreglo array ordenado ascendentemente. +salida: arreglo array ordenado ascendentemente -cuentaDeElementos := n -repetir - haCambiado := falso - disminuir cuentaDeElementos - repetir con indice desde 1 a cuentaDeElementos - if (array en indice) > (array en (indice + 1)) - intercambiar (array en indice) con (array en (indice + 1)) - haCambiado := falso -hasta haCambiado = verdad -retorna array +funcion bubblesort(array, n) + flag = 1 + mientras que flag es verdad + flag = false + para i = 1 mientras que i < j con pasa i = i + 1 hacer + si array[i] < array[i - 1] entonces + temp = array[i] + array[i] = array[i - 1] + array[i - 1] = temp + flag = verdad + fin si + fin para + j = j - 1; + fin mientras + retorna array +fin funcion diff --git a/doc/pseudo/countingsort.txt b/doc/pseudo/countingsort.txt new file mode 100644 index 0000000..ef3e8bb --- /dev/null +++ b/doc/pseudo/countingsort.txt @@ -0,0 +1,22 @@ +entrada: array: arreglo de elementos enteros; n: tamaño del arreglo +salida: arreglo array ordenado ascendentemente + +funcion countingsort(array, n) + para i = 0 mientras que i < n con paso i = i + 1 hacer + count[i] = 0 + fin para + para i = 0 mientras que i < n - 1 con paso i = i + 1 hacer + para j = i + 1 mientras que j < n con paso j = j + 1 hacer + si array[i] < array[j] entonces + count[j] = count[j] + 1 + sino + count[i] = count[i] + 1 + fin si + fin para + fin para + + para i = 0 mientras que i < n con paso i = i + 1 hacer + newarray[count[i]] = array[i] + } + retorna newarray +fin funcion diff --git a/doc/pseudo/mergesort.txt b/doc/pseudo/mergesort.txt new file mode 100644 index 0000000..bd9b2b9 --- /dev/null +++ b/doc/pseudo/mergesort.txt @@ -0,0 +1,43 @@ +entrada: array: arreglo de n datos; n: tamaño del arreglo +salida: arreglo ordenado + +funcion mergesort(array, n) + correr_mergesort(array, 0, n - 1); + retorna array +fin funcion + +funcion correr_mergesort(array, izquerda, derecha) + si izquerda != derecha entonces + medio = (izquerda + derecha) / 2 + correr_mergesort(array, izquerda, medio) + correr_mergesort(array, medio + 1, derecha) + unir(array, izquerda, medio + 1, derecha) + fin si +fin funcion + +funcion unir(array, previo_izquerda, previo_medio, derecha) + i = 0 + izquerda = previo_izquerda + medio = previo_medio - 1 + far_derecha = derecha - izquerda + 1 + + mientras que previo_izquerda <= medio y previo_medio <= derecha hacer + si array[previo_izquerda] < array[previo_medio] entonces + temp[i++] = array[previo_izquerda++] + sino + temp[i++] = array[previo_medio++] + fin si + fin mientras + + mientras que previo_izquerda <= medio hacer + temp[i++] = array[previo_izquerda++] + fin mientras + + mientras que previo_medio <= derecha hacer + temp[i++] = array[previo_medio++] + fin mientras + + para i = 0 mientras que i < far_derecha con paso i = i + 1 hacer + array[izquerda + i] = temp[i] + fin para +fin funcion diff --git a/doc/pseudo/quicksort.txt b/doc/pseudo/quicksort.txt index 38a4e27..d999775 100644 --- a/doc/pseudo/quicksort.txt +++ b/doc/pseudo/quicksort.txt @@ -1,40 +1,33 @@ -entrada: array: arreglo de n datos: n: tamaño del arreglo +entrada: array: arreglo de n datos; n: tamaño del array salida: arreglo ordenado -funcion quick_sort{ - - si(n < 2) entonces{ - retorna - } +funcion quick_sort(array, n) + si n < 2 entonces + retorna + fin si - inicio i - inicio j - inicio temp - inicio pivote + pivote = array[n / 2] - pivote = arreglo[n / 2] + para i = 0 y j = n - 1 con paso i = i + 1 y j = j - 1 hacer + mientras que array[i] < pivote hacer + i = i + 1 + fin mientras - para i = 0 y j = n-1 con paso i = i + 1 y j = j - 1 hacer - mientras(arreglo[i] < pivote) hacer - i = i + 1 - fin mientras + mientras que array[j] > pivote hacer + j = j - 1 + fin mientras - mientras(arreglo[j] > pivote) hacer - j = j - 1 - fin mientras + si i >= j entonces + break + fin si - si(i >= j) entonces - break - fin si + temp = array[i] + array[i] = array[j] + array[j] = temp + fin para - temp = arreglo[i] - arreglo[i] = arreglo[j] - arreglo[j] = temp - fin para - - quick_sort(arreglo, i) - quick_sort(arreglo + i, n - i) - - retorna el arreglo ordenado + quick_sort(array, i) + quick_sort(array + i, n - i) -fin funcion \ No newline at end of file + retorna array +fin funcion diff --git a/doc/pseudo/selectionsort.txt b/doc/pseudo/selectionsort.txt index 22b79d3..06e930e 100644 --- a/doc/pseudo/selectionsort.txt +++ b/doc/pseudo/selectionsort.txt @@ -1,31 +1,17 @@ -entrada: array: arreglo de n datos: n: tamaño del arreglo +entrada: array: arreglo de n datos; n: tamaño del arreglo salida: arreglo ordenado -funcion selection_sort - - inicio i - inicio j - inicio temp - inicio min_idx - - para i = 0 hasta i < n - 1 con paso i = i + 1 hacer - - min_idx = i - - para j = i + 1 hasta j < n con paso j = j + 1 hacer - - si (arreglo[j] < arreglo[min_idx] hacer) hacer - - min_idx = j - - fin si - - fin para - - temp = arreglo[min_idx] - arreglo[min_idx] = arreglo[i] - arreglo[i] = temp - - fin para - -fin funcion \ No newline at end of file +funcion selection_sort(array, n) + para i = 0 hasta i < n - 1 con paso i = i + 1 hacer + min_idx = i + para j = i + 1 hasta j < n con paso j = j + 1 hacer + si array[j] < array[min_idx] entonces + min_idx = j + fin si + fin para + temp = array[min_idx] + array[min_idx] = array[i] + array[i] = temp + fin para + retorna array +fin funcion diff --git a/doc/resultados.txt b/doc/resultados.txt deleted file mode 100644 index a48ccdd..0000000 --- a/doc/resultados.txt +++ /dev/null @@ -1,41 +0,0 @@ -Quick sort - 10.000 - 0.1 segundos - 100.000 - 0.17 segundos - 1.000.000 - 0.173 segundos - 5.000.000 - 2.0 segundos - 10.000.000 - 2.4 segundos - -Merge sort - 10.000 - 0.28 segundos - 100.000 - 0.30 segundos - 1.000.000 - 0.304 segundos - 5.000.000 - 1.577 segundos - 10.000.000 - 3.236 segundos - -Bitonic sort - 10.000 - 0.09 segundos - 100.000 - 0.124 segundos - 1.000.000 - 1.405 segundos - 5.000.000 - 7.421 segundos - 10.000.000 - 18.365 segundos - -Selection sort - 10.000 - 0.143 segundos - 100.000 - 11.645 segundos - 1.000.000 - 21 minutos y 2.0 segundos 1262 segundos - 5.000.000 - 8 horas, 45 minutos y 50 segundos teo 31550 segundos - 10.000.000 - 1 day, 11 horas, 3 minutos y 20 segundos teo 126200 segundos - -Count sort - 10.000 - 0.258 segundos - 100.000 - 30.269 segundos - 1.000.000 - 50 minutos y 26.9 segundos teo 3026.9 segundos - 5.000.000 - 21 horas, 1 minuto y 12.5 segundos teo 75672.5 segundos - 10.000.000 - 3 dias, 12 horas, 4 minutos y 50 segundos teo 302690 segundos - -Bubble sort - 10.000 - 0.326 segundos - 100.000 - 32.347 segundos - 1.000.000 - 53 minutos y 54.7 segundos teo 3234.7 segundos - 5.000.000 - 22 horas, 27 minutos y 47.5 segundos teo 80867.5 segundos - 10.000.000 - 3 dias, 17 horas, 51 minutos y 10 segundos teo 323470 segundos