190 likes | 407 Views
Bloque 2: Divide y Vencerás. Unidad 2: Aplicaciones. Aplicaciones típicas DyV. Aplicaciones típicas Multiplicación entera y matricial Búsqueda y ordenación Selección y determinación de la media Exponenciación Las aplicaciones típicas son importantes porque pueden utilizarse como:
E N D
Bloque 2: Divide y Vencerás Unidad 2: Aplicaciones
Aplicaciones típicas DyV • Aplicaciones típicas • Multiplicación entera y matricial • Búsqueda y ordenación • Selección y determinación de la media • Exponenciación • Las aplicaciones típicas son importantes porque pueden utilizarse como: • Ejemplos del modo de confeccionar algoritmos DyV • Bloques constructores de algoritmos específicos
Multiplicación de enteros largos • El algoritmo clásico de multiplicación es O(n2) • Es posible aplicar la técnica divide y vencerás a este problema, conforme a la siguiente estrategia: • Sean 2 números, a y b, de tamaño n • Descompongamos los números a y b en 2 números de longitud n/2 • El producto es
Multiplicación de enteros largos • Si n es par, las ecuaciones anteriores se simplifican • Cuatro multiplicaciones de números con tamaño n/2 es similar a una multiplicación de números de tamaño n. No obstante, considerando:
Multiplicación de enteros largos • Se obtiene que • Esta estrategia permite reducir de 4 a 3 multiplicaciones, de números de longitud n/2, a costa de aumentar el número de sumas y desplazamientos (multiplicación por potencias de 10) • La complejidad de este algoritmo es (nlog 3), aunque sólo es eficiente para n grandes, debido a la existencia de constantes ocultas con un valor elevado
A11 B11 C11 A12 B12 C12 A21 B21 C21 A22 B22 C22 Multiplicación de matrices • Consiste multiplicar dos matrices cuadradas A, B de tamaños n x n, en un orden inferior a O(n3) • Es una variación del problema de la multiplicación de enteros largos, consistente en dividir las matrices en submatrices y realizar los productos parciales • En su formulación más evidente, es necesario resolver 8 subproblemas de tamaño n/2, siendo interesante la estrategia DyV únicamente cuando se resuelven 7 o menos subproblemas x =
Multiplicación de matrices • La solución consiste en: P = (A11+A22)(B11+B22) Q = (A12+A22) B11 C11 = P + S - T + U R = A11 (B12-B22) C12 = R + T S = A22(B21-B11) C21 = Q + S T = (A11+A12)B22 C22 = P + R - Q + U U = (A21-A11)(B11+B12) V = (A12-A22)(B21+B22) • Este algoritmo posee unO(nlog7) O(n2.81). Al igual que para el caso de la multiplicación de enteros, las constantes ocultas son muy altas y el algoritmo es útil solo para valores de n grandes
Búsqueda • La búsqueda binaria probablemente el algoritmo DyV más conocido, con O(log n) • Dado que se trata realmente de un algoritmo de simplificación, en lugar de DyV, puede programarse fácilmente de forma iterativa, la cual es su implementación más frecuente FUNCTION busquedaBinaria(T[1..n], x):1..n; BEGIN i:= 1; j:= n; repeat m:=(i+j) div 2; if T[m] > x then j:= m-1 else i:= m+1 until i>j or T[m]=x; busquedaBinaria:= m; END;
Ordenación • Dos algoritmos de ordenación bien conocidos son DyV • Mergesort • Quicksort • Para ordenar mediante mergesort (ordenación por mezcla) los elementos de un array de tamaño n se: • Divide el array original es dividido en dos trozos de tamaño igual (o lo más parecido posible), es decir n/2 y n/2. • Resuelven recursivamente los subproblemas • Llega al caso base cuando se obtiene un subarray de un solo elemento (versión pura) o cuando se obtiene un subarray de tamaño reducido (versión con umbral) • Combinan los dos subarrays (lo cual se puede realizar en O(n)) • Se obtiene una función de complejidad O(n log n), frente al O(n2) típico de los algoritmos no DyV de ordenación
Ordenación PROCEDURE mergeSort (VAR T[1..n]) BEGIN {se podría evitar la utilización de un algoritmo básico} if T es pequeño then OrdenaciónDirecta(T[1..n]) else begin s:= n div 2; mergeSort(T[1..s]); mergeSort(T[s+1..n]); merge(T[1..n], T[1..s], T[s+1..n]); end; END;
Ordenación • Para ordenar mediante quicksort los elementos de un array de tamaño n se: • Divide el array utilizando un procedimiento Pivote, que devuelve un entero l tal que A[k] A[l] A[m], para k = 1..l-1, m=l+1..n • Resuelven recursivamente los subproblemas • Llega al caso base cuando se obtiene un subarray de un solo elemento (versión pura) o cuando se obtiene un subarray de tamaño reducido (versión con umbral) • No es necesario combinar los subarrays
Ordenación PROCEDURE quickSort (VAR T[1..n]) BEGIN {Puede no utilizarse un algoritmo básico} if n es pequeño then OrdenaciónDirecta(T[1..n]) else begin pivote(T[1..n], l); quickSort(T[1..l-1]); quickSort(T[l+1..n]); end; END;
Ordenación PROCEDURE pivote(T[i..j]; var l: integer) {en l se devuelve la posición del pivote} BEGIN p:= T[i]; k:= i; l:= j+1; repeat k:= k+1 until (T[k] > p) or (k j); repeat l:= l-1 until (T[l] p); while k < l do begin intercambiar (T[k], T[l]); repeat k:= k+1 until (T[k] > p); repeat l:= l-1 until (T[l] p); end; Intercambiar (T[i], T[l]); END;
Ordenación • Quicksort posee una función de complejidad O(n log n) en el caso medio • No obstante, en el caso peor la complejidad de quicksort es O(n2) • Ocurre, dada la función pivote, vista anteriormente, cuando el array está ordenado de modo decreciente o todos los elementos son iguales • La clave para conseguir un algoritmo O(n log n) es seleccionar adecuadamente la mediana (ver a continuación) • Aun así, si todos los elementos del array son iguales, el comportamiento del algoritmo sigue siendo O(n2) • Se soluciona utilizando un pivote modificadopivoteBis(T[i..j]; media, var k, l: integer) 3.3.5. El problema de selección.
Selección • Se denomina Problema de Selección a: • Dado un array T[1..n] y • Un entero s tal que 1<= s <= n • Identificar el elemento que, una vez ordenado T de modo no decreciente, ocuparía la posición s-ésima • Solucionar el problema de selección es sencillo en O(n log n) • Basta ordenar el array T y acceder a la s-ésima posición • No obstante, puede realizarse en O(n), habida cuenta de que exista un procedimiento eficiente para calcular la media de un conjunto de datos • De hecho, el problema de selección es equivalente al cálculo de la mediana, mínimo y máximo
Selección • Suponiendo la existencia de una función mediana, el problema se resolvería siguiendo los pasos: • Identificar la mediana del array • Utilizando un procedimiento como pivoteBis, reordenar el array • Si 1 <= s < k, repetir con el subarray T[1..k-1] • Si k <= s <= l, se ha terminado • Si l < s <= n, repetir con el subarray T[l+1..n], buscando el s-l+1 elemento • Varias notas: • El algoritmo depende del cálculo de la mediana. Si la mediana calculada difiere mucho de la media real, la función de complejidad se torna O(n2), al igual que en el quicksort • Se utiliza pivoteBis, y no pivote, para evitar el caso patológico de que todos los elementos del array sean iguales
Selección • El algoritmo sería de la forma siguiente: FUNCTION seleccion(T[1..n], s):tipo; BEGIN p:= mediana(T[1..n]); pivoteBis(T[1..n], p, k, l); if s < k then selección:= seleccion(T[1..k-1], s) else if s > l then selección:= seleccion(T[l+1..n], s-l+1) else selección:= p; END;
Selección • La mediana puede calcularse (en realidad, se calcula un valor relativamente similar) mediante el siguiente procedimiento de mediana a 5 FUNCTION pseudoMediana(T[1..n]):tipo; BEGIN {Es de nuevo un algoritmo de DyV} if n <= 5 then pseudoMediana:= medianaAdHoc(T[1..n]) else begin z:= n div 5; array Z[1..z]; for i:= 1 to z do Z[i]:= medianaAdHoc(T[5i-4..5i]); pseudoMediana:= selección(Z, z div 2 + 1); end; END;
Exponenciación • Realizar la operación an implica, en su formulación más simple, una complejidad O(n) • Es posible, utilizando DyV, utilizar la siguiente estrategia • El número de multiplicaciones utilizando la versión DyV es O(log n). No obstante, teniendo en cuenta el tamaño de los números implicados en la multiplicación, éste algoritmo sólo es eficiente cuando se utilizan productos DyV