Está en la página 1de 40

Recursividad

ESTRUCTURA DE DATOS
Qu es la recursividad?
La recursividad es un concepto fundamental en
matemticas y en computacin.
Es una alternativa diferente para implementar
estructuras de repeticin (ciclos).
Se dice que una funcin es recursiva cuando se define
en funcin de si misma.
No todas la funciones pueden llamarse a si mismas,
deben estar diseadas especialmente para que sean
recursivas, de otro modo podran conducir a bucles
infinitos, o a que el programa termine
inadecuadamente.

Qu es la recursividad?
Se puede usar en toda situacin en la cual la solucin pueda ser
expresada como una secuencia de movimientos, pasos o
transformaciones gobernadas por un conjunto de reglas no
ambiguas.
Cuando se llama a una funcin, se crea un nuevo juego de
variables locales, de este modo, si la funcin hace una llamada a
si misma, se guardan sus variables y parmetros.
La nueva instancia de la funcin trabajar con su propia copia
de las variables locales, cuando esta segunda instancia de la
funcin retorna, recupera las variables y los parmetros
anteriores y contina la ejecucin en el punto en que haba sido
llamada.

Algoritmo Recursivo
Un algoritmo recursivo es un algoritmo que
expresa la solucin de un problema en
trminos de una llamada a s mismo. La
llamada a s mismo se conoce como llamada
recursiva o recurrente
Recursin Directa e Indirecta
Cuando un procedimiento o funcin incluye
una llamada a s mismo se conoce como
Recursin Directa.

Cuando un procedimiento o funcin llama a
otro procedimiento y ste causa que el
procedimiento original sea invocado, se
conoce como Recursin Indirecta.


6
Ejemplo: Factorial
Para calcular el Factorial de 4 sea 4!, se puede utilizar
un proceso iterativo o uno recursivo.

De manera iterativa:

4! = 1 * 2 * 3 * 4 = 24

Solucin Factorial Iterativa (No Recursiva)
int factorial (int n) {
int fact = 1;
for (int i = 1; i <= n; i++)
fact = fact * i;
return fact;
}
Anlisis Funcin Factorial Recursiva
Para definir 4! de manera recursiva se tiene que
definir en trminos de factorial, es decir, en la
definicin (parte derecha de la igualdad) tiene
que aparecer el factorial.
De manera recursiva:

4! = 4 * 3!



Seguimiento Factorial
Observacines
Se observa que en el clculo de 4! fue muy
importante el hecho de que 0! es igual a 1
Qu hubiera pasado si 0! se calcular
como se calcul los dems factoriales?
Nunca se hubiera terminado el proceso, o
sea, tendramos un proceso infinito.

Fin de la Recursividad
Entonces, toda definicin recursiva
debe tener, al menos, una definicin
base.
Esta definicin base proporciona la
solucin de salida de la
recursividad.

Explicacin Factorial
Para calcular 4!, 3!, 2! y 1! Se uso una
definicin recursiva, por lo que se estuvo
entrando en recursin y cuando se alcanz
la definicin base se comenz a salir de
recursin.

Diseo e implementacin de funciones recursivas
La solucin recursiva a un problema de repeticin se
obtiene respondiendo tres preguntas:

1) La pregunta Caso-Base: Existe al menos una salida
no recursiva o casos bases del subalgoritmo?
Adems, el subalgoritmo funciona correctamente
para ella?
2) La pregunta Ms-pequeo: Cada llamada recursiva
se refiere a un caso ms pequeo del problema
original?.No hay recursin infinita?
3) La pregunta Caso-General: es correcta la solucin
en aquellos casos no base?
Caso Factorial: Preguntas
1. En el clculo de factorial, la pregunta sera:
cul es el nmero ms pequeo para el que se
puede obtener factorial?


2. Cmo se resuelve un caso general del
problema, sabiendo que ya se tiene el caso
anterior ms pequeo?



Definicin Recursiva
De tal forma que, la definicin recursiva de n! es:
a) n! = 1 si n = 0 Definicin base
b) n! = n * (n 1)! si n > 0 Definicin recursiva


Diagrama de Flujo Recursivo
Alcances
Dependiendo del problema que
implemente el mdulo ste diagrama se
puede ver modificado.

Por ejemplo, si tiene ms de una
definicin base, si tiene ms de una
definicin recursiva o si en la solucin
recursiva tiene que realizar alguna
operacin antes de volverse a ejecutar o
no.

Por qu escribir programas recursivos?
Son mas cercanos a la descripcin
matemtica.
Generalmente mas fciles de analizar
Se adaptan mejor a las estructuras de datos
recursivas.
Los algoritmos recursivos ofrecen
soluciones estructuradas, modulares y
elegantemente simples.
Cmo escribir una funcin recursiva?
<tipo_de_regreso><nom_fnc> (<param>){
[declaracin de variables]
[condicin de salida]
[instrucciones]
[llamada a <nom_fnc> (<param>)]
return <resultado>
}

Implementacin de la funcin recursiva Factorial
La importancia del return en una funcin recursiva
1ro.
Hace que la funcin tome el valor de
lo que se est regresando. En
factorial:

si n == 0 factorial = 1
sino factorial= n * factorial(n 1)


La importancia del return en una funcin recursiva
2do.
Termina la ejecucin de la funcin, regresando
el control de la ejecucin al mdulo en que fue
llamada (a la instruccin que se debe ejecutar
despus de que la funcin fue llamada).

Conclusiones
La solucin recursiva de un problema se
obtiene respondiendo dos preguntas:
cmo se resuelve el caso ms pequeo?
y cmo se resuelve un caso general,
sabiendo que ya se tiene el caso anterior
ms pequeo?

Para implementar soluciones recursivas
se utilizan los mdulos: las funciones (int,
float, double, etc.).

Conclusiones
El return de una funcin realiza dos operaciones:
asigna a la funcin el valor que regresa y termina
la ejecucin de la misma, regresando el control a la
siguiente instruccin que se tiene que realizar,
despus de la llamada a la funcin.



Ejercicio
Considere la siguiente ecuacin recurrente:

a
n
= a
n-1
+ 2n
a
0
= 1

Escribe el algoritmo recursivo de la solucin.


BACKTRACKING
El backtracking o vuelta atrs es una tcnica algortmica
de resolucin general de problemas mediante una
bsqueda sistemtica de soluciones.

Se descompone la tarea a realizar en tareas parciales y
se prueba sistemticamente cada una de estas, que a su
vez se descompondrn en subtareas.

Cuando al elegir una tarea se comprueba que no lleva a
una solucin, se debe volver atrs, y probar con otra.

Se utilizan para resolver problemas para los que no
existe un algoritmo eficiente para resolverlos. Esta
tcnica suele ser muy ineficiente.
Esquema General del Algoritmo
El backtracking bsicamente es un recorrido hasta el fondo de un rbol.

A este tipo de bsqueda se le conoce como Bsqueda Primero en
Profundidad o DFS (Depth First Search).
Caractersticas

El algoritmo de Vueltra atrs hace un
recorrido en profundidad en un arbol.

El arbol se construye en memoria por eso se
dice que es implicito.

El recorrido en profundidad regresa sobre
sus pasos (retrocede) cada vez que
encuentra un camino por el que no debe o no
puede continuar.
Dimensiones del rbol Implcito

La Altura : Hay k posibles decisiones que
debemos tomar para llegar a una solucin.

La Anchura: Cada decisin debe tomarse de
un conjunto de alternativas distintas
(dominio).
Dimensiones del rbol Implcito
Cuando queramos aplicar esta tcnica debemos primero
imaginarnos como ser el rbol que vamos a recorrer.
Esquema General
Dado que en todo algoritmo de backtracking hay que recorrer un arbol y en
cada paso se necesita comprobar todas las alternativas posibles y luego
recorrerlas una a una, es que podemos pensar en el siguiente esquema:

1. Si se llego a la mxima profundidad del rbol, entonces mostrar la solucin (caso
base).
2. Sino, entonces
2.1 Construir cada candidato
2.2 Para cada candidato aadirlo a la solucin y llamar
recursivamente a la funcin con el nivel siguiente de
profundidad.

Lo que cambia en cada problema es:
1) La forma de generar cada candidato.
2) Los tipos de datos.
3) El numero de parmetros de la funcin.
4) Aadirle condiciones adicionales propias del problema.
5) Aadirle condiciones adicionales para reducir el rbol.
Problema N - Reinas
Problema N - Reinas
Problema del Laberinto
El problema del laberinto podemos plantearlo de la siguiente manera:

Tenemos un laberinto representado por una matriz cuadrada de
casillas, las cuales pueden estar ocupadas o no.

Desde cada casilla nos podremos mover a cualquiera de sus cuatro
adyacentes, siempre y cuando no estn ocupadas.

El problema consiste en encontrar un camino (si existe) desde la
casilla origen, ubicada en la esquina superior izquierda, a la casilla
destino, que a su vez estar en la esquina inferior derecha.

Problema del Laberinto
El algoritmo bsicamente funciona as:

1. Comprueba si la casilla donde est actualmente es la salida, si es as, sale de la
funcin indicando que se ha hallado la solucin; de lo contrario pasa al siguiente paso.
2. Si es posible visita las casilla de arriba llamando recursivamente a la misma funcin.
Comienza nuevamente en el paso 1.
3. Si no es posible visitar o hallar la salida por arriba intenta con la casilla de la derecha.
Comienza nuevamente en el paso 1.
4. Si no es posible visitar o hallar la salida por la derecha intenta con la casilla de abajo.
Comienza nuevamente en el paso 1.
5. Si no es posible visitar o hallar la salida por abajo intenta con la casilla de la izquierda.
Comienza nuevamente en el paso 1.
6. Si no se encontr la salida por ninguna de las cuatros casillas vecinas, entonces sale
de la funcin indicando que no existe salida del laberinto por la casilla actual.

Alternativas: arriba, derecha, izquierda y abajo
Subtarea: actualizar la posicin del recorrido
Solucin: llegar a la posicin de salida
Solucion Backtracking : Problema del Laberinto
int resolver(int f, int c ) { //resolver desde f,c
lab[f][c]='*';
imprimir();

if( f == 0 || c ==0 || f==FIL-1 || c == COL-1 ){//estamos al borde
return 1; //exito! encontramos la salida
}

//Probamos todas las alternativas posibles
if( lab[f-1][c]==' '){//si podemos avanzar hacia arriba
if( resolver(f-1,c)==1 )
return 1;
}
if( lab[f][c+1]==' '){//si podemos avanzar hacia derecha
if( resolver(f,c+1)==1 )
return 1;
}

Solucion Backtracking : Problema del Laberinto
if( lab[f+1][c]==' '){//si podemos avanzar hacia abajo
if( resolver(f+1,c)==1 )
return 1;
}
if( lab[f][c-1]==' '){//si podemos avanzar hacia izquierda
if( resolver(f,c-1)==1 )
return 1;
}
lab[f][c]=' ';
return 0; //Se queda encerrado, no hay salida
}
int main(){
imprimir();
resolver(1,1);

}
Conclusin
El backtracking es un esquema algortmico que nos va a
permitir resolver una gran variedad de tipos de problemas,
pero, por trmino medio, es sumamente costoso (en
cuanto a complejidades temporales se refiere) debido al
tamao que adoptan sus espacios de bsqueda.

Aplicndole una serie de mejoras podremos conseguir que
dicho espacio mengue para reducir en lo posible las altas
complejidades que suelen tener.

También podría gustarte