02 - Analisis de Algoritmos - 2 - 2

Descargar como pdf o txt
Descargar como pdf o txt
Está en la página 1de 44

ANALISIS DE ALGORITMOS

TEMA: ALGORITMOS DE ORDENAMIENTO


AVANZADO - BUSQUEDA
Temario
 Algoritmos de ordenamiento
 Quick Sort
 Merge Sort
 HeapSort
 Algoritmos de búsqueda
 Algoritmo de Karatsuba
Algoritmo QuickSort
Este método fue creado por el científico británico Charles Antony Richard
Hoare, también conocido como Tony Hoare en 1960, su algoritmo
Quicksort es el algoritmo de ordenamiento más ampliamente utilizado en
el mundo.
Algoritmo QuickSort
El método Quick Sort es actualmente el mas eficiente y veloz de los
método de ordenación interna. Es también conocido con el nombre del
método rápido y de ordenamiento por partición.

Este método es una mejora sustancial del método de intercambio directo


y recibe el nombre de Quick Sort, por la velocidad con la que ordena los
elementos del arreglo.
Quicksort es un algoritmo basado en la técnica de divide y vencerás, que
permite, en promedio, ordenar n elementos en un tiempo proporcional a
n log n.
Algoritmo QuickSort

Pasos que sigue el algoritmo quicksort:


• Seleccionar el elemento central de a[0:n-1] como pivote
• Dividir los elementos restantes en particiones izquierda y derecha, de
modo que ningún elemento de la izquierda tenga una clave (valor)
mayor que el pivote y que ningún elemento a la derecha tenga una clave
más pequeña que la del pivote.
• Ordenar la partición izquierda utilizando quicksort recursivamente.
• Ordenar la partición derecha utilizando quicksort recursivamente.
• La solución es partición izquierda seguida por el pivote y a continuación
partición derecha.
Algoritmo QuickSort PIVOT
En este caso se considera PIVOT a un elemento central.
También se puede tomar el primer elemento del arreglo.

Elementos menores a PIVOT Elementos mayores a PIVOT

Elementos menores a PIVOT Elementos mayores a PIVOT

Cuando el tamaño del arreglo


es 1 se detiene
Algoritmo QuickSort
Algoritmo QuickSort
Algoritmo QuickSort
Algoritmo QuickSort
Algoritmo Merge Sort
Mergesort es un algoritmo de tipo ‘Divide y vencerás’. Divide el array
en dos mitades recursivamente, se llama a sí mismo para las dos
mitades y después una las dos mitades ordenadas.
Algoritmo Merge Sort
 Como se muestra en la imagen, el arreglo de
datos se divide a sí mismo hasta alcanzar el
tamaño ‘1’ de elementos, eso quiere decir
que el vector de tamaño 1 está ordenado.
 Cuando el arreglo se encuentre en ésta
parte cada sub-arreglo se ordena
recursivamente ‘uniéndolos’ y comparando
valores con el arreglo de a lado.
Implementación en Java
Implementación en Java
Implementación en Java
Algoritmo HeapSort
El método de ordenación HeapSort es también conocido con el nombre
“montículo”. Su nombre se debe a su autor J. W. J. Williams quien lo
bautizó así en 1964. Es el más eficiente de los métodos de ordenación
que trabajan con árboles.

La idea central de este algoritmo consiste en lo siguiente:


 Construir un montículo.
 Eliminar la raíz del montículo en forma repetida.
Algoritmo HeapSort
El método de ordenación se puede describir con los siguientes pasos:
1. Construir un montículo inicial con todos los elementos del vector A
[1], A [2], …., A [n]
2. Intercambiar los valores de A [1] y A [n] (siempre queda el máximo
en el extremo)
3. Reconstruir el montículo con los elementos A [1], A [2],……, A [n-1]
4. Intercambiar los valores de A [1] y A [n-1]
5. Reconstruir el montículo con los elementos A [1], A [2],……, A [n-2]
Algoritmo Heap Sort
Este es un proceso iterativo que partiendo de un montículo inicial,
repite intercambiar los extremos, decremento en 1 la posición del
extremo superior y reconstruir el montículo del nuevo vector.
Lo expresamos en forma algorítmica así:
Ordenación Heapsort (Vector, N)
Debe construirse un montículo inicial (Vector, N)
desde k = N hasta 2 hacer
intercambio (Vector [1], Vector [k])
construir montículo (Vector, 1, k-1)
fin desde
Ejemplo: Algoritmo Heap Sort (monticulos)
Índice 0 1 2 3 4 5 6 7 8 9
Elemento 5 8 6 1 4 7 3 9 2 0

Creamos un árbol usando los datos


8 6
del arreglo. Insertando los valores
de izquierda a derecha.
1 4 7 3

9 2 0
Ejemplo: Algoritmo Heap Sort (monticulos)
Posición del ultimo elemento del arreglo
n = len – 1 = 9
0 1 2 3 4 5 6 7 8 9
Posición del ultimo padre
posPadre = (n-1)/2 = 8/2 = 4 5 8 6 1 4 7 3 9 2 0
posIzq(i) = 2*i+1 5 8 6 9 4 7 3 1 2 0
posDer(i) = 2*i+2
5 8 7 9 4 6 3 1 2 0
9 5 9 7 8 4 6 3 1 2 0
9 5 7 8 4 6 3 1 2 0
5 7
0 5 7 8 4 6 3 1 2 9

8 4 6 3

1 2 0
Ejemplo: Algoritmo Heap Sort (monticulos)
Posición del ultimo elemento del arreglo Posición del ultimo elemento del arreglo Posición del ultimo elemento del arreglo
n = len – 1 = 8 n = len – 1 = 7 n = len – 1 = 6
Posición del ultimo padre Posición del ultimo padre Posición del ultimo padre
posPadre = (n-1)/2 = 3 posPadre = (n-1)/2 = 3 posPadre = (n-1)/2 = 3
posIzq(i) = 2*i+1 posIzq(i) = 2*i+1 posIzq(i) = 2*i+1
posDer(i) = 2*i+2 posDer(i) = 2*i+2 posDer(i) = 2*i+2

0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9

0 5 7 8 4 6 3 1 2 9 2 0 7 5 4 6 3 1 8 9 1 2 6 5 4 0 3 7 8 9
0 5 7 8 4 6 3 1 2 9 2 0 7 5 4 6 3 1 8 9 1 5 6 2 4 0 3 7 8 9
0 8 7 5 4 6 3 1 2 9 2 7 0 5 4 6 3 1 8 9 6 5 1 2 4 0 3 7 8 9
8 0 7 5 4 6 3 1 2 9 7 2 0 5 4 6 3 1 8 9 3 5 1 2 4 0 6 7 8 9
2 0 7 5 4 6 3 1 8 9 1 2 0 5 4 6 3 7 8 9
Ejemplo: Algoritmo Heap Sort (monticulos)
Posición del ultimo elemento del arreglo Posición del ultimo elemento del arreglo Posición del ultimo elemento del arreglo
n = len – 1 = 5 n = len – 1 = 4 n = len – 1 = 3
Posición del ultimo padre Posición del ultimo padre Posición del ultimo padre
posPadre = (n-1)/2 = 2 posPadre = (n-1)/2 = 1 posPadre = (n-1)/2 = 1
posIzq(i) = 2*i+1 posIzq(i) = 2*i+1 posIzq(i) = 2*i+1
posDer(i) = 2*i+2 posDer(i) = 2*i+2 posDer(i) = 2*i+2

0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9
3 5 1 2 4 0 6 7 8 9 0 4 1 2 3 5 6 7 8 9 3 2 1 0 4 5 6 7 8 9
3 5 1 2 4 0 6 7 8 9 4 0 1 2 3 5 6 7 8 9 3 2 1 0 4 5 6 7 8 9
5 3 1 2 4 0 6 7 8 9 3 0 1 2 4 5 6 7 8 9 0 2 1 3 4 5 6 7 8 9
0 3 1 2 4 5 6 7 8 9
Ejemplo: Algoritmo Heap Sort (monticulos)
Posición del ultimo elemento del arreglo Posición del ultimo elemento del arreglo
n = len – 1 = 2 n = len – 1 = 1
Posición del ultimo padre Posición del ultimo padre
posPadre = (n-1)/2 = 1 posPadre = (n-1)/2 = 1
posIzq(i) = 2*i+1 posIzq(i) = 2*i+1
posDer(i) = 2*i+2 posDer(i) = 2*i+2

0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9
0 2 1 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9
0
2 0 1 3 4 5 6 7 8 9
1 2
1 0 2 3 4 5 6 7 8 9
3 4 5 6

7 8 9
Algoritmo Heap Sort
Dinámica N° 3
En grupo proceda a realizar una comparación del tiempo de ejecución
de los 3 algoritmos: Quick Sort, Merge Sort y Heap Sort

Grup Lenguaje Consideraciones:


o • Considerar un arreglo de 100 elementos numéricos. (Pueden
1, 8 Python generar aleatoriamente). Valores de los elementos en el rango
de 1 a 1000.
2, 7 JavaScript • También probar con un arreglo de cadenas de nombres. Pueden
3, 6 Java usar el siguiente recurso: https://fossbytes.com/tools/random-
4, 5 PHP name-generator
• Considerar situaciones:
• Arreglo ya esta ordenado.
• Arreglo ya esta desordenado.
Algoritmos de búsqueda
Un algoritmo de búsqueda es un conjunto de instrucciones que están
diseñadas para localizar un elemento con ciertas propiedades dentro
de una estructura de datos
Búsqueda secuencial
El problema de búsqueda en un arreglo presenta varias instancias:
 El elemento a buscar se encuentra en la posición 0
 El elemento a buscar se encuentra en la posición 1
Con éxito
 ….
 El elemento a buscar se encuentra en la posición n-1
 El elemento a buscar no se encuentra (Sin Éxito)
Búsqueda secuencial
Como el algoritmo realiza la búsqueda de forma ascendente(de
izquierda a derecha, y desde la posición 0 del arreglo):
• Caso mejor: El elemento a buscar esta en la posición 0 del arreglo.
• Caso peor: la búsqueda fracasa o tiene éxito en la posición n-1.
Búsqueda secuencial
• El costo del algoritmo depende:
• Número de elementos del arreglo.
• Instancia del problema
• Considerando el valor a buscar y el incremento tenemos:
• Mejor caso => T(n) = 1 Constante
• Peor caso => T(n) = Lineal
Ejemplo: Búsqueda secuencial
Búsqueda de un elemento en una tabla ordenada
Solución secuencial:

Complejidad: O(n)
Búsqueda binaria recursiva
Para este algoritmo:
 Cada llamada genera una llamada recursiva (s=1)
 El tamaño del subproblema es la mitad del problema original (b=2)
 Sin considerar la recurrencia el resto de operaciones son O(1) luego g(n) es O(1) =
O(n0) (k=0)
 Luego t(n) es O(nk log n) = Θ(n0 log n) = Θ(log n)
Ejemplo: Búsqueda binaria
Búsqueda de x=9

En cada caso (hasta que x=t[k] o i>j)


 Si x > t[k] -> i=k+1
 Si x < t[k] -> j= k-1
 K = (i+j) / 2
Calculo de la complejidad del tiempo
• Digamos que la iteración en la búsqueda binaria termina después de k
iteraciones.
• En cada iteración, el arreglo se divide por la mitad. Entonces, digamos
que la longitud de la arreglo en cualquier iteración es n
Iteración Longitud de arreglo
1 n
2 n/2
3 (n/2)/2 = n/22
… ….
k n/2k
Calculo de la complejidad del tiempo
• Después de k divisiones, la longitud de la arreglo se convierte en 1.
• Por lo tanto:
• Longitud del arreglo => n/2k = 1 => n = 2k
• Aplicación de la función de registro en ambos lados
• => log 2(n) = log2(2k)
• => log 2(n) = k log2(2)
• Como (log a(a)=1), por lo tanto:
• => k = log 2(n)
• Con eso demostramos que la complejidad de la búsqueda binaria es
log2(n)
Ejemplo: Búsqueda binaria recursiva
Algoritmo de Karatsuba
 El método de Karatsuba permite realizar multiplicaciones de manera
más eficiente, en el caso particular de este trabajo de tesis el método
de Karatsuba será utilizado para realizar multiplicaciones de
polinomios.
 El algoritmo de multiplicación de Karatsuba utiliza la idea recursiva.
Algoritmo de Karatsuba
• Con el apoyo de la bibliografía, se puede recordar cómo dicha
operación dentro de un contexto multiplicativo, u * v, se expresa
matemáticamente usando el citado algoritmo como:
Algoritmo de Karatsuba
La idea del algoritmo es la siguiente:
Por ejemplo 7425 en base 10 es:
• x = x1*B^m + x0 7 * 10^3 + 425
• y = y1*B^m + y0 x1 = 7
x0 = 425
donde x0 y y0 son menos de B^m. El producto entonces es:
• xy = (x1*B^m + x0)(y1*B^m + y0)
• xy = z2*B^2m + z1*B^m + z0
Donde:
• z2 = x1*y1
• z1 = x1*y1 + x0*y1
• z0 = x0*y0
Algoritmo de Karatsuba
Estas fórmulas requieren de cuatro multiplicaciones, se observa que x y se pueden
calcular en solo tres multiplicaciones, a costa de algunas adiciones extras. Con z0 y
z2.
z1 = (x1 + x0)*(y1 + y0) – z2 –z0
Que reemplaza la expresión
z1 = x1*y1 + x0*y1
Por
z1 = (x1 + x0)*(y1 + y0) – x1*y1 –x0*y0
Y el resultado queda de esta manera
resultado = z2*B^2m + z1*B^m + z0
Ejemplo: algoritmo de Karatsuba
Para calcular el producto de 12345 y 6789, elija B = 10 y m = 3. Luego
de descomponerlos se operan dos de entrada utilizando la base
resultante (B^m = 1000), como:
Donde:
• 12345 = 12 * 1000 + 345 X0 = 345
X1 = 12
• 6789 = 6 * 1000 + 789 Y0 = 789
Y1 = 6
Ejemplo: algoritmo de Karatsuba
Sólo tres multiplicaciones, que operan en números enteros más
pequeños, se utilizan para calcular tres resultados parciales
z2 = 12 × 6 = 72 Tenemos:
X0 = 345
z0 = 345 × 789 = 272 205 X1 = 12
z1 = (12 + 345) × (6 + 789) - z2 - z0 Y0 = 789
Y1 = 6
z1 = 357 × 795 - 72 - 272205
z1 = 283815 - 72-272205 = 11538 Donde:
z2 = x1*y1
z0 = x0*y0
z1 = (x1 + x0)*(y1 + y0) – z2 –z0
Ejemplo: algoritmo de Karatsuba
Resultado final -> z2*B^2m + z1*B^m + z0
z2 = 72, z1 = 11538, z0 = 272 205
resultado = 72 * 1000^2 + 11538 * 1000 + 272205
= 72 * 1000000 + 11538 * 1000 + 272205
= 72 000000 + 11538 000 + 272205
= 83810205
Algoritmo de Karatsuba
Dinámica N° 4
En grupo proceda aplicar el algoritmo de karatsuba a las siguientes
multiplicaciones:
• 235689 x 254178
• 985236 x 32147
• 52146 x 45872

Luego proceda a evaluar el tiempo de procesamiento de cada uno de


ellos haciendo de la implementación del algoritmo en un lenguaje de
programación.

También podría gustarte