Title: Recursi
1Recursión
2Recursión
- Un árbol se crea recursivamente
3Qué será que algo sea recursivo?
- Por qué un árbol es una estructura recursiva?
- De qué está formado un árbol?,
- y cada elemento?
4Como definirías recursión?
- Esta figura es recursiva, observala bien....
- Cómo las describirías?
- Se repite algún patrón? Cual?
5Funciones recursivas
- Cuando algo se define en términos de partes de sí
mismo más pequeñas o mas simples, se dice que es
recursivo. - La recursión es una técnica algorítmica donde una
función, para cumplir una tarea, se llama a sí
misma como parte de la tarea. - Se dice que una función es recursiva, si la
función se define en términos de si misma o se
llama a sí misma directa o indirectamente.
6Funciones recursivas
- Involucran dos partes principales o casos
- Caso base (condición de terminación). Es el caso
en el cual el problema es lo bastante simple para
ser resuelto directamente. - Caso recursivo. El caso recursivo tiene 3
operaciones - Dividir el problema en una o mas partes simples
o más pequeñas del problema - Llamarse a sí misma, esto es, llamar a la función
recursivamente en cada parte - Combinar las soluciones de las partes como una
solución para el problema
7Método de las 3 preguntas
- Utilizaremos este método para verificar que una
solución recursiva funciona. Para esto la función
debe ser capaz de contestar si a las siguientes
tres preguntas. - La pregunta caso-base Hay una salida no
recursiva de la función y la rutina funciona
correctamente para este caso base? - La pregunta llamador-mas-pequeño Cada llamada
recursiva se refiere a un caso más pequeño del
problema original y tiende al caso base? - La pregunta caso-general suponiendo que las
llamadas recursivas funcionan correctamente,
funciona correctamente toda la función?
8Ejemplo función recursiva
- Recuerdan como se define el factorial de un
número? - n! n(n-1)(n-2)...21 donde ngt0 y 0!1
- Entonces, cómo podemos definir n! en términos
de sí mismo?, es decir de otro factorial. - n! n(n-1)(n-2)...21 ? (n-1)!
- n! n (n-1)!
- (n-1)! (n-1) (n-2)!
- ....
- 2! 21!
- 1! 10!
- 0! 1
9Ejemplo función recursiva
- El factorial de un número ilustra muy bien los
aspectos básicos de un problema recursivo - Se resuelve en términos de sí mismo con un valor
más pequeño n-1 (caso recursivo) - Tiene una condición de terminación (caso base) en
donde se calcula directamente el resultado - 0! 1
- Esto es, tiene un fin!! En algún momento
termina.
10Ejemplo función recursiva
- include ltiostreamgt
- using namespace std
- int fact(int n) //prototipo
- void main()
- int n, f
- cout ltlt "\n Ingresa un numero "
- cin gtgt n
- f fact(n)
- cout ltlt "El factorial de " ltlt n ltlt " es " ltlt f
ltlt endl -
- int fact(int n)
- if (n 0) return 1 //caso BASE
- return (nfact(n-1)) //llamada recursiva
11Cómo le hace?
120 El fact(5) 120
Llamada en el main fact(5)
5!
120
5 4!
24
4 3!
6
3 2!
2
2 1!
1
1 0!
1
Valor de regreso
1
12Recursión v.s. iteración
- // función iterativa
- int fact(int n)
- int f1
- if(n0 n 1)
- return 1
- else
- for(int i1iltn i)
- f i
- return f
-
- //función recursiva
- int fact(int n)
- if(n0 n 1)
- return 1
- return (nfact(n-1))
No cliclos
Uso de cliclos
13Pila de recursión
Memoria
Segmento de código
Segmento de datos
Segmento extra ( o libre)
Segmento de stack (pila)
Segmento del sistema
Está destinado a las variables locales,
parámetros de la función que se está ejecutando y
su valor de regreso
int suma(int x, int y) int z z x
y return z
14Llamada a una función iterativa
- // función iterativa
- int fact(int n)
- int f1
- if(n0 n 1)
- return 1
- for(int i1iltn i)
- f i
- return f
-
- main()
- int f
- f fact(3)
i 1
f 1
n3
Regreso fact(3)
15Ejemplo llamada recursiva
n 0
Regreso 1 fact(0)
n 1
Regreso 2 fact(1)
n 2
Regreso 3 fact(2)
n 3
Regreso fact(3)
- //función recursiva
- int fact(int n)
- if(n0)
- return 1
- return (nfact(n-1))
-
- main()
- int f
- f fact(3)
16Recursividad v.s. Iteración
Recursividad Iteración
Eficiencia en espacio Puede requerir gastos considerables, sobre todo en almacenamiento, ya que debe guardar copias de variables locales Más eficiente
Eficiencia en tiempo El tiempo de una llamada es costosa Los ciclos son directos
Capacidad de computadora Algunos valores son calculados una y otra vez excediendo la capacidad de la computadora antes de obtener una respuesta La eficiencia en tiempo y espacio permiten llegar en algunos casos a soluciones
Claridad en la solución En algunos casos la solución recursiva es más simple y natural. Utiliza menos código Mayor código y más variables lo hacen mas complicado
17Actividad Colaborativa
- En binas hacer un programa que lea un número N y
llame a las funciones recursivas imprime(n) e
imprimeAlReves(n), que imprimen los números desde
N hasta 0 y de 0 hasta N respectivamente. No
usar estructuras de repetición. - void imprime(int n) //prototipo
- void imprimeAlReves(int n) //prototipo
- void main()
- int n
- cout ltlt ingresa un número
- cin gtgt n
- cout ltlt Los números de ltlt n ltlt a 0 son
\n - imprime(n) //llamada
18Actividad grupal (SOLUCION)
- Compartiendo la experiencia
19Actividad Colaborativa
- En binas hacer un programa que resuelva el
problema del máximo común divisor (MCD) de dos
números X y Y. - El MCD, es el mayor entero que divide tanto a X
como a Y. - Escribir una función recursiva que calcule el
MCD - Una versión para resolver este problema del MCD
es el famoso algoritmo de Euclides, una versión
de este algoritmo es la siguiente - Sean m,n ? ?
- Paso 1 Dividir m por n y obtener residuo r ( 0
lt r lt n) - Paso 2 si r 0, entonces la respuesta es n y
el algoritmo termina - Paso 3 caso contrario asignar m ? n y n ? r
volver al paso 1 - Por ejemplo, si m42 y n30 entonces el
mcd(42,30) 6
20Actividad grupal (SOLUCION)
- Compartiendo la experiencia
21Que aprendimos?
22Tipos de recursión
- Existen 4 tipos de recursión que dependen del
número de llamadas a sí misma y el lugar de la
llamada. - Recursión simple Aquella en cuya definición sólo
aparece una llamada recursiva - Ejemplo Función Factorial, imprime, MCD, etc.
- Recursión múltiple Se dá cuando hay más de una
llamada a sí misma dentro del cuerpo de la
función - Ejemplos Función Fibonacci, torres de hanoi,
escape del calabozo, etc.
23Tipos de recursión
- Recursión anidada Aquella en que en algunos de
los argumentos de la llamada recursiva hay una
nueva llamada a si misma. - Ejemplo Función de Ackerman
- Recursión cruzada o indirecta son algoritmos
donde una función provoca una llamada a sí misma
de forma indirecta a través de otras funciones.
Es decir, es aquella en la que una función llama
a otra función y esta a su vez llama a la función
que la llamo. - Ejemplos Función par-impar, juego de las piedras
24Recursión Múltiple
- Cierto matemático italiano de nombre Leonardo de
Pisa, pero mejor conocido como Fibonacci, propuso
el siguiente problema - Suponga que acabamos de comprar una pareja de
conejos adultos. Al cabo de un mes, esa pareja
tiene una pareja de conejitos (un conejo y una
coneja). Un mes después, nuestra primera pareja
tiene otra pareja de conejitos (nuevamente, un
conejo y una coneja) y, al mismo tiempo, sus
primeros hijos se han vuelto adultos. Así que
cada mes que pasa, cada pareja de conejos adultos
tiene una pareja de conejitos, y cada pareja de
conejos nacida el mes anterior se vuelve adulta.
La pregunta es, cuántas parejas de conejos
adultos habrá al cabo de n meses? Para resolver
este problema, llamemos Fn al número de parejas
adultas al cabo de n meses. - La sucesión de números F0 1, F1 1, F2 2, F3
3, F4 5, etc. recibe el nombre de sucesión de
Fibonacci
25Recursión Múltiple
- La serie de Fibonacci puede definirse como
- Fn Fn-1 Fn-2 para n gt 2, F0 F1 1
- Esto define la sucesión
- 1, 1, 2 , 3, 5, 8, 13, 21, 34, 55, ...
- Cómo se define recursivamente?
- int Fib(int n)
- if (n 0 n 1) return 1 //caso base
- return Fib(n-1) Fib(n-2) //lamada recursiva
-
26Recursión anidada
- Función de Ackerman A se define para valores no
negativos M y N del siguiente modo - A(0, n) n 1
- A(m, 0) A (m-1, 1) ? m gt 0
- A(m, n) A (m-1, A(m, n-1)) ? n,m gt 0
27Recursión anidada
- Función de Ackerman
- int Ack (int m, int n)
- if (m 0)
- return n1
- else
- if (n 0)
- return Ack(m-1, 1)
- else
- return Ack(m-1, Ack(m, n-1)) //anidada
-
- cuál es el valor de Ackerman si m1 y n 2?
28Recursión cruzada o indirecta
- Función par-impar
- int par(int)
- int impar(int)
- int main()
- int x
- cout ltlt Introduce un número
- cin gtgt x
- if (par(x))
- cout ltlt x ltlt es par ltlt endl
- else
- cout ltlt x ltlt es impar ltlt endl
- return 0
29Recursión cruzada o indirecta
- int par(int n)
- if ( n 0)
- return 1
- else
- return impar(n-1)
-
- int impar(int n)
- if ( n 0)
- return 0
- else
- return par(n-1)
-
30Actividad colaborativa
- Actividad Trabajen en ternas para resolver el
siguiente problema usando recursión indirecta. - El problema se llama el juego de las piedras.
- El juego inicia con 21 piedras.
- Dos jugadores se turnan para tomar las piedras.
- Cada uno debe tomar al menos 1 piedra y máximo 4
piedras en cada turno. - El jugador que toma la ultima piedra es el
perdedor. - Indicar en cada turno a que jugador le toca
retirar las piedras y al final quien es el
jugador GANADOR.
31Actividad colaborativa
- Colaborativamente Trabajen en equipo,
asegurándose de que comprenden los razonamientos
y formas de implementar de cada integrante.
Ayudence a entender mejor - Criterios para el éxito Cada integrante del
equipo deberá ser capaz de pasar al frente y
explicar al grupo como resolvio recursivamente el
juego de las piedras. - Responsabilidad Individual Cualquier integrante
del equipo podrá ser seleccionad_at_ aleatoriamente
para exponer su programa. Su calificación será la
del equipo.
32Actividad grupal (SOLUCION)
- Compartiendo la experiencia
33Las torres de Hanoi
34Torres de Hanoi
- La leyenda cuenta que en un templo del lejano
oriente, los sacerdotes intentaban mover una pila
de discos de una estaca a otra. - La pila inicial tenía 64 discos ensartados en una
estaca, y estaban acomodados de abajo hacia
arriba en orden de tamaño decreciente.
35Torres de Hanoi
- Los sacerdotes intentan mover la pila de discos
de una estaca hacia una segunda estaca, con las
restricciones de - Mover un solo disco a la vez
- Ningún disco más grande debe colocarse encima de
uno más pequeño - Una tercera estaca está disonible para alojar
temporalmente a los discos
36Torres de Hanoi
- Se supone que, el mundo se arreglará cuando los
sacedortes completen su tarea. - Por lo cual tenemos grandes insentivos para
ayudarles a solucionar el problema - Supongamos que los sacerdotes intentan mover los
discos de la estaca 1 a la 3.
37Torres de Hanoi
1
2
3
- Ejemplo con 3 estacas y 4 discos
38Actividad en equipos
- Desarrollar un algoritmo que obtenga la secuencia
precisa de movimientos, para la transferencia de
todos los discos de una estaca a otra.
39Actividad en equipos
- Si atacamos el problema con recursividad, mover n
discos puede considerarse en términos de mover
sólo n-1 discos, de la siguiente forma - Mover n-1 discos de la estaca 1 a la 2,
utilizando la estaca 3 como área de
almacenamiento temporal - Mover el último disco (el más grande) de la
estaca 1 a la 3 - Mover los n-1 discos de la estaca 2 a la 3,
utilizando la 1 como área de almacenamiento
temporal
40Actividad en equipos
- El proceso termina cuando la última tarea
involucra mover el disco n1, es decir, el caso
base. - Esto se logra moviendo trivialmente el disco, sin
necesidad alguna de área de almacenamiento
temporal.
41Actividad en equipos
- Escribir un programa que resuelva el problema de
las torres de Hanoi. - Utilizar una función recursiva con cuatro
parámetros - El número de discos a mover
- La estaca en la que inicialmente están ensartados
los discos - La estaca a la que la pila de discos se moverá
- La estaca que se utilizará como área de
almacenamiento temporal
42Actividad en equipos
- El programa deberá desplegar las instrucciones
precisas que seguirá para mover una pila de
discos desde la estaca inicial hasta la estaca de
destino. - Ejemplo
- Para mover una pila de tres discos de la estaca 1
a la 3, el programa deberá desplegar la siguiente
serie de movimientos - 1-gt3
- 1-gt2
- 3-gt2
- 1-gt3
- 2-gt1
- 2-gt3
- 1-gt3
43Actividad grupal (SOLUCION)
- Compartiendo la experiencia
44Que aprendimos?
45Actividad Colaborativa
- Actividad Reacción en cadena
- En un laboratorio de minerales se están
realizando experimentos para predecir las
reacciones en cadena que se puede dar al hacer
explotar una roca de tamaño N, con una bomba de
capacidad B. - El experimento es el siguiente dados 2 números N
y B, tal que B lt N, cuando N explota se parte en
dos números N1 N / B y N2 N ( N / B). - B produce una reacción en cadena si N1 o N2 son
mayores que B. Esto es, si los pedazos
resultantes son mayores que la bomba estos
también explotan partiéndose nuevamente en dos
pedazos, según el criterio anterior. - Este proceso se repite hasta que todos los
pedazos resultantes (N1 y N2) sean menores o
iguales a B.
46Reacción en cadena
- Ejemplo
- Supongamos que N 10 y la bomba B 3.
- Al aplicar la bomba B, N se parte inicialmente en
dos pedazos N1 10/3 3 y N2 10-10/3 7. - Como N27 es mayor que la bomba, se produce la
reacción en cadena, y N2 también estalla en dos
pedazos 7/3 2 y 7-(7/3) 5. - Nuevamente el segundo pedazo es mayor que la
bomba por lo que también deberá estallar en dos
pedazos 5/3 y 5-(5/3). - El proceso se repite hasta que todos los pedazos
sean menores o iguales a 3 (la bomba). - Al final, el bloque N10, con la bomba igual a
3, habrá estallado en los pedazos 3, 2, 1,1 y 3.
47Reacción en cadena
- Escribir una función recursiva, que dado una roca
de tamaño N y una bomba de capacidad B, obtenga
la reacción en cadena que resulta de explotar la
roca con la bomba dada. - La función debe imprimir todos los pedazos que
resultan al explotar N usando B.
48Actividad grupal (SOLUCION)
- Compartiendo la experiencia
49Que aprendimos?