Lester Sánchez Díaz
Universidad de La Habana
Recursión (Recursividad)
Procedimiento de resolver un problema complejo
reduciéndolo en uno o más subproblemas
1. Con la misma estructura que el problema original
2. Más simples de resolver que el problema original
A su vez cada subproblema se divide, usando el
mismo procedimiento, en subproblemas aún más
simples
Los subproblemas llegarán a ser tan simples que no
hará falta dividirlos para resolverlos
La solución del problema inicial se obtiene
combinando las soluciones de cada subproblema
Programación, UH 2013-2014

2
Recursividad en la vida cotidiana
• Recorrer un trayecto de un origen a un destino
‐ Dar un paso desde el origen hacia el destino
‐ Dar (n-1) pasos hacia el destino desde el nuevo origen

• Subir una escalera
‐ Subir un escalón
‐ Subir los (n-1) escalones restantes

• Comerse una pizza (o cualquier otra cosa)
‐ Comerse una porción
‐ Comerse las (n-1) porciones restantes
Programación, UH 2013-2014

3
Recursividad en la vida cotidiana
Distribuir productos que se importan al país para la
venta a la población en la red minorista de mercados
Ejemplo: Distribuir 1000 toneladas de arroz para
1000 mercados (1 tonelada para cada uno)
Distribuir directamente desde el puerto a los mercados no resulta práctico

• Dividir el total en partes según la cantidad de provincias
• Enviar a cada provincia una parte, y que cada provincia se
encargue de la distribución de su parte
• A su vez, cada provincia divide su parte y envía nuevas
porciones a sus municipios
• Luego cada municipio vuelve a dividir su parte y la
distribuye a cada mercado minorista
Programación, UH 2013-2014

4
Problema de distribución de
mercancía
PAIS

1000 ton

100 ton

2

1

...

10

PROVINCIA

MUNICIPIO

10 ton
1 ton

...

2

1

...
1

1

10

10

MERCADO

Los subproblemas son cada vez más pequeños, y llega un
momento en que no hace falta dividirlos para resolverlos
Programación, UH 2013-2014

5
Estructura general de un algoritmo
recursivo
Algoritmo RECURSIVO
IF (Problema Simple)

Condición
de Parada

Caso Base

Resolverlo directamente
ELSE

Resolver de
manera
recursiva

Dividir en subproblemas P1, P2, ..., Pn
Resolver(P1); Resolver(P2); ... Resolver(Pn)
Combinar las soluciones de cada subproblema

Programación, UH 2013-2014

6
Programación, UH 2013-2014

7
Algoritmo para guardar las Matrioskas
CASO BASE
SUBPROBLEMA

6

5

4

1 Matrioska
Guardar n-1
Matrioskas

3 2 1

Guardar Matrioskas (n)
IF (n > 1)
Abrir Matrioska n

Subproblema

Guardar Matrioskas (n-1)
Colocar n-1 dentro de n
Cerrar Matrioska n

Programación, UH 2013-2014

8
Ejemplo: Factorial
Caso Base

1, n = 0
FACT(n)

Definición
Recursiva
de Factorial

n * FACT(n-1) , n > 0

FACT(5) = 1 * 2 * 3 * 4 * 5 = 120
FACT(5) = 5 * FACT(4)

5*4*3*2*1*1
4*3*2*1*1

4 * FACT(3)

3*2*1*1

3 * FACT(2)
División en
subproblemas

2 * FACT(1)
1 * FACT(0)

Programación, UH 2013-2014

120

1

Solución del
problema original

2*1*1
1*1

Combinar
soluciones de los
subproblemas

9
Ejemplo: Factorial
Iterativo

Recursivo

Caso Base

Subproblema
Programación, UH 2013-2014

Converge al
caso base

10
Torres de Hanoi
Tenemos en una estaca una pila de discos de mayor a menor y queremos
pasarlos a la tercera estaca usando la del medio como auxiliar, pero solo
se puede mover un disco a la vez y nunca se puede poner un disco de
mayor tamaño sobre uno menor
ORIGEN

AUXILIAR

DESTINO

¿Cómo mover cualquier cantidad de discos?

Programación, UH 2013-2014

11
Torres de Hanoi
CASO BASE
Mover 1 disco de ORIGEN a DESTINO

ORIGEN

Programación, UH 2013-2014

AUXILIAR

DESTINO

12
Torres de Hanoi
SUBPROBLEMA
Si la cantidad de discos es mayor que 1
1. Mover (n-1) discos de ORIGEN a AUXILIAR
2. Mover el disco que queda en ORIGEN para DESTINO
3. Mover los (n-1) de AUXILIAR a DESTINO

Programación, UH 2013-2014

13
Torres de Hanoi
ORIGEN

AUXILIAR

DESTINO

Subproblema

Caso Base

Programación, UH 2013-2014

Subproblema

14
Torres de Hanoi
Caso Base de la recursión

Converge al caso base

Converge al caso base

Programación, UH 2013-2014

15
DEMO
Torres de Hanoi

Intente hacerlo sin recursividad

Programación, UH 2013-2014

16
Fractales: Copo de Nieve

Construcción de un fractal con forma de Copo de Nieve

Figura que a distintas escalas presenta la misma forma geométrica
Programación, UH 2013-2014

17
Fractales: Triángulo de Sierpinski

Programación, UH 2013-2014

18
Ejemplo: Fractales

Programación, UH 2013-2014

19
Ejemplo: Fractales

Caso Base

Resolver
subproblema

Programación, UH 2013-2014

20
DEMO
Fractales

Programación, UH 2013-2014

21
Ejemplo: Fibonacci
FIB(n)

0,
n=0
1,
n=1
FIB(n-1) + FIB(n-2),

Fib(5)
Fib(4)
Fib(3)
Fib(2)

n>1

Fib(1)

Fib(0)
Fib(1)

0, 1, 1, 2, 3, 5, 8, 13, 21, 34, 55, 89, 144, …
FIB(5) = FIB(4) + FIB(3)

Fib(2)
Fib(1)

Se repite el cálculo
innecesariamente

Fib(0)
Fib(3)

Converge al
caso base

Fib(2)

Fib(1)

Converge al caso base
Intente buscar el término 50 con este algoritmo y vea
cuánto UH 2013-2014
Programación,demora. Pruebe con la variante interativa.

Fib(0)
Fib(1)
Fib(2)
Fib(1)
Fib(0)
Reglas para aplicar la
Recursividad
1. Descomponer el problema original en
subproblemas más simples del mismo tipo
2. Resolver los subproblemas, usando el mismo
método, y combinar sus soluciones para
generar la solución del problema original
3. La subdivisión en subproblemas siempre debe
converger a un caso base que se pueda
resolver sin necesidad de subdividir
Confiar en la recursividad!
Programación, UH 2013-2014

24
Programación, UH 2013-2014

25
Clase Práctica
Calcular una base elevada a una potencia
2^3 = 2 * 2 * 2 = 8
6^4 = 6 * 6 * 6 * 6 = 1296
long Potencia(int base, int exponente)
Multiplicar dos números sin utilizar el operador *
21 * 3 = 21 + 21 + 21 = 63
2 * 24 = 24 + 24 = 48
Su solución debe hacer el menor número posible de llamados
recursivos
long Producto(int a, int b)

Programación, UH 2013-2014

26
Clase Práctica
Determinar si un número es SuperPrimo.
Un número SuperPrimo si es primo y además al quitarle la
última cifra sigue siendo SuperPrimo. Un número primo de
una cifra se considera SuperPrimo.
bool EsSuperPrimo(int n)
Implemente un método que determine si una cadena es
palíndromo
bool EsPalindromo(string s)

Programación, UH 2013-2014

27
Clase Práctica
Implemente un método int TerminoWirth(int n) que
devuelva el término n-ésimo perteneciente al conjunto de
Wirth.

Conjunto de Wirth (W)
1 W
Si x

W

Programación, UH 2013-2014

2x + 1
3x + 1

W
W

28
Clase Práctica (Lab)
Programe un método que permita al usuario escribir en la
Consola tantas líneas como quiera. Cuando el usuario de
“ENTER” sin haber escrito algún texto, debe imprimir cada
una de las líneas que escribió el usuario, pero en orden
inverso.
No debe usar ninguna estructura de datos para almacenar
todas las líneas que escribe el ususario.

Modifique el ejemplo de fractales visto en la clase para
generar el Triángulo de Sierpinski.
Programe un algoritmo para generar un fractal con forma de
copo de nieve.
Programación, UH 2013-2014

29

Recursividad

  • 1.
  • 2.
    Recursión (Recursividad) Procedimiento deresolver un problema complejo reduciéndolo en uno o más subproblemas 1. Con la misma estructura que el problema original 2. Más simples de resolver que el problema original A su vez cada subproblema se divide, usando el mismo procedimiento, en subproblemas aún más simples Los subproblemas llegarán a ser tan simples que no hará falta dividirlos para resolverlos La solución del problema inicial se obtiene combinando las soluciones de cada subproblema Programación, UH 2013-2014 2
  • 3.
    Recursividad en lavida cotidiana • Recorrer un trayecto de un origen a un destino ‐ Dar un paso desde el origen hacia el destino ‐ Dar (n-1) pasos hacia el destino desde el nuevo origen • Subir una escalera ‐ Subir un escalón ‐ Subir los (n-1) escalones restantes • Comerse una pizza (o cualquier otra cosa) ‐ Comerse una porción ‐ Comerse las (n-1) porciones restantes Programación, UH 2013-2014 3
  • 4.
    Recursividad en lavida cotidiana Distribuir productos que se importan al país para la venta a la población en la red minorista de mercados Ejemplo: Distribuir 1000 toneladas de arroz para 1000 mercados (1 tonelada para cada uno) Distribuir directamente desde el puerto a los mercados no resulta práctico • Dividir el total en partes según la cantidad de provincias • Enviar a cada provincia una parte, y que cada provincia se encargue de la distribución de su parte • A su vez, cada provincia divide su parte y envía nuevas porciones a sus municipios • Luego cada municipio vuelve a dividir su parte y la distribuye a cada mercado minorista Programación, UH 2013-2014 4
  • 5.
    Problema de distribuciónde mercancía PAIS 1000 ton 100 ton 2 1 ... 10 PROVINCIA MUNICIPIO 10 ton 1 ton ... 2 1 ... 1 1 10 10 MERCADO Los subproblemas son cada vez más pequeños, y llega un momento en que no hace falta dividirlos para resolverlos Programación, UH 2013-2014 5
  • 6.
    Estructura general deun algoritmo recursivo Algoritmo RECURSIVO IF (Problema Simple) Condición de Parada Caso Base Resolverlo directamente ELSE Resolver de manera recursiva Dividir en subproblemas P1, P2, ..., Pn Resolver(P1); Resolver(P2); ... Resolver(Pn) Combinar las soluciones de cada subproblema Programación, UH 2013-2014 6
  • 7.
  • 8.
    Algoritmo para guardarlas Matrioskas CASO BASE SUBPROBLEMA 6 5 4 1 Matrioska Guardar n-1 Matrioskas 3 2 1 Guardar Matrioskas (n) IF (n > 1) Abrir Matrioska n Subproblema Guardar Matrioskas (n-1) Colocar n-1 dentro de n Cerrar Matrioska n Programación, UH 2013-2014 8
  • 9.
    Ejemplo: Factorial Caso Base 1,n = 0 FACT(n) Definición Recursiva de Factorial n * FACT(n-1) , n > 0 FACT(5) = 1 * 2 * 3 * 4 * 5 = 120 FACT(5) = 5 * FACT(4) 5*4*3*2*1*1 4*3*2*1*1 4 * FACT(3) 3*2*1*1 3 * FACT(2) División en subproblemas 2 * FACT(1) 1 * FACT(0) Programación, UH 2013-2014 120 1 Solución del problema original 2*1*1 1*1 Combinar soluciones de los subproblemas 9
  • 10.
  • 11.
    Torres de Hanoi Tenemosen una estaca una pila de discos de mayor a menor y queremos pasarlos a la tercera estaca usando la del medio como auxiliar, pero solo se puede mover un disco a la vez y nunca se puede poner un disco de mayor tamaño sobre uno menor ORIGEN AUXILIAR DESTINO ¿Cómo mover cualquier cantidad de discos? Programación, UH 2013-2014 11
  • 12.
    Torres de Hanoi CASOBASE Mover 1 disco de ORIGEN a DESTINO ORIGEN Programación, UH 2013-2014 AUXILIAR DESTINO 12
  • 13.
    Torres de Hanoi SUBPROBLEMA Sila cantidad de discos es mayor que 1 1. Mover (n-1) discos de ORIGEN a AUXILIAR 2. Mover el disco que queda en ORIGEN para DESTINO 3. Mover los (n-1) de AUXILIAR a DESTINO Programación, UH 2013-2014 13
  • 14.
    Torres de Hanoi ORIGEN AUXILIAR DESTINO Subproblema CasoBase Programación, UH 2013-2014 Subproblema 14
  • 15.
    Torres de Hanoi CasoBase de la recursión Converge al caso base Converge al caso base Programación, UH 2013-2014 15
  • 16.
    DEMO Torres de Hanoi Intentehacerlo sin recursividad Programación, UH 2013-2014 16
  • 17.
    Fractales: Copo deNieve Construcción de un fractal con forma de Copo de Nieve Figura que a distintas escalas presenta la misma forma geométrica Programación, UH 2013-2014 17
  • 18.
    Fractales: Triángulo deSierpinski Programación, UH 2013-2014 18
  • 19.
  • 20.
  • 21.
  • 22.
    Ejemplo: Fibonacci FIB(n) 0, n=0 1, n=1 FIB(n-1) +FIB(n-2), Fib(5) Fib(4) Fib(3) Fib(2) n>1 Fib(1) Fib(0) Fib(1) 0, 1, 1, 2, 3, 5, 8, 13, 21, 34, 55, 89, 144, … FIB(5) = FIB(4) + FIB(3) Fib(2) Fib(1) Se repite el cálculo innecesariamente Fib(0) Fib(3) Converge al caso base Fib(2) Fib(1) Converge al caso base Intente buscar el término 50 con este algoritmo y vea cuánto UH 2013-2014 Programación,demora. Pruebe con la variante interativa. Fib(0) Fib(1) Fib(2) Fib(1) Fib(0)
  • 23.
    Reglas para aplicarla Recursividad 1. Descomponer el problema original en subproblemas más simples del mismo tipo 2. Resolver los subproblemas, usando el mismo método, y combinar sus soluciones para generar la solución del problema original 3. La subdivisión en subproblemas siempre debe converger a un caso base que se pueda resolver sin necesidad de subdividir Confiar en la recursividad! Programación, UH 2013-2014 24
  • 24.
  • 25.
    Clase Práctica Calcular unabase elevada a una potencia 2^3 = 2 * 2 * 2 = 8 6^4 = 6 * 6 * 6 * 6 = 1296 long Potencia(int base, int exponente) Multiplicar dos números sin utilizar el operador * 21 * 3 = 21 + 21 + 21 = 63 2 * 24 = 24 + 24 = 48 Su solución debe hacer el menor número posible de llamados recursivos long Producto(int a, int b) Programación, UH 2013-2014 26
  • 26.
    Clase Práctica Determinar siun número es SuperPrimo. Un número SuperPrimo si es primo y además al quitarle la última cifra sigue siendo SuperPrimo. Un número primo de una cifra se considera SuperPrimo. bool EsSuperPrimo(int n) Implemente un método que determine si una cadena es palíndromo bool EsPalindromo(string s) Programación, UH 2013-2014 27
  • 27.
    Clase Práctica Implemente unmétodo int TerminoWirth(int n) que devuelva el término n-ésimo perteneciente al conjunto de Wirth. Conjunto de Wirth (W) 1 W Si x W Programación, UH 2013-2014 2x + 1 3x + 1 W W 28
  • 28.
    Clase Práctica (Lab) Programeun método que permita al usuario escribir en la Consola tantas líneas como quiera. Cuando el usuario de “ENTER” sin haber escrito algún texto, debe imprimir cada una de las líneas que escribió el usuario, pero en orden inverso. No debe usar ninguna estructura de datos para almacenar todas las líneas que escribe el ususario. Modifique el ejemplo de fractales visto en la clase para generar el Triángulo de Sierpinski. Programe un algoritmo para generar un fractal con forma de copo de nieve. Programación, UH 2013-2014 29