Recursividad.

Slides:



Advertisements
Presentaciones similares
Complejidad Computacional
Advertisements

Complejidad Computacional
Diseño y análisis de algoritmos
ESTRUCTURA DE DATOS Unidad 01 RECURSIVIDAD.
Estructura de Datos Unidad 4. Recursividad Dra. María Lucía Barrón Estrada Enero-Junio 2007.
Programación II Recursividad
Estructuras de Repetición Algoritmos
MÉTODOS Y ELEMENTOS DE PROGRAMACIÓN
Introducción a los Algoritmos
FUNCIONES EN C.
Funcionamiento, programación
UNIVERSIDAD LATINA (UNILA) IV. IMPLANTACION DE ALGORITMOS.
ALGORÍTMICA Dpto. Ingeniería de Sistemas y Automática
Objetivos Específicos de la Unidad
Recursión Se dice que un método es recursivo si forma parte de sí mismo o se define en función de sí mismo. La recursión es un medio particularmente poderoso.
2.1 Recursividad El hecho de que una función pueda llamarse a sí misma.
Tema 7: Polimorfismo Antonio J. Sierra. Índice Introducción. Sobrecarga de métodos. Objetos como parámetros. Paso de argumentos. Devolución de objetos.
Funciones y procedimientos
CI TEORIA semana 8 Subprogramas o funciones Definición de funciones.
Programación I Teoría VI: Recursividad
FUNCIONES Y PROCEDIMIENTOS
Estructuración y modularidad de los programas Fundamentos de Programación/ Programación I
ANALISIS SINTACTICO El análisis gramatical es la tarea de determinar la sintaxis, o estructura, de un programa. Por esta razón también se le conoce como.
Tema 6: Clases Antonio J. Sierra.
Ingeniero Anyelo Quintero
ESTRUCTURAS DE CONTROL
Programación de Computadores
Semana 5 Subprogramas..
Funciones1 PROGRAMACIÓN ESTRUCTURADA EN PSEUDÓCODIGO Profr. Miguel Rodríguez Hernández PROGRAMACIÓN MODULAR O FUNCIONAL.
Fundamentos de programación

Introducción al análisis de algoritmos
Estructura de Datos y Algoritmos
Capítulo 1 “Elementos de Programación”

PROGRAMACIÓN PROCEDIMENTAL
Material de apoyo Unidad 4 Estructura de datos
Análisis de algoritmos
Figure: Algoritmos Conceptos básicos. Programación: 1.Establecer una secuencia de acciones que: puedan ser ejecutadas por el procesador realicen una.
UNIDAD 2. ALGORITMOS Y ESTRUCTURAS DE DATOS.
Computación I Primer Semestre 2006 Capítulo IV Ciclos y Colecciones (con un sabor a algoritmos)
Recursividad.
Estructuras de Control.
APRENDIZ: SANDRA L. CAICEDO C. ORDEN: 20194
Recursividad (2 clases) 1. Nivelación Funciones Menú Vectores String
Funciones Curso Propedéutico Maestría en Ingeniería Electrónica.
Estructura de Datos En C++
Sentencias de repetición
Análisis de Algoritmos
Programación Procedural y Recursiva en C++
Conceptos Avanzados de Programación
Oscar Bedoya. Edificio 331, 2º piso, E.I.S.C. Estructuras de datos y algoritmos.
Capítulo 2 “Subprogramas/Funciones - Arreglos”
Metodología de la programación
Unidad V Recursión. Objetivos del Aprendizaje Explicar el concepto de recursión. Discutir las diferentes condiciones que deben ser satisfechas para que.
Conalep Coacalco Algoritmos Recursivos
Introducción a los TADs
Estructuras de Decisión
ESTRUCTURA DE CONTROL REPETITIVAS: WHILE, DO… WHILE
 Las funciones son un conjunto de instrucciones que realizan una tarea específica. En general toman unos valores de entrada, llamados parámetros y proporcionan.
Funciones Copyright © 2005 Unidad 1. Copyright © 2005 Objetivos del Aprendizaje Explicar la naturaleza y usos de las funciones. Describir algunas funciones.
U11: Recursividad Otra manera de hacer bucles Dicen algunos pedagogos que conceptualmente mas sencilla.
LE, EI, Profesor Ramón Castro Liceaga UNIVERSIDAD LATINA (UNILA) V. GESTIÓN DE TIPOS Y GENERACIÓN DE CÓDIGOS.
La programación modular es un paradigma de programación que consiste en dividir un programa en módulos o subprogramas con el fin de hacerlo más legible.
UNIVERSIDAD TECNOLÓGICA DE PANAMÁ Facultad de Ingeniería de Sistemas Computacionales Programa de Lic. en Informática Educativa Computación.
LE, EI, Profesor Ramón Castro Liceaga UNIVERSIDAD LATINA (UNILA) IV. IMPLANTACION DE ALGORITMOS.
Paso de parámetros Diseño de programas iterativos Fundamentos de Programación Departamento de Lenguajes y Sistemas Informáticos Unidad Didáctica 7 Versión.
ALGORITMOS Y PROGRAMAS. OBJETIVOS  Resolver problemas mediante la especificación algorítmica.  Proporcionar los procedimientos y técnicas para el desarrollo.
Estructuras de Datos Recursividad.
Recursividad 1 Análisis de algoritmos. Matrushka La Matrushka es una artesanía tradicional rusa. Es una muñeca de madera que contiene otra muñeca más.
Transcripción de la presentación:

Recursividad

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.

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.

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.

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.

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.

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.

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á.

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.

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.

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

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).

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.

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

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

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  2 * 1 3! = 6  3 * 2 * 1 4! = 24  4 * 3 * 2 * 1 5! = 120  5 * 4 * 3 * 2 * 1

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);

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);

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 = 1 * 0! = 2 * 1 = 2 * 1! = 3 * 2 * 1 = 3 * 2! = 4 * 3 * 2 * 1 = 4 * 3! = 5 * 4 * 3 * 2 * 1 = 5 * 4! = N * (N – 1)!

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 1 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.

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.

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

¿Cómo funciona la recursividad?

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);  

¿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.

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

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.

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 }

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);

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.

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.