recursión - dc.uba.ar · triángulo de sierpinsky •construcción: 1. comenzamos con un...

32
Recursión Introducción a la Computación Clase 15 Patricia Borensztejn

Upload: vankiet

Post on 26-Apr-2018

214 views

Category:

Documents


1 download

TRANSCRIPT

Page 1: Recursión - dc.uba.ar · Triángulo de Sierpinsky •Construcción: 1. Comenzamos con un triángulo. 2. Lo reducimos a la mitad de la altura y la mitad del lado y lo triplicamos,

Recursión

Introducción a la Computación

Clase 15

Patricia Borensztejn

Page 2: Recursión - dc.uba.ar · Triángulo de Sierpinsky •Construcción: 1. Comenzamos con un triángulo. 2. Lo reducimos a la mitad de la altura y la mitad del lado y lo triplicamos,

El concepto de la recursión

• Recursión, recurrencia o recursividad es la forma en la cual se especifica un proceso basado en su propia definición.

Page 3: Recursión - dc.uba.ar · Triángulo de Sierpinsky •Construcción: 1. Comenzamos con un triángulo. 2. Lo reducimos a la mitad de la altura y la mitad del lado y lo triplicamos,

Mas imágenes recursivas

• Triángulo de Sierpinsky (1915)

Page 4: Recursión - dc.uba.ar · Triángulo de Sierpinsky •Construcción: 1. Comenzamos con un triángulo. 2. Lo reducimos a la mitad de la altura y la mitad del lado y lo triplicamos,

Triángulo de Sierpinsky

• Construcción:

1. Comenzamos con un triángulo.

2. Lo reducimos a la mitad de la altura y la mitad del lado y lo triplicamos, haciendo que cada uno toque a los otros dos en un extremo

3. Volvemos al paso 2 por cada triángulo generado.

Page 5: Recursión - dc.uba.ar · Triángulo de Sierpinsky •Construcción: 1. Comenzamos con un triángulo. 2. Lo reducimos a la mitad de la altura y la mitad del lado y lo triplicamos,

Recursión

• Definición de la sintaxis de un lenguaje de programación (LISP):

– expresión ::= átomo | lista

– átomo ::= número | símbolo

– número ::= [+-]?['0'-'9']+

– símbolo ::= ['A'-'Z'<nowiki>'</nowiki>a'-'z'].*

– lista ::= '(' expresión* ')'

Page 6: Recursión - dc.uba.ar · Triángulo de Sierpinsky •Construcción: 1. Comenzamos con un triángulo. 2. Lo reducimos a la mitad de la altura y la mitad del lado y lo triplicamos,

Recursión: factorial

• Definición de una función matemática de forma recursiva:

Page 7: Recursión - dc.uba.ar · Triángulo de Sierpinsky •Construcción: 1. Comenzamos con un triángulo. 2. Lo reducimos a la mitad de la altura y la mitad del lado y lo triplicamos,

Recursión en los lenguajes de programación

• Una función que se llama a si misma directa o indirectamente, es una función recursiva.

Page 8: Recursión - dc.uba.ar · Triángulo de Sierpinsky •Construcción: 1. Comenzamos con un triángulo. 2. Lo reducimos a la mitad de la altura y la mitad del lado y lo triplicamos,

Factorial recursivo

factorial(5)

*

5 factorial(4)

*

4 factorial(3)

*

3 factorial(2)

*

2 factorial(1)

Camino de Ida: se contruye por cada activación de la función su bloque de activación en la pila

Camino de Ida

Page 9: Recursión - dc.uba.ar · Triángulo de Sierpinsky •Construcción: 1. Comenzamos con un triángulo. 2. Lo reducimos a la mitad de la altura y la mitad del lado y lo triplicamos,

Factorial recursivo

factorial(5)

*

5 factorial(4)

*

4 factorial(3)

*

3 factorial(2)

*

2

Camino de vuelta

factorial(1) devuelve 1 Y se libera su bloque de activación

1

Page 10: Recursión - dc.uba.ar · Triángulo de Sierpinsky •Construcción: 1. Comenzamos con un triángulo. 2. Lo reducimos a la mitad de la altura y la mitad del lado y lo triplicamos,

Factorial recursivo

factorial(5)

*

5 factorial(4)

*

4 factorial(3)

*

3

Camino de vuelta

factorial(2) devuelve 2 Y se libera su bloque de activación

2

Page 11: Recursión - dc.uba.ar · Triángulo de Sierpinsky •Construcción: 1. Comenzamos con un triángulo. 2. Lo reducimos a la mitad de la altura y la mitad del lado y lo triplicamos,

Factorial recursivo

factorial(5)

*

5 factorial(4)

*

4 6

Camino de vuelta

factorial(3) devuelve 6 Y se libera su bloque de activación

Page 12: Recursión - dc.uba.ar · Triángulo de Sierpinsky •Construcción: 1. Comenzamos con un triángulo. 2. Lo reducimos a la mitad de la altura y la mitad del lado y lo triplicamos,

Factorial recursivo

factorial(5)

*

5 24

Camino de vuelta

factorial(4) devuelve 24 Y se libera su bloque de activación

Page 13: Recursión - dc.uba.ar · Triángulo de Sierpinsky •Construcción: 1. Comenzamos con un triángulo. 2. Lo reducimos a la mitad de la altura y la mitad del lado y lo triplicamos,

Factorial recursivo

factorial(5) devuelve 120 Y se libera su bloque de activación

Page 14: Recursión - dc.uba.ar · Triángulo de Sierpinsky •Construcción: 1. Comenzamos con un triángulo. 2. Lo reducimos a la mitad de la altura y la mitad del lado y lo triplicamos,

Factorial recursivo, versión en C

• Mostramos también el estado de la pila con los bloques de activación …. en que momento? O sea, que estamos viendo en la pantalla?

Page 15: Recursión - dc.uba.ar · Triángulo de Sierpinsky •Construcción: 1. Comenzamos con un triángulo. 2. Lo reducimos a la mitad de la altura y la mitad del lado y lo triplicamos,

Recursión indirecta y declaración anticipada en C

• El problema es que par llama a impar, con lo cual impar debe estar antes, pero impar llama a par: esto se llama recursión indirecta

• En el lenguaje C, debemos declarar las variables, los tipos y las funciones antes de usarlas.

• ¿Como haríamos en este caso?

Page 16: Recursión - dc.uba.ar · Triángulo de Sierpinsky •Construcción: 1. Comenzamos con un triángulo. 2. Lo reducimos a la mitad de la altura y la mitad del lado y lo triplicamos,

Declaración anticipada • En realidad, C no necesita

conocer TODA la función antes de que sea usada, sino solamente su cabecera: nombre, tipo de retorno y parámetros.

• La solución es entonces incluir la cabecera antes de su uso.

• La declaración anticipada puede usarse cuando uno quiera, sin necesidad que se trata de funciones recursivas indirectas, pues a veces facilita la lectura de los programas

• Dibujar el estado de la pila para la llamada impar(7) cuando se llega al caso base.

Page 17: Recursión - dc.uba.ar · Triángulo de Sierpinsky •Construcción: 1. Comenzamos con un triángulo. 2. Lo reducimos a la mitad de la altura y la mitad del lado y lo triplicamos,

Manos Dibujando Maurits Cornelius Escher (1948)

Page 18: Recursión - dc.uba.ar · Triángulo de Sierpinsky •Construcción: 1. Comenzamos con un triángulo. 2. Lo reducimos a la mitad de la altura y la mitad del lado y lo triplicamos,

Recursión e Iteración

• La recursión es una herramienta poderosa pero ocupa muchos recursos en espacio y en tiempo.

• La recursión es una herramienta de repetición mucho mas poderosa que la iteración, debido a que la iteración funciona a nivel de bloque básico (lo que se repiten son un conjunto de sentencias acabadas con un GOTO), en cambio en la recursión se repite la función completa.

• Asi como es importante «salir del bucle», no quedarnos «colgados», en la recursión debemos garantizar el camino de regreso.

Page 19: Recursión - dc.uba.ar · Triángulo de Sierpinsky •Construcción: 1. Comenzamos con un triángulo. 2. Lo reducimos a la mitad de la altura y la mitad del lado y lo triplicamos,

Recursión e Iteración

“Iterar es humano, ‘recursivar’ es divino” dijo

L. Peter Deutsch

Page 20: Recursión - dc.uba.ar · Triángulo de Sierpinsky •Construcción: 1. Comenzamos con un triángulo. 2. Lo reducimos a la mitad de la altura y la mitad del lado y lo triplicamos,

Recursión e Iteración

“Iterar es humano, ‘recursivar’ es diabólico” digo

Yo!

Page 21: Recursión - dc.uba.ar · Triángulo de Sierpinsky •Construcción: 1. Comenzamos con un triángulo. 2. Lo reducimos a la mitad de la altura y la mitad del lado y lo triplicamos,

De recursivo a iterativo

• Para toda función recursiva existe un algoritmo iterativo.

• No siempre es sencillo encontrarlo… aunque hay métodos que nos ayudan…

Page 22: Recursión - dc.uba.ar · Triángulo de Sierpinsky •Construcción: 1. Comenzamos con un triángulo. 2. Lo reducimos a la mitad de la altura y la mitad del lado y lo triplicamos,

Recursivo es mas fácil de pensar

• Una ventaja de los recursivos es que es mas sencillo de pensar… (y mas bello a veces)

• Por ejemplo: pensamos en una función recursiva que calcule el número de bits necesario para representar un número entero. – Caso base: para representar el número 0 o el

número 1 necesitamos un bit

– Caso general: para representar el número n necesitamos un bit mas que para representar el número n/2, no? (la división es entera)

Page 23: Recursión - dc.uba.ar · Triángulo de Sierpinsky •Construcción: 1. Comenzamos con un triángulo. 2. Lo reducimos a la mitad de la altura y la mitad del lado y lo triplicamos,

Recursivo: número de bits necesario para representar el número n

Page 24: Recursión - dc.uba.ar · Triángulo de Sierpinsky •Construcción: 1. Comenzamos con un triángulo. 2. Lo reducimos a la mitad de la altura y la mitad del lado y lo triplicamos,

Fibonacci recursivo

• Un mal ejemplo:

Page 25: Recursión - dc.uba.ar · Triángulo de Sierpinsky •Construcción: 1. Comenzamos con un triángulo. 2. Lo reducimos a la mitad de la altura y la mitad del lado y lo triplicamos,

Fibonacci recursivo

• En la versión recursiva, por cada llamada a función hay dos llamadas a la función, cada una de las cuales genera como mucho otras dos llamadas y así sucesivamente: es decir, el número de llamadas crece de forma exponencial con n, es decir, crece muy rápidamente. Es del orden 2n.

Page 26: Recursión - dc.uba.ar · Triángulo de Sierpinsky •Construcción: 1. Comenzamos con un triángulo. 2. Lo reducimos a la mitad de la altura y la mitad del lado y lo triplicamos,

Fibonacci iterativo

• En la versión iterativa, el número de pasos es proporcional a n, es decir, crece linealmente con la entrada n. (se agrega una iteración mas)

• Por eso la versión iterativa es mejor que la recursiva, aunque no estamos diciendo que sea la mejor solución… podría haber alguna otra mejor.

Page 27: Recursión - dc.uba.ar · Triángulo de Sierpinsky •Construcción: 1. Comenzamos con un triángulo. 2. Lo reducimos a la mitad de la altura y la mitad del lado y lo triplicamos,

Torres de Hanoi

• Reglas:

– Solo podemos mover el disco superior del montón.

– El disco superior debe moverse de una aguja a otra de tal manera que jamás quede debajo de él un disco de mayor tamaño.

Page 28: Recursión - dc.uba.ar · Triángulo de Sierpinsky •Construcción: 1. Comenzamos con un triángulo. 2. Lo reducimos a la mitad de la altura y la mitad del lado y lo triplicamos,

Torres de Hanoi

• Para pasar el primer disco a la aguja final, las dos últimas situaciones deben ser las siguientes:

• Es decir, para resolver Hanoi(4, aguja inicial, aguja final), debemos: – resolver Hanoi(3, aguja

inicial, aguja libre) – Mover disco (aguja inicial,

aguja final) – Resolver Hanoi(3, aguja

libre, aguja final)

Page 29: Recursión - dc.uba.ar · Triángulo de Sierpinsky •Construcción: 1. Comenzamos con un triángulo. 2. Lo reducimos a la mitad de la altura y la mitad del lado y lo triplicamos,

Hanoi

Page 30: Recursión - dc.uba.ar · Triángulo de Sierpinsky •Construcción: 1. Comenzamos con un triángulo. 2. Lo reducimos a la mitad de la altura y la mitad del lado y lo triplicamos,

Hanoi

• El problema de Hanoi… es hacerlo iterativo. ¿Alguien se atreve?

Page 31: Recursión - dc.uba.ar · Triángulo de Sierpinsky •Construcción: 1. Comenzamos con un triángulo. 2. Lo reducimos a la mitad de la altura y la mitad del lado y lo triplicamos,

Problemas Recursivos

Page 32: Recursión - dc.uba.ar · Triángulo de Sierpinsky •Construcción: 1. Comenzamos con un triángulo. 2. Lo reducimos a la mitad de la altura y la mitad del lado y lo triplicamos,

Dibujando fractales, próximamente…

• Los fractales son objetos cuya estructura se repite a diferentes escalas.

• Se definen mediante simples algoritmos recursivos…

• Cuando sepamos dibujar, dibujaremos fractales usando recursión…