Você está na página 1de 36

Algortmica y Complejidad

Tema 5 Divide y Vencers.


D DD Departamento
I II Informtica
A AA Aplicada
Divide y vencers.
1. Mtodo.
2. Un ejemplo sencillo.
3. Complejidad del mtodo.
4. Ejemplo: El mximo subarray.
2
Divide y vencers.
1. Mtodo.
2. Un ejemplo sencillo.
3. Complejidad del mtodo.
4. Ejemplo: El mximo subarray.
3
Mtodo.
4
Divide y vencers.
Dividir.
El problema se divide en varios problemas
similares de menor tamao.
Resolver.
Si los subproblemas son asumibles se resuelven.
En caso contrario se vuelve a aplicar el mtodo.
Combinar.
Se combinan las soluciones de los subproblemas
para obtener la solucin total.
Esquema de
tres etapas!
5
Divide y vencers.
Caractersticas que deben cumplir los problemas para que
se pueda aplicar esta tcnica:
El problema se debe poder descomponer en otros
similares pero ms pequeos.
Los nuevos problemas deben ser disjuntos.
Debe ser posible combinar las soluciones
individuales para obtener la global.
Mtodo.
6
Divide y vencers.
procedure Divide_y_Vencers (P : problema) is
begin
if P es simple then
Solucionar P;
else
Descomponer P en {P1, P2, ..., Pn};
Divide_y_Vencers (P1);
Divide_y_Vencers (P2);
. . . . . . . . . . . . . . . . . . .
Divide_y_Vencers (Pn);
Combinar las soluciones de {P1, P2, ..., Pn};
end if;
end Divide_y_Vencers;
Mtodo.
7
Divide y vencers.
Mtodo.
Hasta donde conviene subdividir el problema?
Existir un umbral n
0
a partir
del cul es ms rpido aplicar
el algoritmo inmediato.
El clculo de n
0
no es trivial y depende de la implementacin.
Es habitual utilizar mtodos empricos para su determinacin.
Algoritmo
Imnediato
n
0
n
T (n)
Algoritmo
Div. y Venc.
Divide y vencers.
1. Mtodo.
2. Un ejemplo sencillo.
3. Complejidad del mtodo.
4. Ejemplo: El mximo subarray.
8
Un ejemplo sencillo.
9
Divide y vencers.
Problema:
-23
1
14
2
31
3
-3
4
13
n-1
-2
n
. . . .
A :
function Maximo (i, j : integer) return integer is
max : integer := integer'first;
begin
for k in i .. j loop
if A(k) > max then
max := A(k);
end if;
end loop;
return max;
end Maximo;
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _
put ("Valor maximo:"); put (Maximo(A'first, A'last));
La solucin inmediata sera:
Encontrar el valor
mximo en un array
de nmeros enteros."
Un ejemplo sencillo.
10
Divide y vencers.
Enfoque "divide y vencers":
1. Dividir el array en dos partes.
2. Hallar el mximo de cada parte.
3. Seleccionar el mayor de los dos.
Se sigue aplicando
de forma recursiva.
Un ejemplo sencillo.
11
Divide y vencers.
function Maximo (i, j : integer) return integer is
med, max_i, max_d : integer;
begin
end Maximo;
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _
put ("Valor maximo:"); put (Maximo(A'first, A'last));
Un ejemplo sencillo.
12
Divide y vencers.
function Maximo (i, j : integer) return integer is
med, max_i, max_d : integer;
begin
if i=j then
return A(i);
else
end if;
end Maximo;
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _
put ("Valor maximo:"); put (Maximo(A'first, A'last));
Un ejemplo sencillo.
13
Divide y vencers.
function Maximo (i, j : integer) return integer is
med, max_i, max_d : integer;
begin
if i=j then
return A(i);
else
med := (i + j) / 2;
max_i := Maximo (i, med);
max_d := Maximo (med+1, j);
end if;
end Maximo;
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _
put ("Valor maximo:"); put (Maximo(A'first, A'last));
Un ejemplo sencillo.
14
Divide y vencers.
function Maximo (i, j : integer) return integer is
med, max_i, max_d : integer;
begin
if i=j then
return A(i);
else
med := (i + j) / 2;
max_i := Maximo (i, med);
max_d := Maximo (med+1, j);
if max_i > max_d then
return max_i;
else
return max_d;
end if;
end if;
end Maximo;
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _
put ("Valor maximo:"); put (Maximo(A'first, A'last));
Divide y vencers.
1. Mtodo.
2. Un ejemplo sencillo.
3. Complejidad del mtodo.
4. Ejemplo: El mximo subarray.
15
Complejidad del mtodo.
16
Divide y vencers.
Problema
Problema
1
Problema
2
Problema
3
Problema
a
Problema
a-1
. . .
T(n/b) + T(n/b ) + T(n/b) + . . . + T(n/b) + T(n/b)
a T ( n / b )
T(n)
Descomposicin del problema
y
combinacin de las soluciones
O ( n
k
)
Complejidad del mtodo.
17
Divide y vencers.
En general responder a esta ecuacin:
a 1, b 2, k 0
T ( n ) = a T ( n / b ) + O ( n
k
)
a : Nmero de subproblemas
en que se descompone.
n/b : Tamao de cada nuevo
subproblema.
T ( n ) =
O ( n
k
), a < b
k
O ( n
k
log n ), a = b
k
O ( n
log
b
a
), a > b
k
Cuya solucin es:
Complejidad del mtodo.
18
Divide y vencers.
function Maximo (i, j : integer) return integer is
med, max_i, max_d : integer;
begin
if i=j then
return A(i);
else
med := (i + j) / 2;
max_i := Maximo (i, med);
max_d := Maximo (med+1, j);
if max_i > max_d then
return max_i;
else
return max_d;
end if;
end if;
end Maximo;
O ( 1 )
O ( 1 )
Complejidad del ejemplo sencillo: (Enfoque Divide y Vencers)
Complejidad del mtodo.
19
Divide y vencers.
function Maximo (i, j : integer) return integer is
med, max_i, max_d : integer;
begin
if i=j then
return A(i);
else
med := (i + j) / 2;
max_i := Maximo (i, med);
max_d := Maximo (med+1, j);
if max_i > max_d then
return max_i;
else
return max_d;
end if;
end if;
end Maximo;
T ( n / 2 )
T ( n / 2 )
Complejidad del ejemplo sencillo: (Enfoque Divide y Vencers)
Complejidad del mtodo.
20
Divide y vencers.
T ( n ) = 2 T ( n / 2 ) + O ( 1 )
a = 2
b = 2
k = 0
a > b
k
2 > 2
0
2 > 1
Complejidad del ejemplo sencillo: (Enfoque Divide y Vencers)
T ( n ) = a T ( n / b ) + O ( n
k
)
O ( n
log
b
a
) = O ( n
log
2
2
) = O ( n )
Complejidad del mtodo.
21
Divide y vencers.
function Maximo (i, j : integer) return integer is
max : integer := integer'first;
begin
for k in i .. j loop
if A(k) > max then
max := A(k);
end if;
end loop;
return max;
end Maximo;
Complejidad del ejemplo sencillo: (Enfoque Inmediato)
O ( n )
Ambos mtodos tienen la misma complejidad.
Divide y Vencers es ms lento por la recursividad.
En este caso es mejor el Enfoque Inmediato.
Divide y vencers.
1. Mtodo.
2. Un ejemplo sencillo.
3. Complejidad del mtodo.
4. Ejemplo: El mximo subarray.
22
Ejemplo: El mximo subarray.
23
Divide y vencers.
"Dados varios nmeros que supondremos almacenados en un array, se trata
de encontrar la secuencia de nmeros contiguos cuya suma sea mxima."
Problema:
12
1
2
2
-3
3
-4
4
-9
5
8
6
A : 12
7
5
8
-6
9
1
10
8
6
12
7
5
8
La solucin sera: cuya suma es 25.
Por ejemplo, dado:
Si existe ms de una solucin, nos conformaremos
con hallar una de ellas.
Ejemplo: El mximo subarray.
24
Divide y vencers.
-3
3
-4
4
-9
5
8
6
12
7
5
8
-6
9
1
10
12
1
2
2
-3
3
-4
4
-9
5
8
6
12
7
5
8
-6
9
1
10
12
1
2
2
-3
3
-4
4
-9
5
8
6
12
7
5
8
-6
9
1
10
12
1
2
2
-3
3
-4
4
-9
5
8
6
12
7
5
8
-6
9
1
10
12
1
2
2
-3
3
-4
4
-9
5
8
6
12
7
5
8
-6
9
1
10
12
1
2
2
-3
3
-4
4
-9
5
8
6
12
7
5
8
-6
9
1
10
12
1
2
2
-3
3
-4
4
-9
5
8
6
12
7
5
8
-6
9
1
10
12
1
2
2
-3
3
-4
4
-9
5
8
6
12
7
5
8
-6
9
1
10
12
1
2
2
-3
3
-4
4
-9
5
8
6
12
7
5
8
-6
9
1
10
12
1
2
2
-3
3
-4
4
-9
5
8
6
12
7
5
8
-6
9
1
10
12
1
2
2
-3
3
-4
4
-9
5
8
6
12
7
5
8
-6
9
1
10
12
1
2
2
-3
3
-4
4
-9
5
8
6
12
7
5
8
-6
9
1
10
12
1
2
2
Una solucin inmediata:
Ejemplo: El mximo subarray.
25
Divide y vencers.
procedure Maximo_Subarray is
. . . . . . . . . . . . . .
begin
max := integer'first;
for i in A'range loop
suma := 0;
for j in i .. A'last loop
suma := suma + A(j);
if suma > max then
max := suma;
inf := i;
sup := j;
end if;
end loop;
end loop;
put ("Indice inferior: "); put (inf); new_line;
put ("Indice superior: "); put (sup); new_line;
put ("Valor de la suma : "); put (max); new_line;
end Maximo_Subarray;
O ( n
2
)
Ejemplo: El mximo subarray.
Divide y vencers.
Enfoque "divide y vencers":
Se divide el array en dos partes.
3 4 5 6 7 8 9 10 1 2
Pueden darse tres casos:
3 4 5 6 7 8 9 10 1 2
El subarray est totalmente
en la parte izquierda.
3 4 5 6 7 8 9 10 1 2
El subarray est totalmente
en la parte derecha.
3 4 5 6 7 8 9 10 1 2
El subarray
atraviesa la divisin.
Ejemplo: El mximo subarray.
Divide y vencers.
Si el subarray est completamente en uno de los lados, se puede resolver de
forma recursiva, finalizando cuando el tamao sea de un slo elemento.
-3
3
-4
4
-9
5
8
6
12
7
5
8
-6
9
1
10
12
1
2
2
-3
3
-4
4
-9
5
8
6
12
7
5
8
-6
9
1
10
12
1
2
2
-3
3
-4
4
-9
5
8
6
12
7
5
8
-6
9
1
10
12
1
2
2
-3
3
-4
4
-9
5
8
6
12
7
5
8
-6
9
1
10
12
1
2
2
-3
3
-4
4
-9
5
8
6
12
7
5
8
-6
9
1
10
12
1
2
2
-3
3
-4
4
-9
5
8
6
12
7
5
8
-6
9
1
10
12
1
2
2
-3
3
-4
4
-9
5
8
6
12
7
5
8
-6
9
1
10
12
1
2
2
-3
3
-4
4
-9
5
8
6
12
7
5
8
-6
9
1
10
12
1
2
2
-3
3
-4
4
-9
5
8
6
12
7
5
8
-6
9
1
10
12
1
2
2
-3
3
-4
4
-9
5
8
6
12
7
5
8
-6
9
1
10
12
1
2
2
El mximo subarray estar formado por la unin del de mayor suma en el
lado izquierdo y el de mayor suma del lado derecho.
En el otro caso, el subarray tendr una parte en el lado izquierdo y otra en el
derecho. Las partes se correspondern con uno de estos casos:
Ejemplo: El mximo subarray.
Divide y vencers.
procedure Maximo_Subarray (E_inf, E_sup : in natural;
S_inf, S_sup : out natural;
S_suma : out integer) is
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
begin
end Maximo_Subarray;
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _
Maximo_Subarray (A'first, A'last, inf, sup, max);
Ejemplo: El mximo subarray.
Divide y vencers.
procedure Maximo_Subarray (E_inf, E_sup : in natural;
S_inf, S_sup : out natural;
S_suma : out integer) is
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
begin
if E_inf = E_sup then
S_suma := A(E_inf); S_inf := E_inf; S_sup := S_inf;
else
end if;
end Maximo_Subarray;
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _
Maximo_Subarray (A'first, A'last, inf, sup, max);
O ( 1 )
Ejemplo: El mximo subarray.
Divide y vencers.
procedure Maximo_Subarray (E_inf, E_sup : in natural;
S_inf, S_sup : out natural;
S_suma : out integer) is
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
begin
if E_inf = E_sup then
S_suma := A(E_inf); S_inf := E_inf; S_sup := S_inf;
else
med := (E_inf + E_sup) / 2;
Maximo_Subarray (E_inf, med, inf_i, sup_i, max_i);
Maximo_Subarray (med + 1, E_sup,inf_d, sup_d, max_d);
Subarray_Comun (E_inf, med, E_sup, inf_c, sup_c, max_c);
end if;
end Maximo_Subarray;
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _
Maximo_Subarray (A'first, A'last, inf, sup, max);
T ( n / 2 )
T ( n / 2 )
?
O ( 1 )
O ( 1 )
Ejemplo: El mximo subarray.
Divide y vencers.
procedure Maximo_Subarray (E_inf, E_sup : in natural;
S_inf, S_sup : out natural;
S_suma : out integer) is
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
begin
if E_inf = E_sup then
S_suma := A(E_inf); S_inf := E_inf; S_sup := S_inf;
else
med := (E_inf + E_sup) / 2;
Maximo_Subarray (E_inf, med, inf_i, sup_i, max_i);
Maximo_Subarray (med + 1, E_sup,inf_d, sup_d, max_d);
Subarray_Comun (E_inf, med, E_sup, inf_c, sup_c, max_c);
if max_i > max_d and max_i > max_c then
S_suma := max_i; S_inf := inf_i; S_sup := sup_i;
elsif max_d > max_i and max_d > max_c then
S_suma := max_d; S_inf := inf_d; S_sup := sup_d;
else
S_suma := max_c; S_inf := inf_c; S_sup := sup_c;
end if;
end if;
end Maximo_Subarray;
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _
Maximo_Subarray (A'first, A'last, inf, sup, max);
O ( 1 )
T ( n / 2 )
T ( n / 2 )
?
O ( 1 )
O ( 1 )
Ejemplo: El mximo subarray.
Divide y vencers.
procedure Subarray_Comun (E_inf, med, E_sup : in natural;
S_inf, S_sup : out natural;
S_suma : out integer) is
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
begin
end Subarray_Comun;
Ejemplo: El mximo subarray.
Divide y vencers.
procedure Subarray_Comun (E_inf, med, E_sup : in natural;
S_inf, S_sup : out natural;
S_suma : out integer) is
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
begin
suma_izq := integer'first;
suma_tmp := 0;
for i in reverse E_inf .. med loop
suma_tmp := suma_tmp + A(i);
if suma_tmp > suma_izq then
suma_izq := suma_tmp;
S_inf := i;
end if;
end loop;
end Subarray_Comun;
O ( n )
Ejemplo: El mximo subarray.
Divide y vencers.
procedure Subarray_Comun (E_inf, med, E_sup : in natural;
S_inf, S_sup : out natural;
S_suma : out integer) is
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
begin
suma_izq := integer'first;
suma_tmp := 0;
for i in reverse E_inf .. med loop
suma_tmp := suma_tmp + A(i);
if suma_tmp > suma_izq then
suma_izq := suma_tmp;
S_inf := i;
end if;
end loop;
suma_der := integer'first;
suma_tmp := 0;
for i in med+1 .. E_sup loop
suma_tmp := suma_tmp + A(i);
if suma_tmp > suma_der then
suma_der := suma_tmp;
S_sup := i;
end if;
end loop;
end Subarray_Comun;
O ( n )
O ( n )
Ejemplo: El mximo subarray.
Divide y vencers.
procedure Subarray_Comun (E_inf, med, E_sup : in natural;
S_inf, S_sup : out natural;
S_suma : out integer) is
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
begin
suma_izq := integer'first;
suma_tmp := 0;
for i in reverse E_inf .. med loop
suma_tmp := suma_tmp + A(i);
if suma_tmp > suma_izq then
suma_izq := suma_tmp;
S_inf := i;
end if;
end loop;
suma_der := integer'first;
suma_tmp := 0;
for i in med+1 .. E_sup loop
suma_tmp := suma_tmp + A(i);
if suma_tmp > suma_der then
suma_der := suma_tmp;
S_sup := i;
end if;
end loop;
S_suma := suma_izq + suma_der;
end Subarray_Comun;
O ( 1 )
O ( n )
O ( n )
Ejemplo: El mximo subarray.
Divide y vencers.
T ( n ) = 2 T ( n / 2 ) + O ( n )
Complejidad del enfoque Divide y Vencers:
a = 2
b = 2
k = 1
T ( n ) = a T ( n / b ) + O ( n
k
)
O ( n
1
log n ) = O ( n log n )
T ( n ) = O (1) + O (1) + T (n / 2) + T (n / 2) + O ( ? ) + O (1)
O (n) + O (n) + O (1)
n
T (n)
n
2
n log n

Você também pode gostar