Tema 2: Análisis y Diseño de Algoritmos Recursivos.

Anuncio
AD2 98/99. Tema 2: Análisis y Diseño de Algoritmos Recursivos
Tema 2: Análisis y Diseño
de Algoritmos Recursivos.
Objetivos.
Introducir las bases necesarias para el diseño y análisis de
los algoritmos recursivos.
Bibliografía.
BÁSICA:
Brassard, P. Bratley: “Algorítmica: concepción y análisis”.
Masson, 1990.
AD2 98/99. Tema 2: Análisis y Diseño de Algoritmos Recursivos
Contenidos.
1. INTRODUCCIÓN : ALGORITMOS RECURSIVOS
2. INDUCCIÓN
2.1 PRINCIPIO DE INDUCCIÓN
2.2 VERIFICACIÓN DE ALGORITMOS RECURSIVOS
3. ETAPAS DEL DISEÑO RECURSIVO.
4. ANÁLISIS DE LA COMPLEJIDAD TEMPORAL DE
LOS ALGORITMOS RECURSIVOS
Scholl P.C. Algorítmica y Representación de Datos. Tomo
2: Recursividad y Arboles. Ed. Masson, 1986.
Casanova A. Programación. Servicio de Publicaciones
UPV, València, 1993.
OTROS:
Aho A.V., Hopcroft J.E., Ullman J.U. The Design and
Analysis of Computer Algorithms. Ed.Addison-Wesley,
1974
Balcázar J.L. “Programación Metódica”. McGraw-Hill,
1993
Grimaldi R.P. Matemáticas Discreta y Combinatoria. Ed.
Addison Wesley Iberoamericana, 1984
Sahni S. Concepts in Discrete Mathematics. The Camelot
Publishing Company, 1985
1
2
AD2 98/99. Tema 2: Análisis y Diseño de Algoritmos Recursivos
1. INTRODUCCIÓN : Algoritmos
recursivos
AD2 98/99. Tema 2: Análisis y Diseño de Algoritmos Recursivos
Un algoritmo A que resuelve un problema P es recursivo si
está basado directa o indirectamente en sí mismo.
- Un objeto es recursivo si su definición requiere la
definición previa del objeto en un caso más sencillo.
Ejemplo: Números Naturales N
Problema P con Datos I
(a) el 0 es un número natural.
resuelto
(b) el sucesor de un número natural es también un
número natural.
en términos de ...
Problema P con Datos I' I
- Una función es recursiva si su resolución requiere la
solución previa de la función para casos más sencillos.
con:
Ejemplo:
I, I' del mismo tipo
I'I
(a) 0!=1
Cuando I' es lo más pequeña posible, solución
directa
(b) n!=n (n-1)!
3
4
AD2 98/99. Tema 2: Análisis y Diseño de Algoritmos Recursivos
ESQUEMA DE
SENCILLO :
UN
ALGORITMO
RECURSIVO
h( x )
d ( x)
f ( x) c( x , f (ant ( x )) d ( x )
{P(x)}
función f(x:T1) devuelve T2
opción
d(x):
r:=h(x); /*Casos directos*/
d(x): v:=f(ant(x)); r:=c(x,v);
/*Casos recursivos*/
AD2 98/99. Tema 2: Análisis y Diseño de Algoritmos Recursivos
TIPOS DE RECURSIÓN
1.- RECURSIÓN LINEAL : Si cada llamada recursiva
genera, como mucho otra llamada recursiva
- FINAL : si la llamada recursiva es la última operación
que se efectúa, devolviéndose como resultado lo que se
haya obtenido de la llamada recursiva sin modificación
alguna.
- NO FINAL : El resultado obtenido de la llamada
recursiva se combina para dar lugar al resultado de la
función que realiza la llamada.
fopción
devuelve r
2.- RECURSIÓN MÚLTIPLE : si alguna llamada puede
generar más de una llamada adicional.
ffunción
{Q(x,r)}
Cada llamada recursiva (activación de la función) posee su
propio conjunto de variables locales y parámetros.
Existen tantos objetos con un mismo nombre como
activaciones de la función estén pendientes de terminar.
La comunicación entre las sucesivas activaciones debe
hacerse por medio de parámetros.
5
6
AD2 98/99. Tema 2: Análisis y Diseño de Algoritmos Recursivos
AD2 98/99. Tema 2: Análisis y Diseño de Algoritmos Recursivos
EJEMPLOS :
RECURSIÓN LINEAL FINAL
Supongamos que hacemos la llamada MCD(25,15)
Traza :
Secuencia de llamadas :
{n
0 m
0}
función MCD(n,m:entero)devuelve entero
MCD(25,15)
var r :entero ;
MCD(25,15)
n,m
opción
r = MCD(n-m,m)
10,15
n=m :
r :=n ;
n>m :
r :=MCD(n-m,m) ;
MCD(n-m,m)
n<m :
r :=MCD(n,m-n) ;
10,15
fopción
n,m
r = MCD(n,m-n)
10,5
n,m
devuelve r
ffunción
n,m
r=MCD(n-m,m)
MCD(n,m-n)
{MCD(n,m) es el m·ximo entero que divide a n y a m}
10,5
5,5
n,m
n,m
{r=5}
{r=5}
MCD(n-m,m)
{r=5}
5,5
{r=5}
n,m
7
8
AD2 98/99. Tema 2: Análisis y Diseño de Algoritmos Recursivos
RECURSIÓN LINEAL NO FINAL :
AD2 98/99. Tema 2: Análisis y Diseño de Algoritmos Recursivos
Supongamos que la llamada inicial es FACT(4)
Secuencia de llamadas :
{n
0}
función FACT (n:entero)devuelve entero
var r,v :entero ;
opción
n=0 :
r :=1 ;
n>0 :
v := FACT(n-1) ;
r :=v*n;
fopción
devuelve r
ffunción
{FACT(n)=n†!}
9
FACT(4)
n
FACT(n-1)
3
n
FACT(n-1)
2
n
FACT(n-1)
1
n
FACT(n-1)
0
n
Llamada inicial
Caso Directo
10
AD2 98/99. Tema 2: Análisis y Diseño de Algoritmos Recursivos
Traza :
AD2 98/99. Tema 2: Análisis y Diseño de Algoritmos Recursivos
RECURSIÓN MÚLTIPLE :
FACT(4)
n=4
v :=FACT(n-1) ;
n=3
v :=FACT(n-1) ;
n=2
v :=FACT(n-1) ;
n=1
v :=FACT(n-1) ;
n=0
r :=1 ;
{v=1}
r :=v*n
{r=1*1=1}
{v=1}
r :=v*n
{r=1*2=2}
{v=2}
r :=v*n
{r=2*3=6}
{v=6}
r :=v*n
{r=6*4=24}
11
{n
0}
función Fib(n:entero)devuelve entero ;
var r :entero ;
opción
n1 :
r:=n ;
n>1 : r:=Fib(n-1)+Fib(n-2) ;
fopción
devuelve r
ffunción
{Fib(n)=Fibonacci(n)}
donde
n
n 1
Fibonacci (n) Fibonacci
(
n
1
)
Fibonacci
(
n
2
)
n
1
12
AD2 98/99. Tema 2: Análisis y Diseño de Algoritmos Recursivos
Traza :
Supongamos que la llamada es Fib(4) :
Árbol de llamadas :
Fib(4)
Fib(3)
Fib(2)
Fib(1)
Fib(2)
Fib(1)
Fib(0)
13
AD2 98/99. Tema 2: Análisis y Diseño de Algoritmos Recursivos
Fib(1)
Fib(0)
Fib(4) Llamada inicial
n
Fib(n-1)
n=3
Fib(n-1)
n=2
Fib(n-1)
n=1
{r=1}
Fib(n-2)
n=0
{r=0}
{r=1+0=1}
Fib(n-2)
n=1
{r=1}
{r=1+1=2}
Fib(n-2)
n=2
Fib(n-1)
n=1
{r=1}
Fib(n-2)
n=0
{r=0}
{r=1+0=1}
{r=2+1=3}
14
AD2 98/99. Tema 2: Análisis y Diseño de Algoritmos Recursivos
AD2 98/99. Tema 2: Análisis y Diseño de Algoritmos Recursivos
2. INDUCCIÓN
Si queremos demostrar la correcciÛn de un algoritmo
Para comprobar que un algoritmo recursivo es correcto hay
que analizar los aspectos siguientes :
recursivo ....
øQU… M…TODO DE DEMOSTRACI”N
1.- ¿Hay una salida no recursiva del algoritmo (Caso
Directo) ?, ¿El algoritmo cumple con la especificación en
este caso ?
PODEMOS USAR?
1. Debemos analizar todas y cada una de las
instrucciones del algoritmo.
2.- ¿Cada llamada recursiva se refiere a un caso más
pequeño del problema original ?
2. Pero .... !!! incluye instrucciones que consisten en
ejecutar el mismo algoritmo ("llamadas recursivas") !!
Idea : Suponer que estas llamadas funcionan
correctamente e intentar demostrar que la función
que hace la llamada también.
3.- Suponiendo que la(s) llamada(s) recursivas cumplen la
especificación (son correctas), ¿cumple la especificación el
algoritmo completo ?
Aplicar el método de demostración por inducción
15
16
AD2 98/99. Tema 2: Análisis y Diseño de Algoritmos Recursivos
AD2 98/99. Tema 2: Análisis y Diseño de Algoritmos Recursivos
Principio de Inducción Fuerte
2.1 PRINCIPIO DE INDUCCIÓN.
Principio de Inducción Fuerte
FASE 1: BASE INDUCCIÓN
FASE 1: BASE INDUCCIÓN
Probar que la propiedad P es cierta para n0 0, n0 N.
(Para ello se utilizan las propiedades de los naturales.)
Probar que la propiedad P es cierta para n0 0, n0 N.
(Para ello se utilizan las propiedades de los naturales.)
FASE 2: INDUCCIÓN
FASE 2: INDUCCIÓN
2a) HIPÓTESIS DE INDUCCIÓN: Supongo que P es
cierta x [n0, n], n n0, n0, n, x N.
Probar que P es hereditara
2a) HIPÓTESIS DE INDUCCIÓN: Supongo P cierta para
n N / n n0
2b) PRUEBA: Probar que P es cierta para n+1.
(Para ello se utilizan las propiedades de los N y la hipótesis de inducción.)
2b) PRUEBA: Probar que P es cierta para n+1.
(Para ello se utilizan las propiedades de los N y la hipótesis de inducción.)
FASE 3: CONCLUSIÓN Si hemos concluido con éxito las
dos fases anteriores
P es cierta n N, n n0, n0 N
FASE 3: CONCLUSIÓN Si hemos concluido con éxito las
dos fases anteriores
P es cierta n N, n n0, n0 N
( P(n0) n: ( P(n) P(n + 1) ) n: P(n))
( n: ((x: x <n: P(x)) P(n))) n: P(n))
n0
x
n0
n n+1
Probar que P es hereditara
n
n0
n0
17
18
AD2 98/99. Tema 2: Análisis y Diseño de Algoritmos Recursivos
AD2 98/99. Tema 2: Análisis y Diseño de Algoritmos Recursivos
PRUEBA POR INDUCCIÓN DE PROPIEDADES DE
FUNCIONES RECURSIVAS.
Ejemplo:
Todo número de la forma 10 n -1 es divisible por 9.
Sea f: D R una función recursiva.
Sea P una propiedad de la función, tal como
BASE DE INDUCCIÓN:
CORRECCIÓN, TERMINACIÓN, OTRAS
Probar que 100 - 1 es divisible por 9: 100 - 1 = 0 = 0 * 9
INDUCCIÓN:
Ejemplo: Dada la función factorial
1
n 0
FACT (n) n * FACT (n 1) n 0
2a) HIPÓTESIS DE INDUCCIÓN:
(a) Demostrar que termina.
Supongo que 10n - 1 es divisible por 9 ( 10n - 1 = 9 * a)
Como el dominio de FACT es N, utilizaremos el principio
de inducción sobre N para la demostración
2b) PRUEBA:
10n+1 - 1 = 10 * (10n - 1) + 9 = 9 * (10 * a + 1)
BASE: FACT(0) origina un número finito de cálculos
INDUCCIÓN:
HIPOTESIS: FACT(n - 1) origina un número finito de
cálculos
PRUEBA: ¿FACT(n) origina un número finito?
Por definición , FACT(n) = FACT(n - 1) * n
Por HI, FACT(n - 1) termina
Entonces, FACT(n) también termina.
19
20
AD2 98/99. Tema 2: Análisis y Diseño de Algoritmos Recursivos
(b) Demostrar que es correcta, o sea que :
FACT (n) n!
donde n ! se define como
n1 n 0
n ! i n 0
1
AD2 98/99. Tema 2: Análisis y Diseño de Algoritmos Recursivos
2.2
VERIFICACIÓN
DE
ALGORITMOS
RECURSIVOS. FUNCIÓN LIMITADORA.
Consideremos el siguiente esquema :
{P(x)}
función f(x:T1) devuelve T2
BASE: FACT(0)=1
opción
INDUCCIÓN:
HIPÓTESIS:
d(x): r:=h(x); /*Casos directos*/
FACT(n-1) = 1 * 2 *.. * (n - 1) n > 0
d(x): v:=f(ant(x)); r:=c(x,v);
/*Casos recursivos*/
PRUEBA: ¿ FACT(n) = 1 * 2 * 3 * .. * n?
fopción
devuelve r
Por definición , FACT(n)=n * FACT(n - 1)
Por HI, FACT(n-1) = 1 * 2 * .. * (n - 1)
ffunción
{Q(x,r)}
Entonces,
FACT(n) = n * (1 * 2 * .. *(n - 1))=1 * 2 * .. * (n - 1) * n
21
22
AD2 98/99. Tema 2: Análisis y Diseño de Algoritmos Recursivos
AD2 98/99. Tema 2: Análisis y Diseño de Algoritmos Recursivos
Para verificar este esquema consideraremos :
CASOS DIRECTOS : Tendremos que demostrar
{P(x)d(x)}
r :=h(x)
{Q(x,r)}
La función limitadora :
- Valida el razonamiento por inducción
que equivale a demostrar P(x)d(x) {Q(x,h(x))}
CASOS RECURSIVOS :
1.- Garantizar que los parámetros de la llamada recursiva
cumplen la precondición :
P(x) d(x) P(ant(x))
- Garantiza la terminación de la secuencia de llamadas
recursivas, ya que cada una tiene que tener un valor
natural t(x) estrictamente inferior al de la anterior y en
los Naturales esto no puede ocurrir indefinidamente
- De hecho es una cota superior del número de llamadas
que se realizan a la función (cuando la recursión es
lineal).
2.- Demostración por inducción de la corrección :
P(x) d(x) Q(ant(x),v) Q(x,c(v,x))
H.I
La verificación no es un argumento a posteriori sino que
guia el diseño y explica el algoritmo.
3.- Validación del razonamiento inductivo :
Definir una función limitadora t : T1 Natural
Demostrar que t(x) decrece estrictamente en cada llamada :
P(x) d(x) t(ant(x)) < t(x)
23
24
AD2 98/99. Tema 2: Análisis y Diseño de Algoritmos Recursivos
3. ETAPAS DEL DISEÑO RECURSIVO.
Un diseño recursivo constará de las siguientes etapas:
AD2 98/99. Tema 2: Análisis y Diseño de Algoritmos Recursivos
DEFINICIÓN DEL PROBLEMA
Nombre
del algoritmo, sus datos y sus resultados
Precondición
Postcondición
1.- Definición del problema.
2.- Análisis de casos. Identificación de la función
limitadora.
3.-Transcripción algorítmica y verificación de cada caso.
4.-Validación de la inducción : la función limitadora
decrece estrictamente en las llamadas.
ANÁLISIS POR CASOS. IDENTIFICACIÓN DE LA
FUNCIÓN LIMITADORA.
Analizar los diferentes casos que se puedan presentar,
identificando :
Uno (o más) CASOS DIRECTOS
Uno (o mas) CASOS RECURSIVOS
Concretar la FUNCIÓN LIMITADORA
OBSERVACIONES :
1.- Es preciso asegurarse de que se cubren todos los casos
que pueden aparecer.
2.- Frecuentemente, la elección de los casos directos puede
realizarse antes de decidir la función limitadora, basta
comparar P y Q para ver en qué casos es fácil obtener Q a
partir de P. Así los casos directos pueden ayudar a buscar la
función limitadora : decrementar ésta debe suponer
aproximarse al caso directo.
25
26
AD2 98/99. Tema 2: Análisis y Diseño de Algoritmos Recursivos
DISEÑO Y VERIFICACIÓN DE CADA CASO
Diseño del fragmento de programa que resuelve cada caso
junto con su verificación :
(1) Al programar los casos recursivos es preciso
suponer, como Hipótesis de Inducción, que las
llamadas recursivas funcionan correctamente.
(2) Para poder aplicar la inducción ha de garantizarse
que, al evaluar la función limitadora sobre los
parámetros que aparecen en cada llamada, se obtienen
valores estrictamente menores que los que
corresponden a los recibidos.
Como subproducto de (2) queda demostrado que la
recursión es finita, ya que no puede haber infinitas
llamadas recursivas tales que cada una de ellas tenga
asociado un número natural estrictamente inferior al
de la anterior.
AD2 98/99. Tema 2: Análisis y Diseño de Algoritmos Recursivos
PROBLEMA 1: MULTIPLICACIÓN DE NATURALES
Supongamos que el repertorio de instrucciones disponibles
sobre los naturales se reduce a la suma y la diferencia.
Queremos diseñar un algoritmo recursivo para realizar la
multiplicación de naturales.
Definición :
algoritmo MULT (Datos a,b :entero
Resultado p :entero)
Precondición {a
0 b
0}
Postcondición {p=a*b}
Análisis de casos. Función limitadora.
Hemos de distinguir al menos un caso directo y otro
recursivo, éste nos ha de permitir hacer decrecer los
parámetros en algún sentido.
Tomemos como función limitadora “a” e intentemos
decrementarla de 1 en 1 :
Caso DIRECTO : a=0
Casos RECURSIVOS : a>0
27
28
AD2 98/99. Tema 2: Análisis y Diseño de Algoritmos Recursivos
Solución al Caso Directo :
AD2 98/99. Tema 2: Análisis y Diseño de Algoritmos Recursivos
El algoritmo queda :
{a
0 b
0}
{a=0}
función MULT(a,b:entero)devuelve entero;
??
p :=0
var p :Natural
opción
{p=a*b}
a=0 : p :=0 ;
Solución a los Casos recursivos :
a>0 : p :=MULT(a-1,b) ;
{p=(a-1)*b}
Obsérvese que a*b=(a-1+1)*b=(a-1)*b+b
p :=p+b ;
fopción
{a>0}
{p=a*b}
devuelve p
p :=MULT(a-1,b)
ffunción
{p=(a-1)*b)} H.I
??
{MULT(a,b)=a*b}
p :=p+b
¿Cuántas llamadas recursivas hace MULT(a,b) ? a
{p=a*b}
PRIMERA MEJORA : Hacer decrecer el menor de a y b
29
30
AD2 98/99. Tema 2: Análisis y Diseño de Algoritmos Recursivos
AD2 98/99. Tema 2: Análisis y Diseño de Algoritmos Recursivos
Diseño de ? ?
SEGUNDA MEJORA :
Si a es PAR : 2*(a div 2)*b=a*b
Suponiendo que además de las operaciones + y - se pueden
usar ciertas multiplicaciones y divisiones (por 2).
Si a es impar :
(a div 2)=(a-1) div 2
Intentemos decrementar a de otra manera : dividiendo por 2
2*(a div 2)*b=2*((a-1) div 2)*b=(a-1)*b
luego a*b=2*(a div 2)*b+b=MULT2(a div 2,b)+b
Hemos de garantizar que a div 2 < a (en el caso recursivo):
Algoritmo resultante :
Caso DIRECTO : a=0
{a
0 b
0}
Casos RECURSIVOS : a>0
función MULT2(a,b:entero)devuelve entero;
Solución al Caso directo : igual que antes
var p :entero
opción
Solución a los Casos recursivos :
a=0 : p :=0 ;
a>0 : p :=MULT(adiv2,b);
{a>0}
{p=(a div 2)*b}
p :=MULT2(a div 2,b)
opción
{p=(a div 2)*b)} H.I
par(a):
p:=p*2;
??
par(a):
p:=p*2+b
fopción
{p=a*b}
{p=a*b}
devuelve p
ffunción
{MULT2(a,b)=a*b}
¿Cuántas llamadas recursivas se realizan en este caso ? log a
31
32
AD2 98/99. Tema 2: Análisis y Diseño de Algoritmos Recursivos
PROBLEMA 2: Cálculo del cociente y el resto de la
división entera. Dados dos enteros a 0 y b > 0 se desea
obtener q, r tales que
a = b * q + r q 0, 0 r < b
Solo usaremos +, - y multiplicaciones y divisiones por 2.
DEFINICIÓN:
algoritmo DIVIDIR (Datos a,b :entero
Resultados q,r :entero)
AD2 98/99. Tema 2: Análisis y Diseño de Algoritmos Recursivos
ANALISIS POR CASOS Y FUNCIÓN LIMITADORA :
Observemos que :
a - b = b * (q - 1) + r, 0 r < b q - 1 0
donde “q-1” es el cociente de “(a-b) div b” y “r” es el resto
Esto nos da una pista para tomar como función limitadora a
y reducir su valor en la forma a-b. Esto requiere como
guarda que a
b, quedando a<b como caso directo :
Casos directos : a<b
Casos recursivos : a
b
Precondición {a
0 b>0}
Postcondición {a=b*q+r 0r<b q
0}
Solución de los Casos Directos :
{b>0 a<b}
??
q :=0 ; r :=a ;
{a=b*q+r r<b q
0}
Solución de los Casos Recursivos :
{b>0 a
b}
DIVIDIR(a-b,b,q,r) ;
{a-b=b*q+r} {a=b*(q+1)+r}
q :=q+1 ;
{a=b*q+r r<b q
0}
33
34
AD2 98/99. Tema 2: Análisis y Diseño de Algoritmos Recursivos
ALGORITMO RESULTANTE :
AD2 98/99. Tema 2: Análisis y Diseño de Algoritmos Recursivos
Ejercicios propuestos :
(1) ¿Podríamos basar el diseño en reducir a en 1 ?
{a
0 b>0}
acción dividir(ent a,b:entero;
sal q,r :entero)
opción
a<b:
q :=0;r :=a ;
a
b:
dividir(a-b,b,q,r);
(2) Diseñar un algoritmo reduciendo el parámetro “a”
mediante una división por 2.
(3) Diseñar un algoritmo incrementando el parámetro “b”
duplicándolo.
q :=q+1 ;
fopción
ffunción
{a=b*q+rq
00r<b q
0}
35
36
AD2 98/99. Tema 2: Análisis y Diseño de Algoritmos Recursivos
PROBLEMA 3 : SUMAR LAS “i”
COMPONENTES DE UN VECTOR “v”.
AD2 98/99. Tema 2: Análisis y Diseño de Algoritmos Recursivos
PRIMERAS
ANÁLISIS DE CASOS Y FUNCIÓN LIMITADORA :
CASO DIRECTO : i=0, anula el dominio del cuantificador
de Q. La solución es s :=0
Supongamos definido :
tipo TipoVector=vector [1..N] de entero ;
CASOS RECURSIVOS : i>0
DEFINICIÓN :
Como función limitadora elegiremos el valor de “i”
algoritmo SUMAV (Datos v :TipoVector ;i :entero
Resultado s : entero)
{iN i>0}
s :=SUMAV(a,i-1) ;
Precondición : {0iN}
Postcondición : {SUMAV(v)=j=1..i v[j] }
{s=j=1..i-1 v[j] }
??
{s=j=1..i v[j] }
37
38
s :=s+a[i]
AD2 98/99. Tema 2: Análisis y Diseño de Algoritmos Recursivos
AD2 98/99. Tema 2: Análisis y Diseño de Algoritmos Recursivos
4. ANÁLISIS DE LA COMPLEJIDAD TEMPORAL DE
LOS ALGORITMOS RECURSIVOS.
Algoritmo resultante :
función SumaV(v:TipoVector;i:entero)
devuelve entero
var s :entero ;
opción
i=0 :
s :=0 ;
i>0 :
s :=SumaV(v,i-1) ;
s :=s+v[i] ;
fopción
devuelve s
ffunción
Si la definición recursiva es:
h( x )
si d ( x )
f (x ) c( x, f (ant1( x )),..., f (ant m ( x ))) si d ( x )
el coste del algoritmo asociado vendrá frecuentemente
dado por:
coste(n) = m coste( F(n) ) + g(n)
si n > n0
coste (n) = no importa
si n n0
donde:
F es la función de reducción de la talla (n) en cada
llamada recursiva. Normalmente F(n)<n, y más
concretamente: F(n) = n–c ó F(n) = n/c.
m es el número de llamadas recursivas que genera
cada llamada a f(x), suponiendo que en todas ellas la
talla se reduzca de la misma forma.
g(n) es el coste de f(x) excluidas las llamadas
recursivas.
39
40
AD2 98/99. Tema 2: Análisis y Diseño de Algoritmos Recursivos
Resolveremos las relaciones de recurrencia por el
método de sustitución.
AD2 98/99. Tema 2: Análisis y Diseño de Algoritmos Recursivos
EJEMPLO (Aplicación del método de sustitución).
función máximo(a: vector; i: entero)
devuelve entero;
opción
i=1: devuelve a[1];
i>1: devuelve
mayor(máximo(a,i-1),a[i]));
fopción
ffunción
La primera llamada es máximo(a,n), siendo n el nº
de elementos del vector.
• La talla del problema es n.
• No hay diferentes instancias; en cualquier caso
se recorre todo el vector.
Las relaciones de recurrencia serán:
coste( 1 ) = K1
coste( n ) = coste( n-1 ) + K2
41
42
n>1.
AD2 98/99. Tema 2: Análisis y Diseño de Algoritmos Recursivos
El método de sustitución consiste en ir desarrollando la
función, tomando valores decrecientes de n y
sustituyendo en coste(n) hasta llegar al caso en que
cesa la recurrencia (caso directo).
AD2 98/99. Tema 2: Análisis y Diseño de Algoritmos Recursivos
Para obtener el orden de las relaciones más
habituales, se puede aplicar el siguiente teorema.
TEOREMA. Sean a 1, b R+, n, c N.
Supóngase que f verifica para n c las relaciones
indicadas. Entonces:
En el ejemplo anterior:
Caso 1
f(n) = a f(n-c) + b
coste(1) = K1
coste(n) = coste(n-1) + K2
luego
n>1,
a=1
(n)
a>1
(an/c)
a=1
(n2)
a>1
(an/c)
a=1
(logcn)
a>1
(nlogca)
a<c
(n)
a=c
(n logcn)
a>c
(nlogca)
Caso 2
f(n) = a f(n-c) + bn + d
coste(n)
= coste(n-1) + k
= coste(n-2) + 2k
= coste(n-3) + 3k
Caso 3
f(n) = a f(n/c) + b
= coste(n-4) + 4k = ....
= coste(n-(n-1)) + (n-1)k
Caso 4
= coste(1) + (n-1)k
f(n) = a f(n/c) + bn + d
= k' + (n-1)k (n).
43
44
AD2 98/99. Tema 2: Análisis y Diseño de Algoritmos Recursivos
Ejemplo: Las torres de Hanoi, en el que se deben
mover n discos de uno en uno desde una pila inicial a
otra destino haciendo uso de una tercera pila auxiliar,
con la restricción de que cualquier disco, en cualquier
momento, sólo puede tener por debajo de él discos de
mayor diámetro.
Procedimiento hanoi(n: natural;
ini, dest, aux:
pila de discos) es
si n>0 entonces
hanoi(n-1,ini,aux,dest);
mueve_disco_sup(ini,dest);
hanoi(n-1,aux,dest,ini)
fsi
fprocedimiento,
donde mueve_disco_sup(a,b tiene coste (1).
AD2 98/99. Tema 2: Análisis y Diseño de Algoritmos Recursivos
Al resolver por sustitución:
coste(n) = 2 coste(n-1) + K1
n>0
coste(n) = K2
n=0
coste(n)
= 2coste(n-1) + K1
= 2(2coste(n-2) + K1) + K1
= 4coste(n-2) +2 K1 + K1
= 4(2coste(n-3) + K1) + 2 K1+ K1
= 8coste(n-3) + 4 K1 + 2 K1 + K1 =......
n
n-1
= 2 coste(0) +2
Talla del problema: n. No hay instancias diferentes.
n
n-2
K1 + 2
n
n
= 2 K2 + K1(2 -1) (2 ).
Relaciones de recurrencia de la función de coste:
coste(n) = 2 coste(n-1) + K1
n>0
n=0
coste(n) = K2
45
46
K1 + ... + 2 K1 + K1
AD2 98/99. Tema 2: Análisis y Diseño de Algoritmos Recursivos
EJEMPLO: Búsqueda dicotómica. (Aplicación de las
relaciones de recurrencia a algoritmos iterativos.)
{ v está ordenado }
procedimiento dicotómica
(v: vector1..n
de entero;
n, x: entero;
sal está: lógico;
sal m: entero) es
var i,j: entero fvar;
i:=1 ; j:=n; está := falso;
repetir
m := (i+j) div 2;
opción
v[m] > x: j := m - 1;
v[m] < x: i := m + 1;
v[m] = x: está := verdadero;
fopción
hasta que i>j
está
fprocedimiento
{1mn((está vm=x) (está k:1kn:vkx)}
AD2 98/99. Tema 2: Análisis y Diseño de Algoritmos Recursivos
(Caso peor)
costep(n) = K1 + costep(n/2))
costep(1) = K2
Si se resuelve la recurrencia por sustitución:
costep(n)
= K1 + costep(n/2)
2
= K1 + K1 + costep(n/2 )
2
= 2 K1 + costep(n/2 )
3
= 2 K1 + K1 + costep(n/2 )
4
La talla del problema es n = j-i+1 j-i
= 3 K1 + K1 + costep(n/2 ) = ....
Caso peor (x no está en v): como tras cada iteración la
talla del problema disminuye aproximadamente a la
mitad, se tiene que:
= (log2n) K1 + costep(n/2
coste(n) = K1 + coste(n/2)
47
n>1
n>1
log n
))
= (log2n) K1 + costep(n/n)
= (log2n) K1 + K2 ( logn ).
48
AD2 98/99. Tema 2: Análisis y Diseño de Algoritmos Recursivos
AD2 98/99. Tema 2: Análisis y Diseño de Algoritmos Recursivos
Caso mejor: x se encuentra en la primera iteración.
Resumen:
coste(n) ( logn )
coste(n) !( 1 )
49
50
Descargar