Recursividad

Anuncio
Año 2011
Cátedra: Computación
Profesor: Mgr. Ma. del Carmen Varaldo
Apunte sobre RECURSIVIDAD
Concepto: Una definición recursiva es aquélla en la que el objeto que se define forma
parte de la definición.
Ejemplo: “Un descendiente del Sr. Pérez”
Una persona es descendiente del Sr. Pérez si:
(1) es un hijo del Sr. Pérez, o
(2) es un hijo de un descendiente del Sr. Pérez.
La condición (1) se denomina salida de la definición.
La condición (2) se denomina parte recursiva propiamente dicha.
Funciones recursivas:
Ejemplo 1: Factorial de un número entero no negativo definido en modo recursivo.
n! =
1
si
n(n − 1)! si
n=0
n>0
En Pascal se escribe ası́:
function factorial (n:byte) : real;
begin
if n = 0
then factorial := 1
else factorial := n∗ factorial(n − 1);
end;
Ejemplo 2: Serie de Fibonacci 1, 1, 2, 3, 5, 8, 13, . . .
Fib(1) =
Fib(2) =
Fib(3) =
Fib(4) =
En general,
1
1
Fib(2) + Fib(1)
Fib(3) + Fib(2)
Fib(n) =
1
si
Fib(n − 1) + Fib(n − 2) si
1
n = 1, n = 2
n≥3
En Pascal se escribe ası́:
function fibonacci (n:byte) : word;
begin
if n = 1 or n = 2
then fibonacci := 1
else fibonacci := fibonacci(n-1) + fibonacci(n-2);
end;
En el caso que se reemplace el parámetro n por 5, esta función será llamada de la
siguiente manera
fibonacci(2)
fibonacci(3)
%
&
fibonacci(1)
%
fibonacci(4)
&
fibonaccii(2)
fibonacci(5)
%
&
fibonacci(2)
fibonacci(3)
%
&
fibonacci(1)
Volviendo hacia atrás sobre los llamados a la función y sabiendo que f ibonacci(2) =
f ibonacci(1) = 1 se deduce que f ibonacci(5) = 5.
Observe, además, que algunos de los cálculos se repiten, por ejemplo fibonacci(1).
Existe otro método de resolver este problema a través de una forma iterativa, no
recursiva. Se presenta la siguiente función:
2
function fibo (n:byte) : word;
var
a, b, f, i : word
begin
a := 1;
b := 1;
if n = 1 or n = 2
then f := 1
else
for i := 3 to n do begin
f := b + a;
a := b;
b := f ;
end;
f ibo := f ;
end;
No siempre es posible pasar de una forma recursiva a una iterativa.
Cuando una rutina recursiva se llama recursivamente a sı́ misma varias veces, para cada llamada se crean copias independientes de las variables declaradas en el
subprograma.
A pesar de que la recursión permite representar en forma clara y elegante muchos
algoritmos, sin embargo, el costo de memoria y tiempo que requiere su realización,
puede implicar que para determinados algoritmos no sea conveniente su utilización.
Procedimientos recursivos:
Ejemplo 1: En Pascal se tiene:
procedure Q (Num1,Num2 : integer);
begin
if N um2 ≤ 0
then Writeln
else begin
Q(N um1 − 1, N um2 − 1);
Write(Num1:1);
Q(N um1 + 1, N um2 − 1);
end;
end;
Observe que si se reemplaza Num1 por 4 y Num2 por 2, se estarı́a invocando el
procedimiento de la siguiente manera:
3


 Q(2, 0)




Write(Num1:1)
Q(3, 1) →





Q(4, 0)





Write(Num1:1) escribe 4
Q(4, 2) →








 Q(4, 0)



Write(Num1:1)
Q(5, 1) →




Q(6, 0)
cambio de renglón
escribe 3
cambio de renglón
cambio de renglón
escribe 5
cambio de renglón
La salida por pantalla es:
3
4
5
Ejemplo 2: Las Torres de Hanói es un rompecabezas o juego matemático inventado en
1883 por el matemático francés Éduard Lucas. El juego, en su forma más tradicional, consiste en tres varillas verticales. En una de las varillas se apila un número
indeterminado de discos (elaborados de madera) que determinará la complejidad de
la solución, por regla general se consideran ocho discos. Los discos se apilan sobre
una varilla en tamaño decreciente. No hay dos discos iguales, y todos ellos están
apilados de mayor a menor radio en una de las varillas, quedando las otras dos varillas vacantes. El juego consiste en pasar todos los discos de la varilla ocupada (es
decir la que posee la torre) a una de las otras varillas vacantes. Para realizar este
objetivo, es necesario seguir tres simples reglas:
1. Sólo se puede mover un disco cada vez.
2. Un disco de mayor tamaño no puede descansar sobre uno más pequeño que él
mismo.
3. Sólo puedes desplazar el disco que se encuentre arriba en cada varilla.
Existen diversas formas de realizar la solución final, todas ellas siguiendo estrategias
diversas.
El siguiente algoritmo resuelve este juego en forma recursiva:
Program hanoi;
uses crt;
var
i,total:integer;
c:char;
procedure movertorre(altura,deaguja,haciaaguja,useaguja:integer);
procedure moverdisco(salida,ponsobre:integer);
4
begin
writeln(salida,’->’,ponsobre);
i:=i+1;
if (i mod 20=0) then begin
writeln(’Presione una tecla’);
c:=ReadKey;
end;
end;
begin
if altura>0 then begin
movertorre(altura-1,deaguja,useaguja,haciaaguja);
moverdisco(deaguja,haciaaguja);
movertorre(altura-1,useaguja,haciaaguja,deaguja);
end;
end;
begin
i:=0;
writeln(’ingresar cantidad de discos’);
readln(total);
movertorre(total,1,3,2);
end.
Bibliografı́a:
1. “Matemática Discreta y Combinatoria”, Ralph Grimaldi
2. “Programación en TURBO PASCAL 7”, Luis Joyanes Aguilar, McGrawHill
5
Descargar