PDF de programación - Tema 3.2: Eficiencia de algoritmos recursivos

Imágen de pdf Tema 3.2: Eficiencia de algoritmos recursivos

Tema 3.2: Eficiencia de algoritmos recursivosgráfica de visualizaciones

Publicado el 11 de Enero del 2019
46 visualizaciones desde el 11 de Enero del 2019
459,1 KB
37 paginas
Creado hace 2a (17/01/2017)
Tema 3.2: Eficiencia de algoritmos recursivos

Diseño y Análisis de Algoritmos

Tema 3.2: Eficiencia de algoritmos recursivos

Contenidos

Contenidos

1

Introducción

2 Expansión de recurrencias

3 Método general para resolución de relaciones de recurrencia

URJC

DAA

2 / 37

Tema 3.2: Eficiencia de algoritmos recursivos

Introducción

Análisis de algoritmos recursivos

La matemática necesaria para analizar algoritmos recursivos son las
relaciones de recurrencia, también llamadas ecuaciones en
diferencias o simplemente recurrencias

Las recurrencias son expresiones matemáticas recursivas

3

T (n) =

5 + T (n − 1)

si n = 0
si n > 0

La resolución de recurrencias consiste en proporcionar fórmulas no
recursivas equivalentes

T (n) = 5n + 3

Veremos dos formas de resolverlas:

Expansión de recurrencias
Resolución de relaciones de recurrencia

URJC

DAA

3 / 37

Tema 3.2: Eficiencia de algoritmos recursivos

Expansión de recurrencias

Función potencia - versión 1

if(e==0)

1 int pot1(int b, int e)
2 {
3
4
5
6
7 }

return 1;

else

return b*pot1(b,e-1);

3

T (n) =

5 + T (n − 1)

si n = 0
si n > 0

n está relacionado con el tamaño del problema, que en este caso es el
exponente e de la función

Podemos pensar en el caso base se realizan 3 operaciones, y 5 en el
recursivo (además del tiempo que llevaría realizar otra llamada con
parámetro n − 1)

URJC

DAA

4 / 37

Tema 3.2: Eficiencia de algoritmos recursivos

Expansión de recurrencias

Resolución por expansión de recurrencias

T (n) = 5 + T (n − 1)

= 5 + 5 + T (n − 2) = 5 · 2 + T (n − 2)
= 5 + 5 + 5 + T (n − 3) = 5 · 3 + T (n − 3)
...
= 5i + T (n − i)

¿Cuándo se llega al caso base T (0)?

Cuando i = n

Sustituyendo:

T (n) = 5n + T (0) = 5n + 3 ∈ Θ(n)

Tiene sentido, ya que decrementamos n en cada llamada recursiva

URJC

DAA

5 / 37

Tema 3.2: Eficiencia de algoritmos recursivos

Expansión de recurrencias

Función potencia - versión 2

if(e==0)

return 1;

1 int pot2(int b, int e)
2 {
3
4
5
6
7
8
9 }

else if (e%2==0)

else

return pot2(b*b,e/2);

return b*pot2(b*b,e/2);

 3

T (n) =

8 + T (n/2)
9 + T ((n − 1)/2)

si n = 0
si n > 0 y n es par
si n > 0 y n es impar

La función es difícil de analizar
Pero podemos suponer que n = 2x es una potencia de dos
Esto es válido ya que estamos analizando complejidad asintótica

URJC

DAA

6 / 37

Tema 3.2: Eficiencia de algoritmos recursivos

Expansión de recurrencias

Resolución por expansión de recurrencias

Asumimos que n = 2x es una potencia de dos (por tanto, par):

T (n) = 8 + T (n/2)

= 8 + 8 + T (n/4) = 8 · 2 + T (n/22)
= 8 + 8 + 8 + T (n/8) = 8 · 3 + T (n/23)
...
= 8i + T (n/2i )

¿Cuándo se llega al caso base T (0)?

i → ∞
Pero eso no tiene sentido
El parámetro de la función T es entero

URJC

DAA

7 / 37

Tema 3.2: Eficiencia de algoritmos recursivos

Expansión de recurrencias

Resolución por expansión de recurrencias

¿Cuándo se llega al caso T (1)?

Cuando n/2i = 1, es decir, cuando i = log2 n

Sustituyendo:

T (n) = 8 log2 n + T (1) = 8 log2 n + 9 + T (0) = 8 log2 n + 9 + 3 =

= 8 log2 n + 12 ∈ Θ(log n)

Tiene sentido, ya que dividimos n por 2 en cada llamada recursiva

URJC

DAA

8 / 37

Tema 3.2: Eficiencia de algoritmos recursivos

Expansión de recurrencias

Soluciones generales a relaciones de recurrencia

a

T (n) =

b + T (n − 1)

si n = 0
si n > 0

T (n) = bn + a ∈ Θ(n)

a

T (n) =

b + T (n − 1)

si n = 1
si n > 1
T (n) = b(n − 1) + a ∈ Θ(n)

URJC

DAA

9 / 37

Tema 3.2: Eficiencia de algoritmos recursivos

Expansión de recurrencias

Soluciones generales a relaciones de recurrencia

a

T (n) =

si n = 1
si n > 1
T (n) = b log2 n + a ∈ Θ(log n)

b + T (n/2)

a

b + T (n/2)

T (n) =

si n = 0
si n > 0

T (n) = b log2 n + b + a ∈ Θ(log n)

URJC

DAA

10 / 37

Tema 3.2: Eficiencia de algoritmos recursivos

Expansión de recurrencias

Soluciones generales a relaciones de recurrencia

a

T (n) =

bn + c + T (n − 1)

si n = 0
si n > 0

T (n) = bn + c + T (n − 1)

= bn + c + b(n − 1) + c + T (n − 2) = 2bn − b + 2c + T (n − 2)
= 2bn − b + 2c + b(n − 2) + c + T (n − 3) =
= 3bn − b(1 + 2) + 3c + T (n − 3) =
= 3bn − b(1 + 2) + 3c + b(n − 3) + c + T (n − 4) =
= 4bn − b(1 + 2 + 3) + 4c + T (n − 4) =
...
= ibn − b

j + ic + T (n − i) = ibn + ic − b

i(i − 1)

+ T (n − i)

2

i−1

j=1

URJC

DAA

11 / 37

Tema 3.2: Eficiencia de algoritmos recursivos

Expansión de recurrencias

Soluciones generales a relaciones de recurrencia

Se alcanza T (0) para i = n

Sustituyendo:

T (n) = bn2 − b
2

n(n − 1) + cn + a



T (n) =

b
2

n2 +

c +

b
2

n + a ∈ Θ(n2)

Tiene sentido, ya que hacemos n + (n − 1) + (n − 2) + ··· + 1
operaciones

URJC

DAA

12 / 37

Tema 3.2: Eficiencia de algoritmos recursivos

Expansión de recurrencias

Soluciones generales a relaciones de recurrencia

T (n) =

bn + c + 2T (n/2)

si n = 0
si n > 0

a



n
2

n
2

T (n) = bn + c + 2T (n/2)

= bn + c + 2

= bn + c + 2



b

+ c + 2T (n/4)



b

+ c + 2

b

n
4

+ c + 2T (n/8)

= 3bn + c(1 + 2 + 4) + 23T (n/23) = 3bn + c(23 − 1) + 23T (n/23)
...
= ibn + c(2i − 1) + 2i T (n/2i )

URJC

DAA

13 / 37

Tema 3.2: Eficiencia de algoritmos recursivos

Expansión de recurrencias

Soluciones generales a relaciones de recurrencia

Se alcanza T (1) para n/2i = 1, es decir, cuando i = log2 n

Sustituyendo:

T (n) = bn log2 n + c(n − 1) + nT (1)

= bn log2 n + c(n − 1) + n(b + c + 2T (0))

= bn log2 n + cn − c + nb + nc + 2na

T (n) = bn log2 n + (2c + b + 2a)n − c

∈ Θ(n log n)

URJC

DAA

14 / 37

Tema 3.2: Eficiencia de algoritmos recursivos

Expansión de recurrencias

Soluciones generales a relaciones de recurrencia

Tiene sentido, ya que hacemos n operaciones 1 + log2 n veces

URJC

DAA

15 / 37

nn/2n/2n/4n/4n/4n/41111111111111111n1 + log2 n Tema 3.2: Eficiencia de algoritmos recursivos

Expansión de recurrencias

Teorema maestro - versión simple

Fórmula útil para algoritmos “divide y vencerás”:

 c

T (n) =

aT (n/b) + cnk

si n = 1

si n > 1

=⇒

T (n) =



Θ(nk )

Θ(nk log n)

Θ(nlogb a)

si a

bk < 1

si a

bk = 1

si a

bk > 1

URJC

DAA

16 / 37

Tema 3.2: Eficiencia de algoritmos recursivos

Expansión de recurrencias

Teorema maestro - demostración

T (n) = aT (n/b) + cnk

= a

aT

+ c



b2


n
n


n

aT

b3

bi

= a2

...

= ai T

+ cnk = a2T

b

k
n
k
+ cnk n
n
a
j
i−1

b2

b2



n


b2

+ cnk
n


b3



1 +

a
bk



a
bk +

a2
b2k

+ c

= a3T

+ cnk

1 +

+ cnk

bk

j=0

Se alcanza T (1) = c cuando: i = logb n

= calogb n + cnk

logb n−1

a

j

bk

j=0

= cnk a

bk

logb n

logb n−1

a

j

bk

j=0

+ cnk

URJC

DAA

17 / 37

Tema 3.2: Eficiencia de algoritmos recursivos

Expansión de recurrencias

Teorema maestro - demostración (logaritmos)

La última igualdad se debe a:

logb n

cnk a

bk

= cnk alogb n

bk logb n = cnk alogb n

nk = calogb n

Más adelante también necesitaremos:

nlogba = alogbn

Ya que:

logb nlogba = logb alogbn = logb a · logb n

Finalmente:

logb n

a

j

bk

j=0

T (n) = cnk

Y tendremos 3 casos según los valores de a, b y k

URJC

DAA

18 / 37

Tema 3.2: Eficiencia de algoritmos recursivos

Expansión de recurrencias

Teorema maestro - demostración

logb n

j=0

T (n) = cnk

a

j

bk

1 a < bk ⇒ T (n) ∈ Θ(nk )



i=0

r i =

1
1 − r

= constante (no diverge), para r < 1

2 a = bk ⇒ T (n) ∈ Θ(nk log n)

T (n) = cnk (logb n + 1)

URJC

DAA

19 / 37

Tema 3.2: Eficiencia de algoritmos recursivos

Expansión de recurrencias

Teorema maestro - demostración

logb n

a

j

bk

j=0

T (n) = cnk

3 a > bk ⇒ T (n) ∈ Θ(nlogb a)

a

bk

logb n+1 − 1
− 1
a

bk

cnk a

alogb n
nk − cnk
K1
K2nlogb a − cnk

bk

=

T (n) = cnk

K2alogb n − cnk

=

K1
Como a > bk ⇒ logb a > k ⇒ T (n) ∈ Θ(nlogb a)

K1

=

URJC

DAA

20 / 37

Tema 3.2: Eficiencia de algoritmos recursivos

Expansión de recurrencias

Teorema maestro - versión completa

Dada una recurrencia del tipo:

T (n) = aT (n/b) + f (n)

donde a > 0, b > 0, y f (n) es una función asintóticamente positiva,
entonces se puede aplicar el teorema maestro en estos tres casos:

URJC

DAA

21 / 37

Tema 3.2: Eficiencia de algoritmos recursivos

Expansión de recurrencias

Teorema maestro - versión completa

1 Si f (n) = O(nlogba−) para alguna constante  > 0, entonces:

T (n) ∈ Θ(nlogba)

2 Si f (n) = Θ(nlogbalog k n) con1 k ≥ 0, entonces:
T (n) ∈ Θ(nlogbalog k+1n)

3 Si f (n) = Ω(nlogba+) con  > 0, y f (n) satisface la condición de
regularidad (af (n/b) ≤ cf (n) para alguna constante c < 1 y para
todo n lo suficientemente grande), entonces:
T (n) ∈ Θ(f (n))

1k suele ser 0

URJC

DAA

22 / 37

Tema 3.2: Eficiencia de algoritmos recursivos Método general para resolución de relaciones de recurrencia

Método general para resolución de relaciones de
recurrencia

No siempre se puede aplicar la expansión de recurrencias

Para muchas recurrencias no se conoce la forma de resolverlas

Sucede como con las integrales o ecuaciones diferenciales: sabemos
como resolver un subconjunto de éstas, pero no todas

Ahora veremos un método general con el que vamos a ampliar el
conjunto de recurrencias que podemos resolver

URJC

DAA

23 / 37

Expansión derecurrenciasMétodo generalde resolución de recurrenciasRecurrencias Tema 3.2: Eficiencia de algoritmos recursivos Método general para resolución de relaciones de recurrencia

Recurrencias homogéneas

Dada la siguiente recurrencia homogénea (aparece un 0 en la parte
derecha):

a0T (n) + a1T (
  • Links de descarga
http://lwp-l.com/pdf14814  

Comentarios de: Tema 3.2: Eficiencia de algoritmos recursivos (0)


No hay comentarios
 

Comentar...

Nombre
Correo (no se visualiza en la web)
Valoración
Comentarios
Es necesario revisar y aceptar las políticas de privacidad

Revisar política de publicidad