Você está na página 1de 9

II.

- ANLISIS DE ALGORITMOS

Un algoritmo probabilista (o probabilstico) es un algoritmo que basa su resultado en la toma de algunas decisiones al azar, de tal forma que, en promedio, obtiene una buena solucin al problema planteado para cualquier distribucin de los datos de entrada. Es decir, al contrario que un algoritmo determinista, a partir de unos mismos datos se pueden obtener distintas soluciones y, en algunos casos, soluciones errneas. Existen varios tipos de algoritmos probabilsticos dependiendo de su funcionamiento, pudindose distinguir: Algoritmos numricos, que proporcionan una solucin aproximada del problema. La solucin obtenida es siempre aproximada pero su precisin esperada mejora aumentando el tiempo de ejecucin. Normalmente, el error es inversamente proporcional a la raz cuadrada del esfuerzo invertido en el clculo. Algoritmos de Monte Carlo. Hay problemas para los que no se conocen soluciones deterministas ni probabilistas que den siempre una solucin correcta, entonces pueden dar la respuesta correcta o respuesta errneas (con probabilidad baja). En este algoritmo a veces da una solucin incorrecta, con una alta probabilidad encuentra una solucin correcta sea cual sea la entrada. Algoritmos de Las Vegas. Este algoritmo nunca da una solucin falsa. Toma decisiones al azar para encontrar una solucin antes que un algoritmo determinista. Si no encuentra solucin lo admite. Hay dos tipos de algoritmos de Las Vegas, segn la posibilidad de no encontrar una solucin: Los que siempre encuentran una solucin correcta, aunque las decisiones al azar no sean afortunadas y la eficiencia disminuya. Los que a veces, debido a decisiones desafortunadas, no encuentran una solucin.

Algoritmos de ordenamiento
Uno de los problemas fundamentales en la ciencia de la computacin es ordenar una lista de items. Existen una infinidad de mtodos de ordenamiento, algunos son simples e intuitivos y otros son extremadamente complicados, pero producen los resultados mucho ms rpido. En este trabajo se presentan los algoritmos de ordenamiento ms comunes, entre los cuales estn los siguientes: Bubble sort, Heap sort, Insertion sort, Merge sort, Quick sort, Selection sort y Shell sort. Los algoritmos de ordenamiento pueden ser divididos en dos clases de acuerdo a la complejidad de los mismos. La complejidad del algoritmo se denota segn la

notacin Big-O. Por ejemplo, O(n) significa que el algoritmo tiene una complejidad lineal. En otras palabras, toma 10 veces ms tiempo en operar un conjunto de 100 datos que en hacerlo con un conjunto de 10 items. Si la complejidad fuera O(n2) entonces tomara 100 veces ms tiempo en operar 100 items que en hacerlo con 10. Adicionalmente a la complejidad de los algoritmos, la velocidad de ejecucin puede cambiar de acuerdo al tipo de dato a ordenar, es por ello que es conveniente comparar los algoritmos contra datos empricos. stos datos empricos se deben elaborar tomando la media de tiempo de ejecucin en un conjunto de corridas y con datos del mismo tipo.

Anlisis de los algoritmos


Bubble sort
Este es el mtodo ms simple y antiguo para ordenar un conjunto de datos, es tambin el ms lento. El algoritmo bubble sort tiene dos bucles for internos que recorren el vector comparando el elemento j+1 con el elemento j y en caso de que este sea mayor hace un cambio de los elementos. Al tener dos bucles internos el comportamiento es en general O(n2), y en las mejores condiciones se comporta como O(n). Como funciona Consiste en comparar pares de elementos adyacentes e intercambiarlos entre s hasta que estn todos ordenados. Con el siguiente arreglo {40,21,4,9,10,35}: Primera pasada: {21,40,4,9,10,35} <-- Se cambia el 21 por el 40. {21,4,40,9,10,35} <-- Se cambia el 40 por el 4. {21,4,9,40,10,35} <-- Se cambia el 9 por el 40. {21,4,9,10,40,35} <-- Se cambia el 40 por el 10. {21,4,9,10,35,40} <-- Se cambia el 35 por el 40. Segunda pasada: {4,21,9,10,35,40} <-- Se cambia el 21 por el 4. {4,9,21,10,35,40} <-- Se cambia el 9 por el 21. {4,9,10,21,35,40} <-- Se cambia el 21 por el 10. Ya estn ordenados, pero para comprobarlo habra que acabar esta segunda comprobacin y hacer una tercera.

Selection sort

Este algoritmo trabaja seleccionando el item ms pequeo a ser ordenado que an esta en la lista, y luego haciendo un intercambio con el elemento en la siguiente posicin. La complejidad de este algoritmo es O(n2). Como funciona. Este mtodo consiste en buscar el elemento ms pequeo del arreglo y ponerlo en primera posicin; luego, entre los restantes, se busca el elemento ms pequeo y se coloca en segundo lugar, y as sucesivamente hasta colocar el ltimo elemento. Por

ejemplo, si tenemos el arreglo {40,21,4,9,10,35}, los pasos a seguir son: {4,21,40,9,10,35} <-- Se coloca el 4, el ms pequeo, en primera posicin : se cambia el 4 por el 40. {4,9,40,21,10,35} <-- Se coloca el 9, en segunda posicin: se cambia el 9 por el 21. {4,9,10,21,40,35} <-- Se coloca el 10, en tercera posicin: se cambia el 10 por el 40. {4,9,10,21,40,35} <-- Se coloca el 21, en tercera posicin: ya est colocado. {4,9,10,21,35,40} <-- Se coloca el 35, en tercera posicin: se cambia el 35 por el 40.

Insertion sort

El insertion sort trabaja insertando el item en su lugar correspondiente al final de la lista. Como el bubble sort, ste algoritmo se comporta como O(n2), pero a pesar de tener el misma complejidad, este algoritmo es casi el doble ms eficiente que el bubble sort. Como funciona. En este mtodo lo que se hace es tener una sublista ordenada de elementos del arreglo e ir insertando el resto en el lugar adecuado para que la sublista no pierda el orden. La sublista ordenada se va haciendo cada vez mayor, de modo que al final la lista entera queda ordenada. Para el ejemplo {40,21,4,9,10,35}, se tiene: {40,21,4,9,10,35} <-- La primera sublista ordenada es {40}. Insertamos el 21: {40,40,4,9,10,35} <-- aux=21; {21,40,4,9,10,35} <-- Ahora la sublista ordenada es {21,40}. Insertamos el 4: {21,40,40,9,10,35} <-- aux=4; {21,21,40,9,10,35} <-- aux=4; {4,21,40,9,10,35} <-- Ahora la sublista ordenada es {4,21,40}. Insertamos el 9: {4,21,40,40,10,35} <-- aux=9; {4,21,21,40,10,35} <-- aux=9; {4,9,21,40,10,35} <-- Ahora la sublista ordenada es {4,9,21,40}. Insertamos el 10: {4,9,21,40,40,35} <-- aux=10; {4,9,21,21,40,35} <-- aux=10; {4,9,10,21,40,35} <-- Ahora la sublista ordenada es {4,9,10,21,40}. Y por ltimo insertamos el 35: {4,9,10,21,40,40} <-- aux=35; {4,9,10,21,35,40} <-- El arreglo est ordenado. En el peor de los casos, el nmero de comparaciones que hay que realizar es de N*(N+1)/2-1, lo que nos deja un tiempo de ejecucin en O(n2). En el mejor caso (cuando la lista ya estaba ordenada), el nmero de comparaciones es N-2. Todas ellas son falsas, con lo que no se produce ningn intercambio. El tiempo de ejecucin est en O(n). El caso medio depender de cmo estn inicialmente distribuidos los elementos. Vemos que cuanto ms ordenada est inicialmente ms se acerca a O(n) y cuanto ms desordenada, ms se acerca a O(n2). El peor caso es igual que en los mtodos de burbuja y seleccin, pero el mejor caso es lineal, algo que no ocurra en stos, con lo que para ciertas entradas podemos tener ahorros en tiempo de ejecucin.

Merge sort

El merge sort divide la lista a ser ordenada en dos mitades iguales y las pone en arreglos separadas. Cada arreglo es ordenado recursivamente, y luego se juntan en el arreglo final. Este algoritmo tiene un comportamiento de O(n log n). Implementaciones elementales del merge sort hacen uso de tres arreglos, uno para cada mitad y uno para almacenar el resultado final Como funciona. Consta de dos partes, una parte de intercalacin de listas y otra de divide y vencers. El esquema es el siguiente: Ordenar(lista L) inicio si tamao de L es 1 o 0 entonces devolver L si tamao de L es >= 2 entonces separar L en dos trozos: L1 y L2. L1 = Ordenar(L1) L2 = Ordenar(L2) L = Fusionar(L1, L2) devolver L fin El algoritmo funciona y termina porque llega un momento en el que se obtienen listas de 2 3 elementos que se dividen en dos listas de un elemento (1+1=2) y en dos listas de uno y dos elementos (1+2=3, la lista de 2 elementos se volver a dividir), respectivamente. Por tanto se vuelve siempre de la recursin con listas ordenadas (pues tienen a lo sumo un elemento) que hacen que el algoritmo de fusin reciba siempre listas ordenadas. Ejemplo: Dada: 3 -> 2 -> 1 -> 6 -> 9 -> 0 -> 7 -> 4 -> 3 -> 8 (lista original) se divide en: 3 -> 2 -> 1 -> 6 -> 9 (lista 1) 0 -> 7 -> 4 -> 3 -> 8 (lista 2) se ordena recursivamente cada lista: 3 -> 2 -> 1 -> 6 -> 9 (lista 1) se divide en: 3 -> 2 -> 1 (lista 1.1) 6 -> 9 (lista 1.2) se ordena recursivamente cada lista: 3 -> 2 -> 1 (lista 1.1) se divide en: 3 -> 2 (lista 1.1.1) 1 (lista 1.1.2) se ordena recursivamente cada lista: 3 -> 2 (lista 1.1.1) se divide en: 3 (lista 1.1.1.1, que no se divide, caso base). Se devuelve 3 2 (lista 1.1.1.2, que no se divide, caso base). Se devuelve 2 se fusionan 1.1.1.1-1.1.1.2 y queda: 2 -> 3. Se devuelve 2 -> 3 1 (lista 1.1.2) 1 (lista 1.1.2.1, que no se divide, caso base). Se devuelve 1 se fusionan 1.1.1-1.1.2 y queda: 1 -> 2 -> 3 (lista 1.1). Se devuelve 1 -> 2 -> 3

6 -> 9 (lista 1.2) se divide en: 6 (lista 1.2.1, que no se divide, caso base). Se devuelve 6 9 (lista 1.2.2, que no se divide, caso base). Se devuelve 9 se fusionan 1.2.1-1.2.2 y queda: 6 -> 9 (lista 1.2). Se devuelve 6 -> 9 se fusionan 1.1-1.2 y queda: 1 -> 2 -> 3 -> 6 -> 9. Se devuelve 1 -> 2 -> 3 -> 6 -> 9 0 -> 7 -> 4 -> 3 -> 8 (lista 2) tras repetir el mismo procedimiento se devuelve 0 -> 3 -> 4 -> 7 -> 8 se fusionan 1-2 y queda: 0 -> 1 -> 2 -> 3 -> 3 -> 4 -> 6 -> 7 -> 8 -> 9, que se devuelve y se termina.

Quick sort

El Quick sort es un algoritmo del estilo divide y vencers. Es bastante ms rpido que el merge sort. El algoritmo de recursin consiste en una serie de cuatro pasos: 1. Si hay menos de un elemento a ser ordenado retorna inmediatamente. 2. Tomar un elemento del vector que sirve como Pivote 3. Dividir el arreglo en dos partes, una con los elementos mayores y una con los elementos menores al pivote. 4. Repetir recursivamente el algoritmo para las dos mitades del arreglo original. La eficiencia de este algoritmo es mayor por la seleccin del elemento que ser tomado como pivote. En el peor caso, el comportamiento es de la forma O(n2), y ocurre cuando la lista esta ordenada. Si el elemento utilizado como pivote se selecciona de forma aleatoria, el comportamiento se parece a O(n log n). Como funciona. Este mtodo se basa en la tctica "divide y vencers", que consiste en ir subdividiendo el arreglo en arreglos ms pequeos, y ordenar stos. Para hacer esta divisin, se toma un valor del arreglo como pivote, y se mueven todos los elementos menores que este pivote a su izquierda, y los mayores a su derecha. A continuacin se aplica el mismo mtodo a cada una de las dos partes en las que queda dividido el arreglo. Normalmente se toma como pivote el primer elemento de arreglo, y se realizan dos bsquedas: una de izquierda a derecha, buscando un elemento mayor que el pivote, y otra de derecha a izquierda, buscando un elemento menor que el pivote. Cuando se han encontrado los dos, se intercambian, y se sigue realizando la bsqueda hasta que las dos bsquedas se encuentran. Por ejemplo, para dividir el arreglo {21,40,4,9,10,35}, los pasos seran: {21,40,4,9,10,35} <-- se toma como pivote el 21. La bsqueda de izquierda a derecha encuentra el valor 40, mayor que pivote, y la bsqueda de derecha a izquierda encuentra el valor 10, menor que el pivote. Se intercambian:{21,10,4,9,40,35} <-- Si seguimos la bsqueda, la primera encuentra el valor 40, y la segunda el valor 9, pero ya se han cruzado, as que paramos. Para terminar la divisin, se coloca el pivote en su lugar (en el nmero encontrado por la segunda bsqueda, el 9, quedando: {9,10,4,21,40,35} <-- Ahora tenemos dividido el arreglo en dos arreglos ms pequeos: el {9,10,4} y el {40,35}, y se repetira el mismo proceso.

Heap Sort
El heap sort tiene un comportamiento del tipo O(n log n), pero a diferencia de los algoritmos merge y quick sort este no requiere recursin masiva o mltiples arreglos para trabajar. El heap sort comienza construyendo un heap del conjunto de datos, y luego remueve los items ms grandes ponindolos al final del arreglo ordenado. Luego de eliminar los items ms grandes, reconstruye el heap y remueve los elementos ms grandes nuevamente. Esto lo repite hasta que no queden elementos en el heap y el heap de items ordenados este lleno. Como funciona. No es propiamente un mtodo de ordenacin, consiste en la unin de dos arreglos ordenados de modo que la unin est tambin ordenada. Para ello, basta con recorrer los arreglos de izquierda a derecha e ir tomando el menor de los dos elementos, de forma que slo aumenta el contador del arreglo del que sale el elemento siguiente para el arreglo-suma. Si quisiramos sumar los arreglos {1,2,4} y {3,5,6}, los pasos seran: Inicialmente: i1=0, i2=0, is=0. Primer elemento: mnimo entre 1 y 3 = 1. Suma={1}. i1=1, i2=0, is=1. Segundo elemento: mnimo entre 2 y 3 = 2. Suma={1,2}. i1=2, i2=0, is=2. Tercer elemento: mnimo entre 4 y 3 = 3. Suma={1,2,3}. i1=2, i2=1, is=3. Cuarto elemento: mnimo entre 4 y 5 = 4. Suma={1,2,3,4}. i1=3, i2=1, is=4. Como no quedan elementos del primer arreglo, basta con poner los elementos que quedan del segundo arreglo en la suma:

Shell sort
Inventado en 1959, ste algoritmo es el ms eficiente de los del tipo O(n2). Pero el Shell es tambin el ms complicado de los algoritmos de este tipo. El algoritmo realiza mltiples pases a travs de la lista, y en cada pasada ordena un numero igual de items. El tamao del conjunto de datos (tambin llamado distancia o intervalo) a ser ordenado va creciendo a medida que el algoritmo recorre el arreglo hasta que finalmente el conjunto esta compuesto por todo el arreglo en si mismo. El tamao del conjunto de datos usado tiene un impacto significativo en la eficiencia del algoritmo. Algunas implementaciones de este algoritmo tienen una funcin que permite calcular el tamao ptimo del conjunto de datos para un arreglo determinado. Como funciona Es una mejora del mtodo de insercin directa, utilizado cuando el arreglo tiene un gran nmero de elementos. En este mtodo no se compara a cada elemento con el de su izquierda, como en el de insercin, sino con el que est a un cierto nmero de lugares (llamado salto) a su izquierda. Este salto es constante, y su valor inicial es N/2 (siendo N el nmero de elementos, y siendo divisin entera). Se van dando pasadas hasta que en una pasada no se intercambie ningn elemento de sitio. Entonces el salto se reduce a la mitad, y se vuelven a dar pasadas hasta que no se intercambie ningn elemento, y as sucesivamente hasta que el salto vale 1. Por ejemplo, lo pasos para ordenar el arreglo {40,21,4,9,10,35} mediante el mtodo de Shell seran: Salto=3: Primera pasada: {9,21,4,40,10,35} <-- se intercambian el 40 y el 9.

{9,10,4,40,21,35} <-- se intercambian el 21 y el 10. Salto=1: Primera pasada: {9,4,10,40,21,35} <-- se intercambian el 10 y el 4. {9,4,10,21,40,35} <-- se intercambian el 40 y el 21. {9,4,10,21,35,40} <-- se intercambian el 35 y el 40. Segunda pasada: {4,9,10,21,35,40} <-- se intercambian el 4 y el 9. Con slo 6 intercambios se ha ordenado el arreglo, cuando por insercin se necesitaban muchos ms.

Anlisis de algoritmos de bsquedas


La bsqueda de un elemento dentro de un arreglo es una de las operaciones ms importantes en el procesamiento de la informacin, y permite la recuperacin de datos previamente almacenados. Todos los algoritmos de bsqueda tienen dos finalidades: - Determinar si el elemento buscado se encuentra en el conjunto en el que se busca. - Si el elemento est en el conjunto, hallar la posicin en la que se encuentra. En este apartado nos centramos en la bsqueda interna. Como principales algoritmos de bsqueda en arreglos tenemos la bsqueda secuencial, la binaria y la bsqueda utilizando tablas de hash.

Bsqueda secuencial
Consiste en recorrer y examinar cada uno de los elementos del arreglo hasta encontrar el o los elementos buscados, o hasta que se han mirado todos los elementos del arreglo.

Bsqueda binaria o dicotmica


Para utilizar este algoritmo, el arreglo debe estar ordenado. La bsqueda binaria consiste en dividir el arreglo por su elemento medio en dos subarreglos ms pequeos, y comparar el elemento con el del centro. Si coinciden, la bsqueda se termina. Si el elemento es menor, debe estar (si est) en el primer subarreglo, y si es mayor est en el segundo. Por ejemplo, para buscar el elemento 3 en el arreglo {1,2,3,4,5,6,7,8,9} se realizaran los siguientes pasos: Se toma el elemento central y se divide el arreglo en dos: {1,2,3,4}-5-{6,7,8,9} Como el elemento buscado (3) es menor que el central (5), debe estar en el primer subarreglo: {1,2,3,4} Se vuelve a dividir el arreglo en dos: {1}-2-{3,4} Como el elemento buscado es mayor que el central, debe estar en el

segundo subarreglo: {3,4} Se vuelve a dividir en dos: {}-3-{4} Como el elemento buscado coincide con el central, lo hemos encontrado. Si al final de la bsqueda todava no lo hemos encontrado, y el subarreglo a dividir est vacio {}, el elemento no se encuentra en el arreglo.

Bsqueda mediante transformacin de claves (hashing)

Es un mtodo de bsqueda que aumenta la velocidad de bsqueda, pero que no requiere que los elementos estn ordenados. Consiste en asignar a cada elemento un ndice mediante una transformacin del elemento. Esta correspondencia se realiza mediante una funcin de conversin, llamada funcin hash. La correspondencia ms sencilla es la identidad, esto es, al nmero 0 se le asigna el ndice 0, al elemento 1 el ndice 1, y as sucesivamente. Pero si los nmeros a almacenar son demasiado grandes esta funcin es inservible. Por eso, se realiza una transformacin al nmero de DNI para que nos de un nmero menor, por ejemplo coger las 3 ltimas cifras para guardar a los empleados en un arreglo de 1000 elementos. Para buscar a uno de ellos, bastara con realizar la transformacin a su DNI y ver si est o no en el arreglo. La funcin de hash ideal debera ser biyectiva, esto es, que a cada elemento le corresponda un ndice, y que a cada ndice le corresponda un elemento, pero no siempre es fcil encontrar esa funcin, e incluso a veces es intil, ya que puedes no saber el nmero de elementos a almacenar. La funcin de hash depende de cada problema y de cada finalidad, y se pueden utilizar con nmeros o cadenas, pero las ms utilizadas son: Restas sucesivas: esta funcin se emplea con claves numricas entre las que existen huecos de tamao conocido, obtenindose direcciones consecutivas. Aritmtica modular: el ndice de un nmero es resto de la divisin de ese nmero entre un nmero N prefijado, preferentemente primo. Los nmeros se guardarn en las direcciones de memoria de 0 a N-1. Este mtodo tiene el problema de que cuando hay N+1 elementos, al menos un ndice es sealado por dos elementos. A este fenmeno se le llama colisin Mitad del cuadrado: consiste en elevar al cuadrado la clave y coger las cifras centrales. Este mtodo tambin presenta problemas de colisin: Truncamiento: consiste en ignorar parte del nmero y utilizar los elementos restantes como ndice. Tambin se produce colisin. Plegamiento: consiste en dividir el nmero en diferentes partes, y operar con ellas (normalmente con suma o multiplicacin). Tambin se produce colisin

Tratamiento de colisiones: Qu pasa cuando a dos elementos diferentes les corresponde el mismo ndice. Pues bien, hay tres posibles soluciones: Cuando el ndice correspondiente a un elemento ya est ocupada, se le asigna el primer ndice libre a partir de esa posicin. Este mtodo es poco eficaz, porque al nuevo elemento se le asigna un ndice que podr estar ocupado por un elemento posterior a l, y la bsqueda se hace lenta, ya que no se sabe la posicin exacta del elemento. Tambin se pueden reservar unos cuantos lugares al final del arreglo para alojar a las colisiones. Este mtodo tambin tiene un problema: Cunto espacio se debe reservar? Lo ms efectivo es, en vez de crear un arreglo de nmero, crear un arreglo de punteros, donde cada puntero seala el principio de una lista enlazada. As, cada elemento que llega a un determinado ndice se pone en el ltimo lugar de la lista de ese ndice. El tiempo de bsqueda se reduce considerablemente, y no hace falta poner restricciones al tamao del arreglo, ya que se pueden aadir nodos dinmicamente a la lista.

Você também pode gostar