Divide y vencerás

Anuncio
Divide y vencerás
Divide y vencerás
• Técnica de diseño de algoritmos que consiste
en descomponer los casos complejos en casos
más pequeños y fáciles de resolver, y
combinar las soluciones obtenidas para
construir la solución del problema original
Ejemplos
• Exponenciación
¿cómo calcular eficientemente ak? La forma
natural es realizando k-1 multiplicaciones.
Esto puede mejorarse viendo que cuando k es
par, ak=(ak/2)2
si k  0
1
 k /2 2
k
a  (a ) si k es par
a(a k 1 ) si k es impar

Ejemplos
• QSort
Ejemplos
• Búsqueda de la mediana
Requiere ordenar los elementos (O(n log n)) y
luego seleccionar el elemento central
Otro problema parecido es conseguir el n-ésimo
elemento más pequeño de un arreglo
Si existiera la función seleccionar(A,n), calcular
la mediana se limitaría a una llamada a esa
función
Ejemplos
• Búsqueda de la mediana
La función seleccionar también puede
construirse en base a la función mediana
Recordemos la función pivote(A,p,k,l) que se
utiliza en QuickSort que utiliza p como pivote
del arreglo A, haciendo que los elementos
menores a p estén en las posiciones 0..k-1 y
los elementos mayores en las posiciones l..n-1
Ejemplos
• Búsqueda de la mediana
Pueden suceder ahora tres casos:
1. s=k: el elemento buscado es p
2. s < k: el elemento buscado está en la mitad
izquierda de A
3. s > k: el elemento buscado está en la mitad
derecha de A
Ejemplos
• Iterativamente:
funcion seleccion(A,s)
i=0; j=n-1;
mientras verdad
p = mediana(A[i..j])
pivote(A[i..j],p,k,l)
si s<k entonces
j=k; // buscar ahora en el lado izq
sino si s>l entonces
i=l; // buscar en el lado derecho
sino
retornar p; // bingo!
fsi
fmientras
ffuncion
Ejemplos
• Cada llamada a mediana es de O(n log n), pero
el algoritmo se comporta igual si usamos
como pivote cualquier elemento del arreglo,
en particular p=A[i];
• Luego, mediana se reduce a:
retornar seleccion(A, n/2);
Ejemplos
• Multiplicación
• La multiplicación tradicional de números
enteros tiene O(N^2)
• Sin embargo, esto puede mejorarse
• Por ejemplo, 324 x 1390:
• 0324 x 1390 podemos separarlo como w=03,
x=24, y=13, z=90
Ejemplos
• 0324 x 1390 podemos separarlo como w=03,
x=24, y=13, z=90
• Podemos ver que:
• 324 = 102w+x
• 1390 = 102y+z
• Luego:
• 324x1390 = (102w+x)(102y+z)=
104wy+102(w+y)+xz
Ejemplos
• 324x1390 = (102w+x)(102y+z)=
104wy+102(w+y)+xz
• Ahora hagamos:
• r = (w+x)(y+z)=wy+wz+xy+xz
• p= wy
• q= xz
• Finalmente podemos calcular el resultado
como 104p+102(r-p-q)+q
Ejemplos
• Hemos reducido 16 multiplicaciones
originalmente a únicamente 3 (obviando las
multiplicaciones por potencias de 10)
• En general, si los números tienen n dígitos
podemos separarlos en números de n/2
dígitos
• Las 3 multiplicaciones que aparecen se hacen
de la misma forma hasta llegar a números
pequeños que puedan manejarse fácilmente
Ejemplos
• Multiplicación de matrices de Strassen
• Sean A y B dos matrices de nxn y sea C = A x B
• El algoritmo clásico de multiplicación de
matrices es de O(n^3)
• Strassen logró mejorar este tiempo a finales
de los 60 aplicando un principio parecido al
usado anteriormente para números enteros
Ejemplos
• Multiplicación de matrices de Strassen
Ejemplos
• Multiplicación de matrices de Strassen
• Este algoritmo permite mejorar la
multiplicación de matrices de O(N^3) a
O(N^2.807)
• Actualmente el algoritmo de CoppersmithWinograd (2008) permite multiplicar matrices
en O(N^2.376)
• Sin embargo, para obtener ventajas las
matrices deben ser realmente grandes
Descargar