Académique Documents
Professionnel Documents
Culture Documents
Tcnica de diseo:
Descomponer el caso a resolver en un nmero de subcasos ms
pequeos del mismo problema.
Resolver independientemente cada subcaso.
Combinar los resultados para construir la solucin del caso
original.
Este proceso se debe aplicar recursivamente.
Divide y Vencers
Esquema genrico
funcin divide_y_vencers (c: tipocaso) : tiposolucin;
var x1, ..., xk : tipocaso; y1, ...,yk: tiposolucin;
si c es suficientemente simple entonces
devolver solucin_simple(c)
sino descomponer c en x1, ..., xk
para i 1 hasta k hacer
yi divide_y_vencers (xi)
fpara
devolver combinar_solucion_subcasos(y1, ..., yk)
fsi
ffuncin
Programacin III
Divide y Vencers
El nmero de subejemplares, k, suele ser pequeo e
independiente de del caso particular a resolver.
Cuando k = 1, el esquema divide_y_vencers pasa a
llamarse reduccin ( simplificacin). En estos casos se
trata de reducir la solucin de un caso muy grande a la de
uno ms pequeo.
Algunos algoritmos de divide_y_vencers pueden
necesitar que el primer subejemplar est resuelto antes de
formular el segundo subejemplar.
Programacin III
Divide y Vencers
Para que el enfoque divide_y_vencers merezca la pena,
se deben cumplir las siguientes condiciones:
Debe ser posible descomponer el caso a resolver en
subcasos.
Se debe poder componer la solucin a partir de las
soluciones de los subcasos de un modo eficiente.
Los subejemplares deben ser, en la medida de lo
posible, aproximadamente del mismo tamao.
Programacin III
Divide y Vencers
Clculo de la complejidad para el caso general
Sea n el tamao de nuestro caso original.
Y sea k el nmero de subcasos.
Supongamos que existe una constante b t.q. el tamao de los k
subcasos es aprox. n/b .
Si g(n) es el tiempo requerido por el algoritmo divide_y_vencers
en casos de tamao n, sin contar el tiempo necesario para realizar las
llamadas recursivas
t(n) = k*t(n b) + g(n)
Donde t(n) es el tiempo total requerido por el algoritmo
divide_y_vencers, siempre que n sea lo suficientemente grande.
Programacin III
Divide y Vencers
Si existe un entero p t.q. g(n) (np), entonces podemos concluir
que:
T(n)
(np)
si k < bp
(np log n)
si k = bp
(nlogbk)
si k > bp
Programacin III
Divide y Vencers
Falta por ver cundo se deja de dividir el caso en subcasos y se
resuelve con un algoritmo bsico, es decir, cmo se determina el
umbral.
El umbral ser un n0 t.q. cuando el tamao del caso a tratar sea
menor o igual, se resuelva con un algoritmo bsico, es decir, no se
generen ms llamadas recursivas.
La determinacin del umbral ptimo, es un problema complejo. Para
un mismo problema puede variar con la implementacin concreta o
con el tamao de n.
Dada una implementacin particular, puede calcularse
empricamente. Este sistema puede requerir unas cantidades notables
de tiempo de computadora y humano.
Programacin III
Divide y Vencers
Tambin puede emplearse una tcnica hbrida para su
clculo:
Primero se deben obtener las ecuaciones de
recurrencia de nuestro algoritmo (estudio terico).
Determinar empricamente los valores de las
constantes que se utilizan en dichas ecuaciones para la
implementacin concreta que estamos empleando.
El umbral ptimo se estima hallando el tamao n del
caso para el cual no hay diferencia entre aplicar
directamente el algoritmo clsico o pasar a un nivel ms
de recursin.
Programacin III
x = 12
2
-2
3
0
4
3
5
8
6
8
7
9
8 9 10
12 12 26
k
i
i
ik
k
k j
j
ij
11
31
T[k] x ?
j
j
no
s
s
no
i = j alto
Programacin III
Programacin III
si
l < bk
si
l = bk
si
l > bk
PROBLEMA: Ordenacin
Sea T[1..n] una matriz de n elementos. Nuestro problema
es ordenar estos elementos por orden ascendente.
Nosotros conocemos varios mtodos de ordenacin: por
seleccin, por insercin y por montculo. ste ltimo
mtodo tiene un orden de tiempo de ( n log n).
Hay varios algoritmos clsicos de ordenacin que siguen el
esquema de divide y vencers. Nosotros vamos a estudiar
dos de ellos. Ordenar por fusin (mergesort) y ordenacin
rpida (quicksort)
Programacin III
Programacin III
10
Programacin III
k=1
(nk)
si
l < bk
(nk log n)
si
l = bk
(n log b l)
si
l > bk
Combinamos 2 soluciones: l = 2
En cada paso dividimos el tamao del problema a la mitad b = 2
l = bk { 2 = 21}, t(n) (nk log n) t(n) (n log n)
(Est despreciando el tiempo requerido por insertar() ya que es con un n
suficientemente pequeo)
Programacin III
11
Ordenacin rpida
El primer paso es escoger un elemento de la matriz a
ordenar como pivote.
A continuacin la matriz se parte a ambos lados del
pivote. Los elementos mayores que el pivote se
almacenan a la derecha del mismo y los dems a la
izquierda.
La matriz se ordena mediante llamadas recursivas a
este algoritmo.
Programacin III
Ordenacin rpida
Uso del algoritmo
Se suele seleccionar como pivote el elemento que ocupa la
posicin central del vector o subvector a ordenar ya que:
Si todos los elementos tienen igual probabilidad, ese es tan
bueno como cualquier otro
Programacin III
12
Ordenacin rpida
procedimiento pivote (T[i..j]; var l)
{Permuta los elementos de la matriz T[i..j] y proporciona un valor l tal que, al final, i <= l <= j; T[k] <= p
para todo i <= k < l, T[l] = p, y T[k] > p para todo l< k <= j, en donde p es el valor inicial de T[i]}
p T[i]
k i; l j + 1
repetir
kk+1
hasta que T[k] > p o k >= j frepetir
repetir
ll1
hasta que T[l] <= p frepetir
mientras k < l hacer
intercambiar T[k] y T[l]
repetir
kk+1
hasta que T[k] > p frepetir
repetir
ll1
hasta que T[l] <= p frepetir
fmientras
intercambiar T[i] y T[l]
fprocedimiento
Programacin III
Ordenacin rpida
procedimiento ordenacion_rapida(T[i..j])
{Ordena la submatriz T[i..j] por orden no decreciente}
si j i es suficientemente pequeo entonces insertar (T[i..j])
sino
pivote(T[i..j],l);
ordenacion_rapida (T[i..l-1])
ordenacin_rapida (T[l+1..j])
fsi
fprocedimiento
Programacin III
13
Ordenacin rpida
Coste de ordenacin rpida
1. Si suponemos que:
el orden inicial del vector es aleatorio
los elementos de T son diferentes en su mayora
todas las n! permutaciones de sus elementos son
igualmente probables
los subproblemas estaran equilibrados
El orden sera: O(n log n)
2. Si los subproblemas no estn del todo equilibrados se suele
asumir que el coste es O(n log n)
Programacin III
Ordenacin rpida
Coste de ordenacin rpida
3. Los casos peores:
el vector est inicialmente ordenado
todos los elementos son iguales
14
Ordenacin rpida
Coste de ordenacin rpida
Si partimos de la hiptesis de que:
todos los elementos de T son diferentes
cada una de las n! permutaciones tienen la misma probabilidad
t(m) tiempo medio de ordenacion_rapida(T[i..j])
m = j - i + 1 {n de elementos en T[i..j]}
El valor l devuelto por pivote(T[1..n]) ser un entero entre 1 y n
con probabilidad 1/n
Programacin III
Ordenacin rpida
Coste de ordenacin rpida
El tiempo ser por tanto:
t(n) (n) + 1/n (t(l-1) + t(n-l)) (1)
sabemos que: g(n) dn
sabemos que hay un valor k tal que 0 k n -1 que aparece 2 veces
en (1):
t(n) dn + 2/n t(k)
para n suficientemente grande
No se pueden aplicar las recurrencias lineales vistas
anteriormente
Por analoga con otros mtodos de ordenacin es razonable
esperar que : t(n) = O(n log n)
Programacin III
15