Tecnología de la Programación

Documentos relacionados
UNIVERSIDAD DE LOS ANDES NUCLEO UNIVERSITARIO RAFAEL RANGEL (NURR) DEPARTAMENTO DE FISICA Y MATEMATICA AREA COMPUTACION TRUJILLO EDO.

Metodología de la Programación II. Recursividad

Algoritmos Recursivos de Búsqueda y Ordenación y sus tiempos

Temario. Tema 2. Tecnología de Desarrollo Software. 2.1 Excepciones en C Prueba y Depuración. 2.3 Documentación

Universidad de Valladolid. Departamento de informática. Campus de Segovia. Estructura de datos Tema 4: Ordenación. Prof. Montserrat Serrano Montero

Tema 2. Recursividad. Fundamentos de Programación II. Luís Rodríguez Baena

Alonso Ramírez Manzanares Computación y Algoritmos 10.03

Recursión Directa. Una función es de recursión directa si contiene una llamada explícita a si misma. return foo (y 1); Recursión Indirecta

Metodología y Tecnología de la Programación

Capítulo 2: Recursividad.

Agradecimientos. Nota de los autores. 1 Problemas, algoritmos y programas 1

Tema 6. Reutilización de código. Programación Programación - Tema 6: Reutilización de código

Bloque 4. La descomposición funcional y el diseño descendente

El concepto de función en programación se fundamenta en el concepto de función matemática 1

1. Manejo de memoria estática 2. Manejo de memoria dinámica

Ejemplo: El problema de la mochila. Algoritmos golosos. Algoritmos y Estructuras de Datos III. Segundo cuatrimestre 2013

Escuela Politécnica Superior de Ingeniería Departamento de Ingeniería Informática

#include <stdio.h> /* Factorial de un número - versión 1- */

A = A n. = {a n. Georges E. Alfaro Salazar 1

CI 2125, Computación I

Estructuras de Repetición (Hacer-Mientras)

El programa que permite el manejo de la base de datos tiene la siguiente funcionalidad:

ARBOLES ARBOLES BINARIOS ORDENADOS. REPRESENTACIÓN Y OPERACIONES

Tema: FUNCIONES, PROCEDIMIENTOS Y RECURSIVIDAD.

<tipo> Tipo de dato de los elementos del vector

8. Sentencia return y métodos

Temario detallado. Conceptos generales de lenguajes y compiladores. Proceso de compilación de un programa en C++ bajo Code::Blocks

Examen Principios de Programación Febrero 2012

Presentación. Programación I. Conceptos Avanzados de Programación. :: Prof. Yeniffer Peña

Análisis de algoritmos

Práctica 3: Vectores y matrices en C.

FUNDAMENTOS DE INFORMÁTICA

Notación Asintótica 2

Problemas de Recursividad

Algoritmos de Ordenación

Mostrar Números Ascendentemente. Soluciones Ejercicios Tema 5. tostring Recursivo de LEG. Suma Recursiva de un Vector (1/3)

DEFINICION. Ing. M.Sc. Fulbia Torres Asignatura: Estructuras de Datos Barquisimeto 2006

PROBLEMAS DEL TEMA 7: Subprogramas y Modularidad

Multiplicación de enteros Algoritmo clásico 1234*5678 = 1234* (5* *100+7*10+8) = 1234*5* *6* *7* *8 Operaciones bási

3. Técnicas de diseño de algoritmos

Algoritmos. Diseño de algoritmos por inducción. Alberto Valderruten. Dept. de Computación, Universidade da Coruña

EJERCICIOS DE COMPLEJIDAD ALGORÍTMICA

Analisis de algoritmos

INTRODUCCIÓN. Estructura de Datos Tipos Abstractos de Datos (TAD S) Profs. Lorna Figueroa M. Mauricio Solar F. UTFSM 1 / 2008

MATEMATICA GRADO 9 II PERIODO PROF. LIC. ESP. BLANCA NIEVES CASTILLO R. CORREO: cel

Funciones. Parámetros por valor

324 MR Versión 1 Prueba Integral 1/3 Semana 10 Lapso

Sorting++ Herman Schinca. Clase de Junio de 2011

Tecnólogo Informático- Estructuras de Datos y Algoritmos- 2009

Examen escrito de Programación 1. Jueves 5 de febrero de Problema 1 o (3.5 puntos)

Algoritmos y programas. Algoritmos y Estructuras de Datos I

1. NUMEROS REALES a. Los Números Reales

Java para programadores

Árboles. Cursos Propedéuticos Dr. René Cumplido M. en C. Luis Rodríguez Flores

Lenguaje C Bucles, Condicionales, operadores y Algoritmos.

fib(0) + fib (1) + fib (5) = fib(5) = 3 + fib (3) + fib (4) = 3. + fib (1) + fib (2) + fib (4) =

Datos y tipos de datos

Principios de Computadoras II

INTELIGENCIA EN REDES DE COMUNICACIONES PRÁCTICA FINAL. Ignacio Ribas Ramos Miguel Flecha Lozano Ingeniería de Telecomunicaciones

La segunda observación permite reformular el problema de una manera más simple:

TEMA 4. ESTRUCTURAS DE CONTROL

Algoritmos. Medios de expresión de un algoritmo. Diagrama de flujo

Lenguaje C. Tipos de Datos Simples y Estructuras de Control

Resolución de Problemas

Ciclos. Recordando Estructuras de Control Básicas: SELECCIÓN (condición) SECUENCIAL

Semana de las Matemáticas e Ingeniería. Desarrollo de algoritmos recursivos empleando la aplicación PseInt

Apuntadores (Punteros)

Para las ecuaciones diferenciales ordinarias no lineales no existen métodos generales.

Tema 5.- Recursividad

Datos y tipos de datos

Lección 2 Introducción al lenguaje C

Diseño de compiladores. Representación intermedia Ambientes de ejecución

Algoritmos: Diseño de algoritmos por inducción

Guía práctica de estudio 05: Diagramas de flujo

Distinguir las diferentes estructuras de repetición utilizadas en problemas con bucles: mientras, repetir mientras, para.

Primer Parcial de Programación 3 (1/10/2009)

LA ESTRUCTURA DE DATOS PILA EN JAVA. CLASE STACK DEL API JAVA. EJEMPLO Y EJERCICIOS RESUELTOS. (CU00923C)

El lenguaje C. 1. Identificadores, constantes y variables

!MATRICES INVERTIBLES

Laboratorio de Paralelismo OpenMP: ejemplos y ejercicios

Tema 2. El lenguaje JAVA

RESUMEN DE CONCEPTOS BASICOS DE PROGRAMACION JAVA

CONCEPTOS BASICOS DEL LENGUAJE JAVA

Algoritmos de Ordenamiento

ALGORITMICA Y PROGRAMACION POR OBJETOS I

Tema 6: Generación de código (parte 2)

1. Ejemplo de clase : La clase Cuenta 2. Uso de la clase Cuenta. 3. Métodos y objetos receptores de mensajes (Importante)

Por ejemplo, el factorial puede definirse de manera recursiva de la siguiente manera:

UNIVERSIDAD NACIONAL AUTÓNOMA DE MÉXICO. Introducción FACULTAD DE INGENIERÍA. Ordenación

Análisis de Algoritmos

Java Básico. Métodos estáticos

NIVEL 15: ESTRUCTURAS RECURSIVAS BINARIAS

Programación Orientada a Objetos Métodos Guía de Ejercicios v9.7

Llamamos potencia a todo producto de factores iguales. Por ejemplo: 3 4 =

TIPO DE DATO ABSTRACTO (TDA)

Programación n Orientada a Objetos Sentencias Java Parte I. Ing. Julio Ernesto Carreño o Vargas MsC.

Programación de Computadores 4 Iteraciones y Decisiones. Prof. Javier Cañas. Universidad Técnica Federico Santa María Departamento de Informática

Centro Asociado Palma de Mallorca. Antonio Rivero Cuesta

Programación de Sistemas

Transcripción:

Título de Grado en Ingeniería Informática Curso 2009/10 Fernando Jiménez Barrionuevo Gracia Sánchez Carpena Mari Carmen Garrido Carrera Departamento de Ingeniería de la Información de las Comunicaciones Universidad de Murcia

Temario 1.1 Definición de recursividad 1.2 Recursividad en C 1.3 Esquemas recursivos 1.4 Tiempo de ejecución de los algoritmos recursivos 1.5 Recursión vs iteración 2

1.1 Definición de Recursividad Se dice que un objeto es recursivo si forma parte de sí mismo o se define en función de sí mismo. Técnica particularmente potente en las definiciones matemáticas. La potencia de la recursión reside evidentemente en la posibilidad de definir un número infinito de objetos mediante un enunciado finito. De igual forma, un número infinito de operaciones de cálculo puede describirse mediante un programa recursivo finito. En general, un programa recursivo P puede expresarse como una composición de instrucciones básicas S i (que no contienen a P) y el propio P. P [S i,p] 3

1.1 Definición de Recursividad Ejemplos: Números naturales: 1 es un número natural El siguiente de un número natural es un número natural Función factorial, n! (para números enteros no negativos): 0! = 1 Si n>0 entonces n! = n (n 1)! 3! = 3 (3-1)! = 3 2! = 3 2 (2-1)! = 3 2 1! = 3 2 1 (1-1)! = 3 2 1 0! = 3 2 1 1 = 6 4

1.1 Definición de Recursividad Un algoritmo es recursivo si se invoca a sí mismo al menos una vez. Recursividad directa: El algoritmo contiene una llamada explícita a sí mismo, es decir, A invoca a A. Recursividad indirecta: El algoritmo se invoca a sí mismo de forma indirecta, es decir, A invoca a B y B invoca a A. Recursividad de cola o extremo final: La llamada recursiva es la última instrucción que ejecuta el algoritmo. 5

1.1 Definición de Recursividad Un algoritmo recursivo está bien construido si: 1. Contiene, al menos, un caso base, en el cual el algoritmo no se llama a sí mismo. 2. Los valores de los parámetros del algoritmo en las sucesivas llamadas recursivas están más cerca del caso base que el valor con el que se llamó inicialmente al algoritmo, garantizando que el caso base se alcanza. 6

1.2 Recursividad en C Multiplicación n m (m 0) Caso Base: (m = 0) n 0 = 0 Caso General: (m > 0) n m = n + n (m - 1) // m>=0 int multiplica(int n, int m) if (m==0) return 0; return n+multiplica(n,m-1); // m>=0 (version comprimida) int multiplica(int n, int m) return(m==0?0:n+multiplica(n,m-1)); 7

1.2 Recursividad en C División entera n / m (n 0 y m>0) Caso Base: (n < m) n / m = 0 Caso General: (n m) n / m = 1 + ( n m ) / m // n>=0, m>0 int divide(int n, int m) if (n<m) return 0; return 1+divide(n-m,m); // n>=0 y m>0 (version comprimida) int divide(int n, int m) return (n<m?0:1+divide(n-m,m)); 8

1.2 Recursividad en C Módulo n % m (n 0 y m > 0) Caso Base: Caso General: (n < m) n % m = n (n m) n % m = ( n m ) % m // n>=0, m>0 int modulo(int n, int m) if (n<m) return n; return modulo(n-m,m); // n>=0 y m>0 (version comprimida) int modulo(int n, int m) return (n<m?n:modulo(n-m,m)); 9

1.2 Recursividad en C Potencia n m (m 0) Caso Base: (m = 0) n 0 = 1 Caso General: (m > 0) n m = n n m - 1 // m>=0 int potencia(int n, int m) if (m==0) return 1; return n*potencia(n,m-1); // m>=0 (version comprimida) int potencia(int n, int m) return(m==0?1:n*potencia(n,m-1)); 10

1.2 Recursividad en C Factorial n! (n 0) Caso Base: (n = 0) 0! = 1 Caso General: (n > 0) n! = n ( n 1 )! // n>=0 int factorial(int n) if (n==0) return 1; return n*factorial(n-1); // n>=0 (version comprimida) int factorial(int n) return(n==0?1:n*factorial(n-1)); 11

1.2 Recursividad en C Fibonacci fib(n) (n 0) Caso Base: Caso General: (n 1) fib(n) = n (n > 1) fib(n) = fib(n-2) + fib(n-1) // n>=0 int fibonacci(int n) if (n<=1) return n; return fibonacci(n-2)+fibonacci(n-1); // n>=0 (version comprimida) int fibonacci(int n) return(((n<=1))?n:fibonacci(n-2)+fibonacci(n-1)); 12

1.2 Recursividad en C Hanoi h(n,a,b,c) (n 1) Caso Base: (n = 1) h(1,a,b,c): a c Caso General: (n > 1) h(n,a,b,c): h(n-1,a,c,b), a c, h(n-1,b,a,c) // n>=1 void hanoi(int n, char a, char b, char c) if (n>1) hanoi(n-1,a,c,b); printf( Mover de %d a %d\n,a,c); if (n>1) hanoi(n-1,b,a,c); 13

1.3 Esquemas recursivos Divide y Vencerás función DV(x) devuelve solución si x es suficientemente pequeño o sencillo entonces (Caso Base): devolver ad hoc (x) en otro caso (Caso General): descomponer x en casos más pequeños x 1,x 2,...,x n para i=1 hasta n hacer y i = DV(x i ) combinar los y i para obtener una solución y de x devolver y 14

1.3 Esquemas recursivos Divide y Vencerás: Búsqueda Binaria Busca un elemento e en un vector v ordenado. Devuelve el índice de una ocurrencia del elemento e en del vector v. Si el vector v no contiene ninguna ocurrencia del elemento e, devuelve -1. // v está ordenado int buscabin(int v[], int ini, int fin, int e) if (ini>fin) return -1; int med = (ini+fin)/2; if (v[med]==e) return med; if (v[med]>e) return buscabin(v,ini,med-1,e); if (v[med]<e) return buscabin(v,med+1,fin,e); // v está ordenado, tam es el numero de elementos de v int buscabin(int v[], int tam, int e) return buscabin(v,0,tam,e); 15

1.3 Esquemas recursivos Divide y Vencerás: Ordenación por Mezcla Ordena un vector v desde el índice ini hasta el índice fin. void mergesort(int v[], int ini, int fin) if ((fin-ini)>0) int med = (ini+fin)/2; mergesort(v,ini,med); mergesort(v,med+1,fin); mezcla(v,ini,fin,med); // tam es el numero de elementos de v void mergesort(int v[], int tam) mergesort(v,0,tam); 16

1.3 Esquemas recursivos Vuelta Atrás: Una solución Devuelve cierto si encuentra una solución a partir de un paso, y falso en caso contrario. Si encuentra una solución la devuelve en el parámetro solucion. funcion VA(entrada: paso, salida: solución) devuelve booleano si solución completa entonces devolver cierto fin si para cada posibilidad de solución si posibilidad aceptable en solución entonces anotar posibilidad en solución si VA(siguiente paso, solución) entonces devolver cierto fin si cancelar posibilidad en solución fin si fin para devolver falso 17

1.3 Esquemas recursivos Vuelta Atrás: Una solución Solución compuesta por n pasos y m posibilidades para cada paso. El parámetro solucion debe pasarse como apuntador porque es de salida. bool VA(int i, solucion * s) if (i==n) return true; for(int j=0;j<m;j++) if (aceptable(s,i,j)) anotar(s,i,j); if (VA(i+1,s)) return true; cancelar(s,i,j); return false; LLamada inicial al método VA: solucion * s = new solucion(); inicia(s); if (VA(0,s)) imprime(s); 18

1.3 Esquemas recursivos Vuelta Atrás: Todas las soluciones Obtiene todas las soluciones posibles a partir de un paso. funcion VA(entrada: paso, salida: solución) si solución completa entonces anotar solución en otro caso para cada posibilidad de solución si posibilidad aceptable en solución entonces anotar posibilidad en solución VA(siguiente paso, solución) cancelar posibilidad en solución fin si fin para fin si 19

1.3 Esquemas recursivos Vuelta Atrás: Todas las soluciones Solución compuesta por n pasos y m posibilidades para cada paso. void VA(int i, solucion * s) if (i==n) imprime(s); else for(int j=0;j<m;j++) if (aceptable(s,i,j)) anotar(s,i,j); VA(i+1,s); cancelar(s,i,j); LLamada inicial al método VA: solucion s = new solucion(); inicia(s); VA(0,s)); 20

1.3 Esquemas recursivos Vuelta Atrás: Ocho Reinas n = 8 (8 pasos, un paso por cada reina) m = 8 (8 posibilidades para cada reina) x[i]: indica la posición en columna de la reina en la fila i-ésima a[i]: true si la columna i-ésima está libre b[i]: true si la diagonal derecha i-ésima está libre c[i]: true si la diagonal izquierda i-ésima está libre struct solucion int x[8]; bool a[8]; bool b[15]; bool c[15]; ; 21

1.3 Esquemas recursivos Vuelta Atrás: Ocho Reinas void inicia(solucion * s) for(int j=0;j<8;j++) s->a[j] = true; for(int j=0;j<15;j++) s->b[j] = true; s->c[j] = true; void imprime(solucion * s) for(int j=0;j<8;j++) printf("%d ",s->x[j]); printf("\n"); bool aceptable(solucion * s,int i,int j) return s->a[j]&&s->b[i+j]&&s->c[i-j+7]; void anotar(solucion * s, int i, int j) s->x[i]=j; s->a[j]=false; s->b[i+j]=false; s->c[i-j+7]=false; void cancelar(solucion * s, int i, int j) s->a[j]=true; s->b[i+j]=true; s->c[i-j+7]=true; 22

1.4 Tiempo de ejecución de los algoritmos recursivos Expansión de recurrencias Utiliza la recurrencia misma para sustituir m<n por cualquier T(m) en la derecha, hasta que todos los términos T(m) para m>1 se hayan reemplazado por fórmulas que impliquen sólo T(1). Como T(1) siempre es constante, se tiene una fórmula para T(n) en función de n y de algunas constantes. A esta fórmula se le denomina forma cerrada para T(n). 23

1.4 Tiempo de ejecución de los algoritmos recursivos Ejemplo: Factorial Ecuación de recurrencia: T(0) = c 1 T(n) = T(n-1) + c 2 si n>0 Expansión de recurrencias: T(n) = T(n-1)+c 2 = [T(n-2)+c 2 ]+c 2 = T(n-2)+2c 2 = [T(n-3)+c 2 ]+2c 2 = T(n-3)+3c 2 Forma cerrada para T(n) (por inducción en i): T(n) = T(n-i) + i c 2 La expansión terminará cuando se alcance T(0) en lado derecho de la forma cerrada, es decir, cuando n-i=0, por tanto i=n. Sustituyendo en la forma cerrada i por n se obtiene: T(n) = T(0) + n c 2 = c 1 + n c 2 Esto demuestra que T(n) es O(n). 24

1.4 Tiempo de ejecución de los algoritmos recursivos Ejemplo: Búsqueda Binaria Ecuación de recurrencia: T(1) = c 1 T(n) = T(n/2) + c 2 si n>1 Expansión de recurrencias: T(n) = T(n/2)+c 2 = [T(n/4)+c 2 ]+c 2 = T(n/4)+2c 2 = [T(n/8)+c 2 ]+2c 2 = T(n/8)+3c 2 Forma cerrada para T(n) (por inducción en i): T(n) = T(n/2 i ) + ic 2 La expansión terminará cuando se alcance T(1) en lado derecho de la forma cerrada, es decir, cuando n/2 i =1, por tanto i=log n. Sustituyendo en la forma cerrada i por n se obtiene: T(n) = T(1) + log n c 2 = c 1 + log n c 2 Esto demuestra que T(n) es O(log n). 25

1.4 Tiempo de ejecución de los algoritmos recursivos Ejemplo: Mergesort Ecuación de recurrencia: T(1) = c 1 T(n) = 2 T(n/2) + n c 2 si n>1 Expansión de recurrencias: T(n) = 2T(n/2)+nc 2 = 2[2T(n/4)+(n/2)c 2 ]+nc 2 = 4T(n/4)+2nc 2 = 8T(n/8)+3nc 2 Forma cerrada para T(n) (por inducción en i): T(n) = 2 i T(n/2 i ) + i n c 2 La expansión terminará cuando se alcance T(1) en lado derecho de la forma cerrada, es decir, cuando n/2 i =1, por tanto i=log n. Sustituyendo en la forma cerrada i por n se obtiene: T(n) = nt(1) + (log n) n c 2 = nc 1 + n log n c 2 Esto demuestra que T(n) es O(n log n). 26

1.5 Recursión vs Iteración La recursión implica múltiples llamadas y el uso de la pila interna para almacenar, en cada llamada recursiva, los parámetros de llamada, variables locales y dirección de retorno, lo que hace que en general sea más ineficiente que el diseño iterativo. Siempre es posible sustituir un algoritmo recursivo por un algoritmo iterativo que utilice una pila. Casos en los que no se debe utilizar la recursión: 1. Recursividad de cola 2. Árbol de recursión lineal (ejemplo, factorial) 3. Árbol de recursión ramificado, pero con nodos repetidos (ejemplo Fibonacci) Conclusión: la recursión se deberá utilizar cuando, además de facilitar el diseño del algoritmo, genere un árbol de recursión ramificado y con nodos no repetidos. 27

1.5 Recursión vs Iteración Multiplicación n m (m 0) Caso Base: (m = 0) n 0 = 0 Caso General: (m > 0) n m = n + n (m - 1) // m>=0 (versión recursiva) int multiplica(int n, int m) if (m==0) return 0; return n+multiplica(n,m-1); // m>=0 (versión iterativa) int multiplica(int n, int m) int res = 0; for(;m>0;m--) res+=n; return res; 28

1.5 Recursión vs Iteración División entera n / m (n 0 y m > 0) Caso Base: (n < m) n / m = 0 Caso General: (n m) n / m = 1 + ( n m ) / m // n>=0, m>0 (versión recursiva) int divide(int n, int m) if (n<m) return 0; return 1+divide(n-m,m); // n>=0, m>0 (versión iterativa) int divide(int n, int m) int res = 0; for(;n>=m;n-=m) res++; return res; 29

1.5 Recursión vs Iteración Módulo n % m (n 0 y m > 0) Caso Base: Caso General: (n < m) n % m = n (n m) n % m = ( n m ) % m // n>=0, m>0 (versión recursiva) int modulo(int n, int m) if (n<m) return n; return modulo(n-m,m); // n>=0, m>0 (versión iterativa) int modulo(int n, int m) for(;n>=m;n-=m); return n; 30

1.5 Recursión vs Iteración Potencia n m (m 0) Caso Base: (m = 0) n 0 = 1 Caso General: (m > 0) n m = n n m - 1 // m>=0 (versión recursiva) int potencia(int n, int m) if (m==0) return 1; return n*potencia(n,m-1); // m>=0 (versión iterativa) int potencia(int n, int m) int res = 1; for(;m>0;m--) res*=n; return res; 31

1.5 Recursión vs Iteración Factorial n! (n 0) Caso Base: (n = 0) 0! = 1 Caso General: (n > 0) n! = n ( n 1 )! // n>=0 (versión recursiva) int factorial(int n) if (n==0) return 1; return n*factorial(n-1); // n>=0 (version iterativa) int factorial(int n) int res = 1; for(;n>0;n--) res*=n; return res; 32

1.5 Recursión vs Iteración Fibonacci fib(n) (n 0) Caso Base: Caso General: (n 1) fib(n) = n (n > 1) fib(n) = fib(n-2) + fib(n-1) // n>=0 (versión recursiva) int fibonacci(int n) if ((n<=1)) return n; return fibonacci(n-2)+fibonacci(n-1); // n>=0 (version iterativa) int fibonacci(int n) if (n<=1) return n; int * aux = (int *)malloc((n+1)*sizeof(int)); aux[0] = 0; aux[1] = 1; for(int i=2; i<=n; i++) aux[i] = aux[i-2] + aux[i-1]; int res = aux[n]; free(aux); return res; 33

1.5 Recursión vs Iteración Búsqueda Binaria // v está ordenado (versión recursiva) int buscabin(int v[], int ini, int fin, int e) if (ini>fin) return -1; int med = (ini+fin)/2; if (v[med]==e) return med; if (v[med]>e) return buscabin(v,ini,med-1,e); if (v[med]<e) return buscabin(v,med+1,fin,e); // v está ordenado (versión iterativa) int buscabin(int v[], int ini, int fin, int e) while(ini<=fin) int med = (ini+fin)/2; if (v[med]==e) return med; if (v[med]>e) fin = med-1; else ini = med+1; return -1; 34

Ejercicios Propuestos Máximo Común Divisor mcd(n,m) (n 0, m 0) Caso Base: (m == 0) mcd(n,m) = n Caso General: (m > 0) mcd(n,m) = mcd(m,n%m) Monedas: Calcular el número mínimo de monedas necesarias para una determinada cantidad. Suponemos que tenemos monedas de 1, 5, 10, 20 y 50 céntimos y que la cantidad es menor de 1 euro. 35