La descarga está en progreso. Por favor, espere

La descarga está en progreso. Por favor, espere

Recursividad.

Presentaciones similares


Presentación del tema: "Recursividad."— Transcripción de la presentación:

1 Recursividad

2 Matrushka La Matrushka es una artesanía tradicional rusa. Es una muñeca de madera que contiene otra muñeca más pequeña dentro de sí. Ésta muñeca, también contiene otra muñeca dentro. Y así, una dentro de otra.

3 Definición de Recursividad
La recursividad es un concepto fundamental en matemáticas y en computación. Es una alternativa diferente para implementar estructuras de repetición (ciclos). Los métodos se hacen llamadas recursivas. Primero debemos decir que la recursividad no es una estructura de datos, sino que es una técnica de programación que nos permite que un bloque de instrucciones se ejecute n veces. Reemplaza en ocasiones a estructuras repetitivas. Se utiliza principalmente en la inteligencia artificial, manejo de fractales.

4 Definición de Recursividad
La recursividad es un concepto difícil de entender en principio, pero luego de analizar diferentes problemas aparecen puntos comunes. En Java los métodos pueden llamarse a sí mismos. Si dentro de un método existen instrucciones para la llamada a sí mismo decimos que el método es recursivo. La solución iterativa es fácil de entender. Utiliza una variable para acumular los productos y obtener la solución. En la solución recursiva se realizan llamadas al propio método con valores de n cada vez más pequeños para resolver el problema.

5 Definición de Recursividad
Cuando un método se llama a sí mismo, se asigna espacio en la pila para las nuevas variables locales y parámetros. Al volver de una llamada recursiva, se recuperan de la pila las variables locales y los parámetros antiguos y la ejecución se reanuda en el punto de la llamada al método.

6 Definición de Recursividad
Cada vez que se produce una nueva llamada al método se crean en memoria de nuevo las variables y comienza la ejecución del nuevo método. Para entender el funcionamiento de la recursividad, podemos pensar que cada llamada supone hacerlo a un método diferente, copia del original, que se ejecuta y devuelve el resultado a quien lo llamó. Hay que tener en cuenta que cada vez que se llama a una función se reservan 4 bytes de la memoria que se liberarán cuando finaliza su ejecución.

7 Función recursiva Las funciones recursivas se componen de:
Caso base: una solución simple para un caso particular (puede haber más de un caso base). Siempre ha de existir uno o más casos en los que los valores de los parámetros de entrada permitan al método devolver un resultado directo. Estos casos también se conocen como solución trivial del problema.

8 Función recursiva Caso recursivo: una solución que involucra volver a utilizar la función original, con parámetros que se acercan más al caso base. Los pasos que sigue el caso recursivo son los siguientes: El procedimiento se llama a sí mismo. El problema se resuelve, tratando el mismo problema pero de tamaño menor. La manera en la cual el tamaño del problema disminuye asegura que el caso base eventualmente se alcanzará.

9 Función recursiva Los procesos recursivos suelen ocupar más memoria y tardar un poquito más que los iterativos porque cuando el compilador llama a una subrutina guarda todas las variables locales. La recursividad y la iteración (ejecución en bucle) están muy relacionadas, cualquier acción que pueda realizarse con la recursividad puede realizarse con iteración y viceversa. Tanto la iteración como la recursión se basan en una estructura de control: - La iteración utiliza una estructura repetitiva - La recursión utiliza una estructura de selección.

10 Función recursiva Ventajas de la Recursión
Soluciones simples, claras Soluciones elegantes. Soluciones a problemas complejos. Desventajas de la Recursión: INEFICIENCIA Sobrecarga asociada con las llamadas a subalgoritmos. Una simple llamada puede generar un gran numero de llamadas recursivas. El valor de la recursividad reside en el hecho de que se puede usar para resolver problemas sin fácil solución iterativa. La ineficiencia inherente de algunos algoritmos recursivos. La recursividad se debe usar cuando sea realmente necesaria, es decir, cuando no exista una solución iterativa simple.

11 Función recursiva La recursividad es especialmente apropiada cuando el problema a resolver (por ejemplo calculo del factorial de un número) o la estructura de datos a procesar (por ejemplo los árboles) tienen una clara definición recursiva. No se debe utilizar la recursión cuando la iteración ofrece una solución obvia. Cuando el problema se pueda definir mejor de una forma recursiva que iterativa lo resolveremos utilizando recursividad. Para medir la eficacia de un algoritmo recursivo se tienen en cuenta tres factores: Tiempo de ejecución Uso de memoria Legibilidad y facilidad de comprensión

12 Función recursiva Las soluciones recursivas suelen ser más lentas que las iterativas por el tiempo empleado en la gestión de las sucesivas llamadas a los métodos. Además consumen más memoria ya que se deben guardar los contextos de ejecución de cada método que se llama. A pesar de estos inconvenientes, en ciertos problemas, la recursividad conduce a soluciones que son mucho más fáciles de leer y comprender que su correspondiente solución iterativa. En estos casos una mayor claridad del algoritmo puede compensar el coste en tiempo y en ocupación de memoria. De todas maneras, numerosos problemas son difíciles de resolver con soluciones iterativas, y sólo la solución recursiva conduce a la resolución del problema (por ejemplo, Torres de Hanoi o recorrido de Árboles).

13 Ejemplo de recursividad
Implementar un método recursivo que muestre los números desde 1 hasta n, recibiendo un parámetro de tipo entero y que luego llame en forma recursiva con el valor del parámetro menos 1.

14 Ejemplo de recursividad
public class Recursividad { public void imprimir(int x) { if (x>0) { //Caso base imprimir(x-1); //Llamada recursiva acercándose al caso base System.out.println(x); //Imprime los valores } public static void main(String[] args) { Recursividad re=new Recursividad(); //Instanciación de la clase re.imprimir(4); //Llamada al método con argumento

15 Ejemplo de recursividad
4 3 4 2 3 4 1 2 3 4

16 Ejemplo: factorial Escribe un programa que calcule el factorial (!) de un entero no negativo. He aquí algunos ejemplos de factoriales: 0! = 1 1! = 1 2! =  2 * 1 3! = 6  3 * 2 * 1 4! = 24  4 * 3 * 2 * 1 5! = 120  5 * 4 * 3 * 2 * 1

17 Ejemplo: factorial (iterativo - repetetitivo)
import javax.swing.JOptionPane; public class Factorial2 { public static void main(String[] args) { int n=0,c=1,fact=1; n=Integer.parseInt(JOptionPane.showInputDialog("Ingrese el valor de n: ")); if ((n==0) || (n==1)) { fact=1; } else { while(c<=n) { fact=fact*c; c=c+1; JOptionPane.showMessageDialog(null, "El factorial es: "+ fact); System.exit(0);

18 Ejemplo: factorial (recursivo)
public class Factorial { int factorial(int fact) { if (fact>0) { int valor=fact * factorial(fact-1); return valor; } else return 1; } public static void main(String[] ar) { Factorial re=new Factorial(); int f=re.factorial(4); System.out.println("El factorial de 4 es "+f);

19 Ejemplo: A continuación se puede ver la secuencia de factoriales.
0! = 1 1! = 1 2! = 2 3! = 6 4! = 24 5! = 120 ... N! = = 1 * = 1 * 0! = 2 * = 2 * 1! = 3 * 2 * 1 = 3 * 2! = 4 * 3 * 2 * 1 = 4 * 3! = 5 * 4 * 3 * 2 * 1 = 5 * 4! = N * (N – 1)!

20 Solución 1 si N = 0 (base) N ! = N * (N – 1) ! si N > 0 (recursión)
Aquí podemos ver la secuencia que toma el factorial si N = 0 (base) N ! = N * (N – 1) ! si N > 0 (recursión) Un razonamiento recursivo tiene dos partes: la base y la regla recursiva de construcción. La base no es recursiva y es el punto tanto de partida como de terminación de la definición.

21 Solución Recursiva Dado un entero no negativo x, regresar el factorial de x fact: Entrada n entero no negativo, Salida:entero. int factorial (int fact) { if (fact > 0) valor=fact * fact(n – 1); return valor; else return 1; } Es importante determinar un caso base, es decir un punto en el cual existe una condición por la cual no se requiera volver a llamar a la misma función.

22 ¿Cómo funciona la recursividad?
Llamadas recursivas Resultados de las llamadas recursivas

23 ¿Cómo funciona la recursividad?

24 Ejemplo recursividad /*Calcular la suma de los números pares desde 2 hasta n utilizando recursividad*/ package sumapares; import javax.swing.JOptionPane; public class SumaPares { int suma=0; public int calcular(int n) { if (n>1) { if((n%2) == 0) { suma=suma+n; } calcular(n-1); return (suma); public static void main(String[] args) { int n,suma; SumaPares miSuma=new SumaPares(); n = Integer.parseInt(JOptionPane.showInputDialog("Ingrese n:")); suma=miSuma.calcular(n); JOptionPane.showMessageDialog(null, "La suma de los números pares desde cero hasta: "+n +" es de: "+suma); System.exit(0);

25 ¿Por qué escribir programas recursivos?
Son mas cercanos a la descripción matemática. Generalmente mas fáciles de analizar Se adaptan mejor a las estructuras de datos recursivas. Los algoritmos recursivos ofrecen soluciones estructuradas, modulares y elegantemente simples.

26 Factible de utilizar recursividad
Para simplificar el código. Cuando la estructura de datos es recursiva ejemplo : árboles. Cuando los métodos usen arreglos largos. Cuando el método cambia de manera impredecible de campos. Cuando las iteraciones sean la mejor opción. No factible utilizar recursividad

27 Otros conceptos Cuando un procedimiento incluye una llamada a sí mismo se conoce como recursión directa. Cuando un procedimiento llama a otro procedimiento y éste causa que el procedimiento original sea invocado, se conoce como recursión indirecta.

28 Ejemplo: Serie de Fibonacci
Valores: 0, 1, 1, 2, 3, 5, 8... Cada término de la serie suma los 2 anteriores. Fórmula recursiva fib(n) = fib (n - 1) + fib (n - 2) Caso base: Fib (0)=0; Fib (1)=1 Caso recursivo: Fib (i) = Fib (i -1) + Fib(i -2) public int fib(int n){ if (n <= 1){ return n;} //condición base else { return fib(n-1)+fib(n-2); } //condición recursiva }

29

30 Ejemplo recursividad //Programa para calcular la potencia de x elevado a la n en forma recursiva public class Potencia1 { public double potencia(double x, int n) { if(n==0){ return 1;} else {return x*potencia(x,n-1);} } public static void main(String[] args) { Potencia1 miPotencia= new Potencia1(); int n; double x; double result; x = Double.parseDouble(JOptionPane.showInputDialog("Ingrese el valor de x:")); do{ n = Integer.parseInt(JOptionPane.showInputDialog("Ingrese n:")); } while(n<=0); result=miPotencia.potencia(x,n); JOptionPane.showMessageDialog(null, x+" elevado a la "+n+" es igual a "+result);

31 Recursión vs iteración
Repetición Iteración: ciclo explícito (se expresa claramente) Recursión: repetidas invocaciones a método Terminación Iteración: el ciclo termina o la condición del ciclo falla Recursión: se reconoce el caso base En ambos casos podemos tener ciclos infinitos Considerar que resulta más positivo para cada problema LA RECURSIVIDAD SE DEBE USAR CUANDO SEA REALMENTE NECESARIA, ES DECIR, CUANDO NO EXISTA UNA SOLUCIÓN ITERATIVA SIMPLE.

32 Dividir para vencer Muchas veces es posible dividir un problema en subproblemas más pequeños, generalmente del mismo tamaño, resolver los subproblemas y entonces combinar sus soluciones para obtener la solución del problema original. Dividir para vencer es una técnica natural para las estructuras de datos, ya que por definición están compuestas por piezas. Cuando una estructura de tamaño finito se divide, las últimas piezas ya no podrán ser divididas.


Descargar ppt "Recursividad."

Presentaciones similares


Anuncios Google