Estructura de Datos y Algoritmos

Slides:



Advertisements
Presentaciones similares
Introducción al Teorema de Gödel Eduardo Alejandro Barrio UBA - CONICET 2do Cuatrimestre de 2009 Eduardo Alejandro Barrio UBA.
Advertisements

La aritmetización de la sintaxis
Diseño y análisis de algoritmos
Diseño y análisis de algoritmos
Diseño y análisis de algoritmos
FACTORIZACIÓN LU Bachilleres:
LA CLASE VIRTUAL POLINOMIOS.
funciones Por: Carlos Alberto García Acosta
La maquina de Turing La máquina de Turing es una caja negra (tan simple como una máquina de escribir y tan compleja como un ser humano) capaz no sólo de.
Iteración La iteración permite modelar problemas en los cuales una secuencia de instrucciones debe ejecutarse varias veces. La cantidad de iteraciones.
Metodología de la Programación
Combinadores SK.
Unidad académica: Ingenierías
Unidad 4: Análisis de algoritmos (parte II)
KRIGING.
PROGRAMACION DE ESTRUCTURAS DE DATOS
Programación 1 Introducción
Teoría de lenguajes y compiladores
ESPACIOS VECTORIALES.
PARADIGMA Es un esquema de pensamiento que nos lleva a concebir las cosas de una manera determinada. el término paradigma puede indicar el concepto de esquema.
CI TEORIA semana 8 Subprogramas o funciones Definición de funciones.
FUNCIONES Y PROCEDIMIENTOS
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.
Representaciones de conjuntos y funciones Roberto Moriyón.
Teoría de lenguajes y compiladores
TRAMPAS EN EL DISEÑO DE LENGUAJES CON RELACIÓN A LOS NOMBRES - REGLAS DE ALCANCE - COMPILACIÓN POR SEPARADO CONTROL DE FLUJO - EVALUACIÓN DE EXPRESIONES.
2- SIMPLEX.
SOBRE LA CONSTRUCCION AXIOMATICA DE LOS NUMEROS NATURALES I
Semana 5 Subprogramas..
Programación en Matlab
La Derivada. Ya vimos: los conceptos, métodos ó instrumentos necesarios para establecer el “comportamiento” de una función.  en un entorno de x o [ 
Problemas, algoritmos y programas: Modelar: Simular o programar su solución en un computador. Algoritmos: Es un conjunto finito, y no ambiguo de etapas.

2º Bachillerato de Ciencias y Tecnología BC2A – BC2B Curso
Introducción al análisis de algoritmos
Algoritmos.
Estructura de Datos y Algoritmos
Inteligencia artificial
Programación I Universidad Nacional de Luján
Sesión 5 Sentencias de Selección y repetición Prof:Eridan Otto Programación de Computadores Lenguaje Pascal.
PROGRAMACIÓN PROCEDIMENTAL
Material de apoyo Unidad 4 Estructura de datos
Análisis de algoritmos
Estructuras de Datos y Algoritmos Curso 2009 Tecnólogo Informático.
Recurrencia Programación II de enero de 2009.
Teoría – Alejandro Gonzalez
Figure: Algoritmos Conceptos básicos. Programación: 1.Establecer una secuencia de acciones que: puedan ser ejecutadas por el procesador realicen una.
Planteos Recursivos Resolución de Problemas y Algoritmos
Recursividad.
PENSAMIENTO ANALÍTICO SISTÉMICO DAISY KATERINE RODRÍGUEZ DURÁN
Curso de Teoría del Autómata
Parte I. Estructuras de Datos.
Recursividad (2 clases) 1. Nivelación Funciones Menú Vectores String
Parte I. Estructuras de Datos.
Análisis de Algoritmos
Recursividad Un objeto se dice que es recursivo si él mismo forma parte de su definición. Ejemplos de objetos recursivos: Una locomotora es un tren Un.
Términos algoritmo diseñar algoritmo implementar algoritmo
ELEMENTOS DE COMPUTACIÓN Profesor: Guillermo Figueroa
PRINCIPIOS DE PROGRAMACIÓN
Elaboración de algoritmos usando lógica de programación
LIC. JOSEPH RUITON RICRA
Conalep Coacalco Algoritmos Recursivos
Introducción a los TADs
Lic. Carla Aguirre Montalvo
75.41 Algoritmos y Programación II Cátedra Ing. Patricia Calvo Complejidad algorítmica.
 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.
PROGRAMACIÓN Grupo de Modelamiento de Sistemas
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.
Principios logicos.
 Dicho principio lógico podemos formularlo de la siguiente forma: A es A, en la cual la variable A denota un pensamiento o contenido concreto cualquiera.
Transcripción de la presentación:

Estructura de Datos y Algoritmos Recurrencia

Introducción Diccionario castellano recurrir volver una cosa al sitio de donde salió; retornar, repetirse, reaparecer; (poco frecuente) recurrir a algo -> hacer uso de ello (más común)

Introducción Subprogramas recurrentes se invocan (llaman) a sí mismos definidos en términos de sí mismos

Circularidad Recurrencia inútil Procedure P Begin   P End P

Circularidad Termina con un error de ejecución: no hay más memoria (p.ej:'stack overflow') ¿ Por qué ? cada vez que un programa P llama otro Q debe guardarse una indicación del punto en P donde el control debe retornar al finalizar la ejecución de Q las llamadas a procedimientos pueden encadenarse arbitrariamente Q1 -> Q2 -> Q3 -> ... -> Qn -> ...

Circularidad Hay una estructura de datos donde se almacenan sucesivos puntos de retorno: En general se tiene: P -> Q1 -> Q2 -> Q3 -> ... -> Qn donde Qn es el subprograma que se está ejecutando

Circularidad Paralelamente, se ha formado la estructura de "puntos de retorno": p0, p1, p2, ..., pn-1 p0 -> punto de retorno en P p1 -> punto de retorno en Q1 ... pn-1 -> punto de retorno en Qn-1

Circularidad La estructura crece con cada nueva llamada (un lugar) y decrece al terminar la ejecución de un subprograma. La estructura se comporta como una PILA (análogo a una pila de platos)

Circularidad pn-1 pn-2 . . p1 p0 El tope de la pila es el punto donde debe retornarse el control tras la terminación del subprograma corriente. Por lo tanto, si el subprograma corriente llama a otro, el correspondiente punto de retorno debe colocarse como nuevo tope de la pila Y al finalizar un subprograma, se usa el tope como dirección de retorno y se lo remueve de la pila.

Circularidad Volviendo al ejemplo de "recurrencia inútil": la pila crece infinitamente, pero la memoria de la máquina es finita, por lo tanto, en algún momento no hay más memoria (stack overflow = desbordamiento de la pila)

Ejemplo PROCEDURE P; VAR x : int; BEGIN   LeerCaracter(x);     IF EsPrimo(x) THEN     WriteString("Es Primo")   ELSE     WriteString("No es Primo");   END; {if}     P; END P;

Ejemplo (continuación) En principio, permitiría implementar un programa interactivo. Pero también termina por desbordar la pila (stack), en las implementaciones elementales. Este es un ejemplo de recurrencia infinita

Circularidad Estas recurrencias: pueden tener sentido en principio (como en el último ejemplo) pero terminan por desbordar la memoria (al menos con las implementaciones comunes de llamadas a subprogramas)

Circularidad Comparar primer ejemplo con: (y análogamente para el segundo ejemplo) Estas versiones (iterativas) originan ejecuciones infinitas pero no por ello desbordan la memoria PROCEDURE P BEGIN   WHILE true DO   END {while} END P;

Otro ejemplo FUNCTION Fact(n : INT) : INT BEGIN   IF (n = 0) THEN     RETURN 1   ELSE     RETURN ( n * Fact(n-1));   END END Fact; Que calcula esta función?

Otro ejemplo (continuación) Cada ejecución de Fact(n) para n : NATURAL es finita En este ejemplo, para valores no demasiado grandes de n, Fact(n) puede ser demasiado grande (“CARDINAL OVERFLOW") 15! = 1,3 x 1012 Existirá un rango de valores de tipo NATURAL para los cuales la función anterior computa efectivamente los correspondientes factoriales.

Comparar con versión iterativa PROCEDURE Fact (n : INT) : INT VAR i, f : INT; BEGIN   f := 1;   FOR i := 2 TO n DO     f := f * i;   END; {for}   RETURN f; END Fact;

Comparar con versión iterativa (continuación) La versión recurrente es más simple análoga a una definición matemática La versión iterativa es más eficiente (no usa pila) Se acomoda mejor al esquema de máquinas de estados En particular, podría darse que: La versión recurrente terminara por desbordar la pila en casos en que la versión iterativa terminaría normalmente

Primeras Conclusiones Usamos subprogramas recurrentes Operando sobre nuevos datos Produciendo además otros efectos Esto le da sentido a la circularidad Nos aseguramos que en algún momento “pare” de ejecutar

Primeras Conclusiones Por ejemplo, podemos decir que la función Fact está definida en términos de sí misma. Esto sugeriría una circularidad de la definición pero en realidad es una afirmación no demasiado precisa. En realidad, para cada n, Fact(n) no está definido circularmente (pe. en términos de sí mismo) sino en términos de Fact(n-1) o bien (si n = 0) directamente (pe. sin usar Fact)

Primeras Conclusiones El cómputo de Fact(n) se realiza: directamente (n = 0) reduciéndolo a Fact en un número más chico (mas cercano a 0) Esto garantiza que toda ejecución de Fact(n) es finita y que por lo tanto Fact(n) esta bien definida para todo n (a menos del problema de "CARDINAL OVERFLOW" o eventualmente "STACK OVERFLOW", en otros casos)

Primeras Conclusiones El uso de recurrencia permite escribir programas cuyas computaciones son de largo variable

Primeras Conclusiones recurrencia/iteración Existe redundancia al tener ambos conceptos? De hecho, pueden considerarse lenguajes: sin iteración sin asignación (ver FACT recurrente, alcanza con el concepto de función que retorna un valor) sin variables de estado

Primeras Conclusiones Esto es la base de los llamados LENGUAJES DECLARATIVOS Lenguajes Declarativos Funcionales - son particularmente interesantes Lógicos

Primeras Conclusiones Los lenguajes con variables de estado, asignación e iteración son llamados lenguajes IMPERATIVOS La mayoría de los lenguajes imperativos modernos admite recurrencia El uso de recurrencia permite desarrollar soluciones simples y elegantes, en muchos casos en que las correspondientes soluciones iterativas son demasiado complejas También se da lo inverso (pe. Fact)

Orígenes En Matemática, los números naturales usualmente se asumen como bien conocidos se escriben en notación decimal (También en MODULA-2, PASCAL, C, … ) En lógica, los naturales se definen explícitamente

dn * bn + ..... + d0 * b0 (un polinomio) Orígenes La idea es abstraerse de cualquier sistema de numeración posicional Un sistema de numeración es de hecho un sistema de representación de números El sistema en base b usa b símbolos Ej: dígitos : dn dn-1 .... d0 de tal forma que el número representado es: dn * bn + ..... + d0 * b0 (un polinomio)

Orígenes Tratamos de abstraernos de todas estas representaciones. Pe. buscar una "más general" que podamos tomar como la definición (lo esencial) del concepto de número natural Esto nos lleva a considerar el sistema de numeración más simple posible SISTEMA UNARIO

SISTEMA UNARIO Sistema unario de numeración: hay un sólo dígito : | representamos los números como secuencias de ese dígito: || 2 ||||| 5 es conveniente tener una representación para el 0 (cero) Esto nos lleva a la definición de los números naturales

Naturales Es el caso de Definición Inductiva de un conjunto. Damos reglas para construir todos los elementos del conjunto:   Regla 1 - 0 es un natural Regla 2 - Si n es un natural entonces Sucesor(n) es otro natural Regla 3 - Esos son todos los naturales 0 y Sucesor son llamados (operadores) CONSTRUCTORES del conjunto N

Naturales La Regla 3 permite justificar el PRINCIPIO de DEMOSTRACIÓN por INDUCCIÓN MATEMÁTICA NATURAL Sea P una propiedad de números naturales o sea: P(n) es una proposición enunciado (matemático)

INDUCCIÓN MATEMÁTICA NATURAL Ejemplos n es par, n > 2 Si n es primo entonces no es par Entonces es un principio (esquema) de demostraciones de enunciados de la forma: P(n) vale para todo n. (Obviamente no es un método para probar "P(n) vale para todo n" cualquiera sea P, sino para hacer evidente que "P(n) vale para todo n" para ciertas P)

INDUCCIÓN MATEMÁTICA NATURAL Si (1) P(0) vale. ("caso base") y (2) asumiendo que P(n) vale. Y podemos demostrar que P(S (n)) vale. ("paso inductivo") entonces : P(n) vale para todo natural n

INDUCCIÓN MATEMÁTICA NATURAL Idea: "Juego de fichas de dominó” Para tirar todas: tirar la primera la distancia entre dos sucesivas debe ser tal que asegure que si cae la previa, entonces ella tira a la siguiente.

INDUCCIÓN MATEMÁTICA NATURAL La misma idea sirve para definir funciones sobre los naturales: f : N -> X "tirar" -> asociarle su imagen en f,  Definir f(n) f(0) = x0 (no depende de f) ("caso base") f(S(n)) = c (n,f(n)) (donde la función c no depende de f) Si la función está definida en 0 y podemos definirla en S(n) usando que está definida en n) entonces queda definida para todo n (RECURRENCIA PRIMITIVA)

Ejemplos fac: N -> N fac 0 = 1 fac (S(n)) = (S(n)) * fac(n) Ej: fac 3 = 3 * fac 2 = 3 * 2 * fac 1 = 3 * 2 * 1 * fac 0 = 3 * 2 * 1 * 1 = 6 Método mecánico de cálculo (simple sustitución) Otro modelo de cómputo (programa) mecánico (funciones recurrentes (recursivas))

Ejemplos (continuación) +: N x N -> N m + 0 = m m + (S n) = S (m + n) *: N x N -> N m * 0 = 0 m * (S n) = (m * n) + m

INDUCCIÓN MATEMÁTICA NATURAL En C usamos notación decimal en lugar de la unaria. Las ecuaciones de la definición de fac se expresan: IF ( n == 0 ) THEN RETURN 1 ELSE RETURN n * Fact(n-1)

Otro ejemplo en C (más complejo) Fib: N -> N (los números de Fibonacci) Fib(0) = 1 Fib(1) = 1 Fib(n+2) = Fib(n) + Fib(n+1) (dos llamadas en distintos puntos) (no es un caso de recurrencia primitiva)

Principio de Inducción Completa Si podemos probar P(n) asumiendo P(z) para todo z < n entonces vale P(n) para todo n. En términos de las fichas de domino: Si una cualquiera se cae toda vez que todas sus predecesoras se caen entonces todas se caen. Notar que toda aplicación de este principio requiere probar la propiedad para 0. (¿Por qué?)

Principio de Inducción Completa Caso general de definición recurrente de funciones f : N -> X Casos Base (no aparece f en las bi) f(n0) = b0 ... f(nk) = bk Casos Recurrentes (las ei pueden depender de f) f(nk+1) = e1 ... f(nk+r) = er

Principio de Inducción Completa Para que f esté definida como función debe probarse, para todo n: EXISTENCIA Y UNICIDAD de f(n) para cada n debe haber una ecuación (caso) que se aplique (exhaustividad) Las llamadas recurrentes deben ser de la forma: f(n) = c(f(m1), ...... , f(mp))   (donde c no depende de f y está bien definida) donde mi < n para cada mi

Principio de Inducción Completa Se justifica por INDUCCION COMPLETA (notar que < es "bien fundado") Metodológicamente pensar los casos de n: Base Reducción a un predecesor (o algunos predecesores)

Listas (ejemplo) Vamos a definir el conjunto de las listas secuenciales finitas de naturales. Inductivamente: [] es una Lista de Naturales SI n : Natural y L : ListaNaturales ENTONCES n.L : ListaNaturales Esas son todas las listas Donde . es la concatenación de listas.

Ejemplos de Listas [] 1.[] ([1]) 2.1.[] ([2,1]) 1.[]   ([1]) 2.1.[] ([2,1]) notación resumida: x1.x2......xn.[] se representa:   [x1,x2,...,xn]

Listas (continuación) Tomamos en consecuencia: Principio de INDUCCIÓN PRIMITIVA ESTRUCTURAL: si P([]) y para todos n y S podemos probar P(n.S) asumiendo P(s) entonces P(S) vale para toda S : NLista Tenemos también el esquema de definición de funciones sobre NListas por RECURRENCIA PRIMITIVA ESTRUCTURAL: f : NLista -> x f([]) = x0 f(x.S) = c(x, S, f(s))

Listas (continuación) Todo lo anterior se generaliza trivialmente a listas de elementos de cualquier tipo: AListas donde A es cualquier tipo (el tipo de los elementos de la lista) Notar que NLista es un conjunto infinito (comparar con tipos de vectores, que son conjuntos de secuencias de un largo dado) !!!

Ejemplos de funciones sobre listas definidas por recurrencia primitiva largo: ALista -> N largo([]) = 0 largo(x.S) = 1 + largo(S) snoc: A x Alista -> Alista snoc(x,[]) = [x] snoc(x,y.S) = y.(snoc(x,S)) Que hace la función snoc?

Que hace la función snoc? La función snoc inserta al elemento x al final de la lista S

Descomposición de listas Problema Escribir una función Pal : NLista -> Bool tal que Pal(S) = true sii S es palíndromo (capicúa)

Descomposición de listas (cont.) Una manera de resolverla: Pal([]) = true Pal([x]) = true Pal(S) = (Primero(S) = Ultimo(S)) & (Pal(Medio(S)) (para S con al menos 2 elementos) donde las funciones Primero, Ultimo y Medio se definirán separadamente

La función Medio La función Medio no puede definirse para toda lista. De hecho: Medio : {S : ALista / S tiene al menos dos elementos} -> Alista Podemos decir:   Medio : ALista -> Lista con la precondición: el argumento debe tener al menos dos elementos

La función Medio Ejemplos similares puenden darse con naturales: mcd : N x N -> N (máximo común divisor) Precondición : los argumentos no pueden ser ambos nulos

La función Medio Medio([x,y]) = [] Medio(x.y.S) = y.Medio(y.S) (S no vacía) Notar los casos considerados. El espacio (dominio) son las listas de al menos dos elementos. Se cumplen exhaustividad y exclusión En el caso de recurrencia, la llamada recurrente respeta la precondición de la función.

La función Medio Fundamental: si se usa una función sin respetar la precondición, no se puede tener ninguna garantía acerca del resultado. Ver que la definición es correcta: Dado S = [z1, ... , zn, zn+1]: Medio(y.S) = [z1, ... , zn] Porque: Medio(x.y.S) = Medio ([x,y,z1, ... , zn,zn+1]) = [y,z1, ... , zn] = y.Medio(y.S) tal como está definido