DividirYConquistar 4x1
DividirYConquistar 4x1
DividirYConquistar 4x1
Introducción
Algoritmos y Complejidad
Ordenamiento: mergesort y quicksort
Algoritmos “dividir y conquistar”
Elemento mediano
Pablo R. Fillottrani
Multiplicación de matrices
Depto. Ciencias e Ingeniería de la Computación
Universidad Nacional del Sur
Par de puntos más cercanos
Primer Cuatrimestre 2017
Criptografía – exponenciación modular
Generalidades
I “dividir y conquistar” (DYC) es un técnica de diseño de algoritmos I es importante entonces determinar para cada problema:
que consiste en 1. cuáles son las subinstancias, y cómo se encuentran
1. descomponer la instancia del problema a resolver en un conjunto 2. cómo solucionar el problema en las subinstancias
de instancias más pequeñas del mismo problema 3. cómo combinar las soluciones parciales
2. resolver independientemente cada una de estas subinstancias. I para el punto 2. se puede aplicar nuevamente la técnica DYC,
No se guardan resultados de instancias previamente calculadas,
hasta que se llegue a subinstancias de tamaño suficientemente
como en PD.
3. combinar estas soluciones en una solución a la instancia original. pequeño para ser resueltas inmediatamente.
I es probable que esta técnica resulte en un algoritmo más
eficiente que el original.
Algoritmos y Complejidad Algoritmos y Complejidad
Introducción Introducción
Generalidades Generalidades
Esquema General
function DYC(x)
IF x es suficientemente simple I se debe especificar cuáles son el algoritmo básico, el de
RETURN algoritmoBasico(x) descomposición y el de combinación
ELSE I también se necesita determinar cuándo una instancia es
descomponer x en x[1],x[2],...,x[s] suficientemente simple como para dejar de aplicar la división
FOR i ::= 1 TO s
I si se trata de tamaño, este valor se denomina umbral
y[i] ::= DYC(x[i])
ENDFOR
combinar y[i] en una solución y a x
RETURN y
ENDINF
I el tiempo de ejecución está determinado por la recurrencia: I los métodos vistos para resolver recurrencias brindan soluciones
a la mayoría de las recurrencias generadas por algoritmos DYC.
f (n) si n es simple I en especial el método del teorema maestro.
TDYC (n) =
sTDYC (n ÷ b) + g (n) sino
I para que DYC sea eficiente las subinstancias deben ser todas de
donde aproximadamente el mismo tamaño.
I n = |x |
I además, se debe estudiar cuidadosamente cuál o cuáles son los
I b es una constante tal que n ÷ b aproxime el tamaño de las
mejores umbrales.
subinstancias
I f (n) es el tiempo de algoritmoBásico()
I g (n) es el tiempo de la partición y combinación.
Algoritmos y Complejidad Algoritmos y Complejidad
Introducción Introducción
Generalidades Generalidades
Correctitud
I es muy difícil, o a veces imposible, encontrar teóricamente un
umbral optimal (ya sea para cada instancia o incluso para cada
n).
I puede pasar que el umbral óptimo cambia de instancia en I a diferencia de los algoritmos greedy, es fácil probar la
instancia, y que dependa de cada implementación en particular. correctitud de los algoritmo DYC
I también es poco práctico encontrar empíricamente una I se supone la correctitud del algoritmo básico, y se prueba por
aproximación a un buen umbral: sería necesario ejecutar el inducción sobre el tamaño de la instancia que la solución
algoritmo muchas veces en una gran cantidad de instancias obtenida es correcta suponiendo la correctitud de las instancias
I la solución generalmente tomada es un camino híbrido: más chicas
1. se encuentra la función exacta del tiempo de ejecución de los I no vamos a ver en detalle ninguna prueba de correctitud para
algoritmos (no alcanza con conocer sólo el orden!) dando valores DYC, pero no son difíciles de hacer
a las constantes de acuerdo pruebas empíricas.
2. se toma como n0 un valor en el cual tome aproximadamente el
mismo tiempo el algoritmo directo que el DyC
Algoritmos y Complejidad Algoritmos y Complejidad
Introducción Introducción
Multiplicación de enteros grandes Multiplicación de enteros grandes
I Problema: supongamos que tenemos que multiplicar dos enteros I si se implementa cualquiera de los algoritmos tradicionales para
a y b, de n y m dígitos cada uno, cantidades que no son posibles el producto entre dos números cualesquiera, el resultado es de
de representar directamente por el HW de la máquina Θ(nm)
I es fácil implementar una estructura de datos para estos enteros I aplicaremos DYC para tratar de mejorar este tiempo. Suponiendo
grandes, que soporte por el momento que n = m
1. suma de Θ(n + m).
2. resta de de Θ(n + m).
3. productos y divisiones por la base de Θ(n + m).
I aplicando DYC una sola vez, y usando base 10 se tiene: I si se extiende el método aplicando DYC recursivamente se
a x y b w z obtiene la recurrencia:
Θ(n2 )
dn/2e bn/2c dn/2e bn/2c si n ≤ n0
tDyC (n) =
I esto es: 4tDyC (dn/2d) + Θ(n) sino
I el resultado no es bueno (aplicar el teorema maestro!)
a×b = (x10bn/2c + y) × (w10bn/2c + z) = I el principal problema es que se necesitan cuatro productos más
= xw102bn/2c + (xz + wy)10bn/2c + yz pequeños.
Algoritmos y Complejidad Algoritmos y Complejidad
Introducción Introducción
Multiplicación de enteros grandes Multiplicación de enteros grandes
a×b = xw102bn/2c + (r − xw − yz)10bn/2c + yz I comparado con an2 + bn + c es sólo una mejora del 25 % en la
constante del término principal, pero igualmente es de Θ(n2 )
I se tiene entonces dos productos de bn/2c dígitos, un producto
de a lo sumo bn/2c + 1 dígitos, más sumas, restas y productos
de potencias de la base.
I para obtener una mejora asintótica es preciso aplicar DYC I se puede deducir de esta recurrencia que
recursivamente a los productos más pequeños TDyC (n) ∈ O (nlog 3 |n = 2k ), usando otra vez el teorema maestro.
I el tiempo de este algoritmo genera la siguiente recurrencia: I como TDyC (n) es eventualmente no decreciente y nlog 3 es de
crecimiento suave, entonces TDyC (n) ∈ O (nlog 3 ), aplicando la
Θ(n2 ) si n es pequeño
regla de las funciones de crecimiento suave.
TDyC (n) = TDyC (bn/2c) + TDyC (dn/2e)+
+TDyC (bn/2c + 1) + Θ(n) sino
I análogamente se puede mostrar que TDyC (n) ∈ Ω(nlog 3 )
(ejercicio).
Algoritmos y Complejidad Algoritmos y Complejidad
Introducción Introducción
Multiplicación de enteros grandes Multiplicación de enteros grandes
BÚSQUEDA BINARIA
function BúsqBinaria(T[i..j],x)
I este algoritmo naïve tiene tiempo Θ(n) en el peor caso, y Θ(1) IF i=j
en el mejor caso RETURN i
ELSE
I si todas las instancias del arreglo tienen igual probabilidad de ser
k ::= (i+j) div 2
llamadas, entonces el tiempo promedio también es de Θ(n)
IF x<=T[k]
I para aplicar DYC se determina en cuál mitad del arreglo debería
RETURN BúsqBinaria(T[i..k],x)
estar x, comparándolo con el elemento del medio
ELSE
I luego se busca recursivamente en esa mitad RETURN BúsqBinaria(T[k+1..n],x)
ENDIF
ENDIF
Mergesort(A[1..n])
IF n es pequeño
RETURN Inserción(A)
I la partición consiste en la creación de dos mitades del arreglo
ELSE original
crear A1 y A2 subarreglos de A I la combinación es la mezcla de las mitades ordenadas
B1 ::= Mergesort(A1) I hay que tener cuidado con el manejo de los parámetros, para
B2 ::= Mergesort(A2) evitar duplicar los arreglos. En este caso se pasarán los índices
Mezcla(B1, B2, B)
RETURN B
ENDIF
Ejercicios
I es fundamental para que el tiempo sea de Θ(n log n) que las dos
subinstancias en las que se parte el problema sean de tamaño
semejante
I ¿qué pasa si se divide el problema original en subinstancias de
I en el caso extremo de partir en subinstancias de tamaño
tamaño k y n − k , con k constante?
desparejo, la recurrencia sería
I ¿qué pasa si se divide el problema original en tres subinstancias
Θ(n2 ) si n ≤ n0 de tamaño semejante?
T (n) = T (n − 1) + T (1) + Θ(n) = I ¿qué pasa si la partición o la combinación toman tiempo de
= T (n − 1) + Θ(n) sino
Θ(n2 ) en lugar de Θ(n)?
Quicksort
Algoritmo de pivoteo
...
WHILE k<l I el total de iteraciones es l − i + 1 para k y j + 1 − l para j
intercambiar A[k] y A[l] I luego en total de iteraciones es de Θ(j − i )
REPEAT I como el tiempo del cuerpo de los ciclos es constante, el tiempo
k ::= k+1 total es entonces de Θ(j − i )
UNTIL A[k]>piv
REPEAT
l ::= l-1
UNTIL A[l]<=piv
ENDWHILE
Algoritmos y Complejidad Algoritmos y Complejidad
Ordenamiento: mergesort y quicksort Ordenamiento: mergesort y quicksort
Quicksort Quicksort
Análisis probabilístico
I el tiempo promedio está definido entonces por la recurrencia:
n−1
1
I se puede probar que el tiempo promedio del quicksort es de Tprom (n) = ( ∑ Θ(n) + Tprom (k ) + Tprom (n − 1 − k )) =
n k =0
Θ(n log n), asignando igual probabilidad a todos los arreglos
I supongamos que todas las n! instancias tienen igual probabilidad 2 n−1
= Θ(n) + ∑ Tprom (k ) =
de ser llamadas, y que todos los elementos de T son distintos n k =0
n−1
I esto implica que el pivote cae con igual probabilidad en cada una 2
= Θ(n) + [Tprom (0) + Tprom (1) + ∑ Tprom (k )] =
de las posiciones del arreglo a ordenar; y también que cada uno n k =2
de las subinstancias generadas heredan una distribución
2 n−1
uniforme. = Θ(n) + ∑ Tprom (k )
n k =2
I también se puede elegir el pivote al azar, resultando en una I Problema: se tiene un arreglo A[1..n] de enteros, no
versión probabilística de Quicksort con tiempo esperado de necesariamente ordenado, y se quiere encontrar el elemento
Θ(n log n) mediano.
I la ventaja de esta versión es que no existe una instancia en la I éste es el elemento que estaría en la posición dn/2e si el arreglo
que tarde más, sino que ciertas ejecuciones sobre cualquier estuviera ordenado.
instancia son las que llevan el peor caso I si el elemento mediano es elegido como pivote cuando no hay
elementos repetidos, se asegura la partición del arreglo en
subarreglos de tamaño semejante
Algoritmos y Complejidad Algoritmos y Complejidad
Elemento mediano Elemento mediano
Selección
SELECCIÓN
function Selección(A[i..j],s)
p ::= Mediano(A[i..j])
PivotearBH(p,A[i..j],k,l)
I la reducción MEDIANO −→ SELECCIÓN es trivial, basta con
CASE
llamar a SELECCIÓN con s = dn/2e.
s<=k: j ::= k
I la reducción SELECCIÓN −→ MEDIANO tampoco es difícil, ya r ::= Selección(T[i..j],s)
que es muy parecida al algoritmo de búsqueda binaria k<s<l: r ::= p
s>=l: i ::= l
r ::= Selección(T[i..j],s-l+1)
ENDCASE
RETURN r
Algoritmos y Complejidad Algoritmos y Complejidad
Elemento mediano Elemento mediano
Selección Selección
Costo Veces
I se necesita entonces un algoritmo eficiente para seleccionar un function PseudoMediano(A[1..n])
elemento que divida al arreglo ordenado en partes IF n<=5
“suficientemente” parejas. p ::= MedAdhoc5(A[1..n]) a 1
ELSE
I Ejercicio: Sea TS (n) el tiempo del algoritmo de SELECCIÓN.
z ::= piso(n/5) b 1
Supongamos que seleccionar el pivote lleva tiempo TS (n/b),
array Medianos[1..z]
para algún b natural, b ≤ 9. ¿cuán “suficientemente” buena, en
FOR i ::= 1 TO z
función de b, tendría que ser la división del arreglo? (Ayuda: usar
Medianos[i] ::=
las propiedades de las recurrencias.)
MedAdhoc5(A[5i-4..5i]) c bn/5c
I el siguiente algoritmo encuentra una aproximación al mediano ENDFOR
con tiempo de ejecución en Θ(TS (bn/5c) + bn/5c). p ::= Selección(Medianos[1..z],
techo(z/2)) TS (bn/5c) 1
ENDIF; RETURN p
Algoritmos y Complejidad Algoritmos y Complejidad
Elemento mediano Elemento mediano
Selección Selección
Costo
function Selección(A[i..j],s)
I donde MedAdhoc5() es un algoritmo para encontrar el p ::= PseudoMediano(A[i..j]) Θ(n) + tS (bn/5c)
mediano de a los sumo 5 elementos PivotearBH(p,A[i..j],k,l) Θ(n)
I y por lo tanto es de tiempo Θ(1). CASE
I el tiempo de ejecución de Pseudomediano() es s<=k: r::=Selección(A[i..k],s) TS (k − i + 1)
Θ(n) + TS (bn/5c), donde TS () es el tiempo de ejecución del k<s<l: r::=p Θ(1)
algoritmo para resolver el problema SELECCIÓN s>=l: s::=s-l+1 Θ(1)
r::=Selección(A[l..j],s) TS ( j − l + 1)
ENDCASE
RETURN r Θ(1)
Lema 3
La posición r del resultado del algoritmo Pseudomediano()
3 7
cuando A tiene n elementos es tal que 10 n − 4 ≤ r ≤ 10 n + 56 .
Prueba.
La mínima cantidad de elementos menores o iguales es
3
3d z2 e ≥ 10 n − 65 . Luego la máxima cantidad de elementos mayores es
3
menor que n − ( 10 n − 65 ) = 10
7
n + 65 . Por otro lado, la máxima
candidad de elementos menores es a lo sumo
2z + 3b z2 c + 4 ≤ 10 7
n + 4.
Quicksort revisado
costo
Quicksort(A[i..j])
IF j-i es pequeño Θ(1)
Inserción(A[i..j]) Θ(1)
I usando entonces este algoritmo para calcular el mediano, y el
ELSE
pivoteo de la bandera holandesa se puede obtener la siguiente
piv ::= Mediano(A[i..j]) Θ(n)
versión de quicksort
PivotearBH(A[i..j],piv,k,l) Θ(n)
Quicksort(A[i..k]) T (n/2) peor caso
Quicksort(A[l..j]) T (n/2) peor caso
ENDIF
MULTIPLICACIÓN DE MATRICES
I el tiempo de ejecución es
I se tiene el problema de calcular el producto C de dos matrices
Θ(1) si n es pequeño A, B cuadradas de dimensión n
T (n) =
2T (n/2) + Θ(n) sino I el algoritmo directo tiene tiempo de ejecución en Θ(n3 ), ya que
cada uno de los n2 elementos de C lleva tiempo Θ(n) en
I usando el teorema maestro, T (n) ∈ Θ(n log n).
computarse
I ¿qué pasa si esta versión de quicksort en lugar de llamar a I si existiera un algoritmo dividir y conquistar que partiera las
Mediano(), busca el pivote con PseudoMediano()? matrices originales en matrices de n/2 × n/2, 8 o más
(ejercicio)
multiplicaciones de estas matrices igualaría o empeoraría el
tiempo del algoritmo directo (ejercicio).
Algoritmos y Complejidad Algoritmos y Complejidad
Multiplicación de matrices Multiplicación de matrices
Algoritmo de Strassen
n
I si se definen las siguientes matrices auxiliares, también de 2
× n2
I sea un conjunto de n
I para las matrices cuyos n no son potencia de 2, es necesario puntos en el plano (que
completarlas con 0’s hasta llegar a una potencia de 2 supondremos en el primer
I otros algoritmos similares se han definido siguiendo esta cuadrante). Problema: se
estrategia; se divide a la matriz en b × b partes, y se busca una quiere encontrar el par de
forma de calcular el producto con k componentes generados a puntos más cercanos.
partir de operaciones escalares en las partes tal que el algoritmo
I
directo
debe
logb k < log2 7. n
comparar pares de
2
puntos, por lo que su
tiempo está en Θ(n2 ).
costo
I si existe en Franja una function MasCercanos(P[1..n])
distancia d3 < d entonces IF n es pequeño Θ(1)
ésa es la solución. En caso RETURN algoritmoBasico(P) Θ(1)
contrario la solución es d ELSE
I para que el algoritmo DYC m ::= punto medio de coord. x Θ(1)
sea más eficiente que el crear P1 y P2 ??
algoritmo directo, debe d1 ::= MásCercanos(P1) T (bn/2c)
tenerse cuidado que la d2 ::= MásCercanos(P2) T (dn/2e)
sobrecarga de la partición d ::= min(d1, d2) Θ(1)
y combinación sean de crear Franja con ancho 2d de m ??
tiempo menor que Θ(n2 ) d3 ::= recorrido(Franja) ??
RETURN min(d,d3)
ENDIF
Criptografía
2
I se puede mejorar el tiempo de Θ(n log n) a costa de incorporar
Esquema para protocolos de Clave Secreta
como entrada al algoritmo no solo P ordenado por coordenadas
x, sino también ordenado por coordenas y .
I de esta forma se elimina el ordenamiento en cada llamada
recursiva, realizándose solamente un única vez al comienzo del
algoritmo, y la creación de Franja se puede hacer entonces en
tiempo lineal
I el problema ahora es crear los nuevos arreglos ordenados por y
para cada llamada recursiva; pero esto puede hacerse en tiempo
lineal a partir del arreglo completo ordenado por y
I la recurrencia queda entonces T (n) = 2T (n/2) + Θ(n) que
sabemos que está en Θ(n log n)
Protocolo RSA
I B (el receptor del mensaje) elige dos números primos p y q I B también debe elegir un número n aleatorio, tal que
(cuanto más grandes, más difícil de quebrar el cifrado) y calcula 1 < n < z − 1, que no tenga factores comunes con (p − 1)(q − 1)
z = pq I existe un algoritmo eficiente (basado en el algoritmo de Euclides)
I existen algoritmos eficientes para testear si un número es primo que dado cualquier n, no sólo comprueba si cumple con la
(se verá más adelante un algoritmo probabilístico) y para propiedad sino que al mismo tiemo calcula el único s tal que
multiplicar enteros grandes (ya visto) 1 ≤ s ≤ z − 1 y ns mod (p − 1)(q − 1) = 1
I sin embargo, no se conocen algoritmos eficientes para factorear
z.
Exponenciación modular
Esquema de un protocolo de Clave Pública
Transformada de Fourier
costo
Recursiv-Transf(A,X)
Θ(1)
I el tiempo de ejecución es, si |A| = n y |X | = m,
IF (A.length=1) RETURN A
X^2 ::= {X[i]*X[i], 0<= i<= m-1} Θ(m)
Θ(1) si n = 1
Apar ::= {A[0], A[2],..., A[n-2]} Θ(n) TRT (n, m) =
2TRT (n/2, m) + Θ(n + m) si n > 1
Aimpar ::= {A[1],A[2],...,A[n-1]} Θ(n)
Ypar ::= Recursiv_Transf( Apar,X^2) I por inducción constructiva TRT (n, m) ∈ O (nm)
Yimpar ::= Recursiv_Transf(Aimpar,X^2) I como n = m al inicio, entonces es O (n2 ), no es suficiente
Y ::= {Ypar[i]+
X[i]*Yimpar[i], 0<= i <= m-1} Θ(m)
RETURN Y
Lema 9
∑nj =−01 (ωkn )j = 0 para n ≥ 1, k 6= 0 y k no divisible por n
I las demostraciones quedan como ejercicios
I las raíces enésimas de la unidad forman un grupo (asociativa,
elemento neutro y elemento simétrico) con la multiplicación, con
propiedades similares a (Z, +mod n )