Tema 08: Programación dinámica

Slides:



Advertisements
Presentaciones similares
Programación Dinámica  La programación dinámica se suele utilizar en problemas de optimización, donde una solución está formada por una serie de decisiones.
Advertisements

PROGRAMACIÓN I CENTRO DE ESTUDIOS INTEGRADOS EL MARISCAL - CEIM Ing. Luisa Fernanda Arenas Castañeda Feb 6 de 2016.
RECONOCES Y REALIZAS OPERACIONES CON DISTINTO TIPO DE FUNCIONES PROFESORA: XÓCHITL ARIANDA RUIZ ARMENTA MATEMÁTICAS 4 4TO SEMESTRE ENERO 2015 MULTIVERSIDAD.
Tema 4:Combinatoria. 1.Introducción a la combinatoria. 2.Variaciones. 2.1.Sin repetición 2.2.Con repetición 3.Permutaciones 2.1.Sin repetición 2.2.Con.
Dolz, Pablo Joaquín. I.S.F.D Nº 107, Cañuelas. Bs. As. Argentina. Año 2011.
TEMA 4: COMBINATORIA. 1.INTRODUCCIÓN La combinatoria es una rama de la matemática que estudia colecciones finitas de objetos que satisfacen unos criterios.
FUNCIONES, PROSESAMIENTO ELEMENTAL DE DATOS
Introducción a la Programación Multimedial
Universidad autónoma del estado de México
CALCULO DE LÍMITES Elaborado por: Ing. Juan Adolfo Álvarez Martínez Noviembre,
2. Simplificación de funciones booleanas: Método de Karnaugh
Tema 4: COMBINATORIA.
Introducción a la Programación Multimedial
. Primera Open Class Asignatura: Programación Estructurada Tema:
Olimpiadas Chilenas de Informática - Formación
FUNCIONES, PROCESAMIENTO ELEMENTAL DE DATOS
TRIGONOMETRÍA Rama de la matemática que estudia la relación
PARTE II: ALGORÍTMICA Tema 5. Programación dinámica.
COMBINATORIA 4º ESO – CURSO
Características estáticas de los elementos del sistema de medición
Fundamentos de programación
Estructuras de Datos Recursividad.
MAESTRÍA EN CONTROL DE OPERACIONES Y GESTIÓN LOGÍSTICA
Introducción a los algoritmos
Administración.
MATRICES.
CAPÍTULO 9: DETECCIÓN DE LÍNEAS
LA DERIVADA Autor: Victor Manuel Castro González
Características estáticas de los elementos del sistema de medición
TÍTULO DEL PROYECTO Plataformas Computacionales de Entrenamiento, Experimentación, Gestión y Mitigación de Ataques a la Ciberseguridad.
Descripción e interpretación de la estadística
Funciones Cuadráticas.
MÉTODOS NUMÉRICOS ..
Tema 6. Conceptos básicos de programación Clase 1
Apuntes de Matemáticas 2º ESO
Fundamentos de Probabilidad
COMPUTER DATA SYSTEMS CDS.
Algoritmo Conjunto ordenado y finito de pasos que permite hallar la solución de un problema. Una secuencia de pasos que conducen a la realización de una.
ALGORTIMO Y PROGRAMA REDES PETRI
La planeación y la organización de problemas técnicos y el trabajo por proyectos en los procesos productivos.
PROGRAMACION LINEAL UNIVERSIDAD LIBRE 2016
LA FUNCION INFORMATICA
Fundamentos de programación
UNIVERSIDAD ALONSO DE OJEDA FACULTAD DE CIENCIAS ADMINISTRATIVAS
Leyes de los senos y de los cosenos
Diseñar y elaborar algoritmos
EXPERIMENTO FACTORIAL 23
Sabes Que es un ALGORITMO
CONCEPTOS BÁSICOS DE COMPUTACIÓN E HISTORIA
ESTADÍSTICA BÁSICA.
Sucesiones.
Taller de Matemáticas Financieras
HECHO POR EVA OLIVO VERDÚ
Tipos de Datos abstractos
Área de Matemática.
Metodología de la Programación
Estructuras de Datos MC Beatriz Beltrán Martínez Primavera 2018
Introducción a los algoritmos
Tipos de Datos abstractos
Apuntes Matemáticas 2º ESO
Progresiones. La esencia de la matemática no es hacer las cosas simples complicadas, sino hacer las cosas complicadas simples (S. Gudder) Montoya.
Optimización de Procesos.
PROPIEDADES DE LAS FUNCIONES CONTINUAS MATEMÁTICAS II.
.- Es fácil observar que cuantos más puntos dibujamos sobre una recta, más segmentos diferentes se determinan. ____|_______|_____ Dos puntos (A y B)
MC Beatriz Beltrán Martínez Verano 2018
Eduardo Cruz Pérez.
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.
Nelson Baloian, José A. Pino
Carlos Manuel Ortega Avila
Estrategia algorítmica
Transcripción de la presentación:

Tema 08: Programación dinámica Instituto Politécnico Nacional Escuela Superior de Cómputo Análisis de algoritmos Tema 08: Programación dinámica M. en C. Edgardo Adrián Franco Martínez http://www.eafranco.com edfrancom@ipn.mx @edfrancom edgardoadrianfrancom

Contenido Introducción Programación dinámica Enfoques de la programación dinámica Principio de optimalidad Diseño de un algoritmo de programación dinámica Ejemplos Fibonacci Cálculo del coeficiente binomial Análisis de algoritmos 08 Programación dinámica Prof. Edgardo Adrián Franco Martínez

Introducción La técnica divide y vencerás señala que es posible dividir un problema en subproblemas y combinar las soluciones para resolver el problema original. En ocasiones resolver subproblemas nos lleva a considerar subproblemas idénticos. Si aprovechamos la duplicación, resolviendo cada problema una sola vez, guardando la solución para su uso posterior entonces tendremos un algoritmo más eficiente. Análisis de algoritmos 08 Programación dinámica Prof. Edgardo Adrián Franco Martínez

La idea de la programación dinámica es evitar repetición de cálculos. La base de la programación dinámica es el razonamiento inductivo: ¿Como resolver un problema combinando soluciones para problemas más pequeños? Se resuelven primero los subproblemas más pequeños y por tanto más simples. Combinando las soluciones se obtienen las soluciones de ejemplares sucesivamente más grandes hasta llegar al ejemplar original. Análisis de algoritmos 08 Programación dinámica Prof. Edgardo Adrián Franco Martínez

Programación dinámica La programación dinámica es un método para reducir el tiempo de ejecución de un algoritmo mediante la utilización de subproblemas superpuestos y subestructuras óptimas. Una subestructura óptima significa que se pueden usar soluciones óptimas de subproblemas para encontrar la solución óptima del problema en su conjunto. Un problema tiene subproblemas superpuestos si se usa un mismo subproblema para resolver diferentes problemas mayores. Análisis de algoritmos 08 Programación dinámica Prof. Edgardo Adrián Franco Martínez

La programación dinámica por el contrario, es un método ascendente: Los algoritmos divide y vencerás están dentro de los métodos descendentes. Empezar con el problema original y descomponerlo en pasos sucesivos en problemas de menor tamaño. La programación dinámica por el contrario, es un método ascendente: Resolver primero los problemas pequeños (guardando las soluciones) y después combinarlas para resolver problemas más grandes. La programación dinámica hace uso de: Subproblemas superpuestos Subestructuras óptimas Memoizacion Análisis de algoritmos 08 Programación dinámica Prof. Edgardo Adrián Franco Martínez

En general, se pueden resolver problemas con subestructuras óptimas siguiendo estos tres pasos: Dividir el problema en subproblemas más pequeños. Resolver estos problemas de manera óptima usando este proceso de tres pasos recursivamente. Usar estas soluciones óptimas para construir una solución óptima al problema original. Los subproblemas se resuelven a su vez dividiéndolos en subproblemas más pequeños hasta que se alcance el caso fácil, donde la solución al problema es trivial. Análisis de algoritmos 08 Programación dinámica Prof. Edgardo Adrián Franco Martínez

Ejemplo: Fibonacci (Problemas 𝚶( 𝒄 𝒏 ) Análisis de algoritmos 08 Programación dinámica Prof. Edgardo Adrián Franco Martínez

Si se llama a fib(5), se produce un árbol de llamadas que contendrá funciones con los mismos parámetros varias veces: fib(5) fib(4) + fib(3) (fib(3) + fib(2)) + (fib(2) + fib(1)) ((fib(2) + fib(1)) + (fib(1) + fib(0))) + ((fib(1) + fib(0)) + fib(1)) (((fib(1) + fib(0)) + fib(1)) + (fib(1) + fib(0))) + ((fib(1) + fib(0)) + fib(1)) Análisis de algoritmos 08 Programación dinámica Prof. Edgardo Adrián Franco Martínez

Cuando se llega en el árbol a los casos base (señalados en la imagen) evidentemente las llamadas a la función se detienen. Pero también podemos notar que existen varios casos en donde se llama recursivamente a números que ya fueron calculados, por ejemplo el 3. Entonces para subsecuentes llamadas la cantidad de operaciones a calcular se volverían exponenciales y la complejidad aproximada sería 𝑂(𝑐 𝑛 ) lo cuál para un n=20 ya es mucho que calcular (𝑂 ( 1+ 5 2 ) 𝑛 ≈15,127 llamadas a la función). Análisis de algoritmos 08 Programación dinámica Prof. Edgardo Adrián Franco Martínez

Originalmente, el término de programación dinámica se refería a la resolución de ciertos problemas y operaciones fuera del ámbito de la Ingeniería Informática, al igual que hacía la programación lineal. Aquel contexto no tiene relación con la programación en absoluto; el nombre es una coincidencia. El término también lo usó en los años 40 Richard Bellman, un matemático norteamericano, para describir el proceso de resolución de problemas donde hace falta calcular la mejor solución consecutivamente. Algunos lenguajes de programación funcionales, sobre todo Haskell, pueden usar la memorización automáticamente sobre funciones con un conjunto concreto de argumentos, para acelerar su proceso de evaluación. Esto sólo es posible en funciones que no tengan efectos secundarios. Análisis de algoritmos 08 Programación dinámica Prof. Edgardo Adrián Franco Martínez

Memoizacion Los subproblemas superpuestos provocan resolver varias veces el mismo problema, ya que la solución de un subproblema requiere calcular soluciones que otro subproblema también tenga que calcular. Perder tiempo calculando varias veces la solución al mismo subproblema se puede evitar guardando las soluciones que ya hemos calculado. Entonces, si necesitamos resolver el mismo problema más tarde, podemos obtener la solución de la lista de soluciones calculadas y reutilizarla. Este acercamiento al problema se llama memoización (Memoization en inglés) o memorización se diferencia de 'memorización' puesto que el término ya era usado en matemáticas). Análisis de algoritmos 08 Programación dinámica Prof. Edgardo Adrián Franco Martínez

Se puede resolver el problema, utilizando el enfoque de memorización (guardar los valores que ya han sido calculados para utilizarlos posteriormente). Así, rellenaríamos una tabla con los resultados de los distintos subproblemas, para reutilizarlos cuando haga falta en lugar de volver a calcularlos. La tabla resultante sería una tabla unidimensional con los resultados desde 0 hasta n. Análisis de algoritmos 08 Programación dinámica Prof. Edgardo Adrián Franco Martínez

En programación dinámica comúnmente se utilizan tablas de resultados conocidos que se va generando a medida que se resuelven los subcasos. Function Fibonacci (n:int): int; if (n=0) return 0; else if (n=1) return 1; else if (Fib[n]!=NONE) return Fib[n]; else Fib[n]=Fibonacci(n-1)+fibonacci(n-2); Análisis de algoritmos 08 Programación dinámica Prof. Edgardo Adrián Franco Martínez f(4) f(3) f(2) f(1) f(0) f(4) f(3) f(2) f(1) f(0)

Subestructuras óptimas Donde tiene mayor aplicación la Programación Dinámica es en la resolución de problemas de optimización. En este tipo de problemas se pueden presentar distintas soluciones, cada una con un valor, y lo que se desea es encontrar la solución de valor óptimo (máximo o mínimo). La solución de problemas mediante esta técnica se basa en el llamado principio de óptimo enunciado por Bellman en 1957 y que dice: “En una secuencia de decisiones óptima toda subsecuencia ha de ser también óptima”. Análisis de algoritmos 08 Programación dinámica Prof. Edgardo Adrián Franco Martínez

Enfoques de la programación dinámica Top-down: El problema se divide en subproblemas, y estos se resuelven recordando las soluciones por si fueran necesarias nuevamente. Es una combinación de memoización y recursión. Bottom-up: Todos los problemas que puedan ser necesarios se resuelven de antemano y después se usan para resolver las soluciones a problemas mayores. Este enfoque es ligeramente mejor en consumo de espacio y llamadas a funciones, pero a veces resulta poco intuitivo encontrar todos los subproblemas necesarios para resolver un problema dado. Análisis de algoritmos 08 Programación dinámica Prof. Edgardo Adrián Franco Martínez

Fibonacci utilizando (Programación dinámica -Top-down) int tabla[n]; // tabla {-1,-1,…,-1} int fibonacci(int n) { if (n<2) return n; if(tabla[n-1] == -1) tabla[n-1] = fibonacci(n-1); if(tabla[n-2] == -1) tabla[n-2] = fibonacci(n-2); tabla[n] = tabla[n-1] + tabla[n-2]; return tabla[n]; } 𝚶(𝒏) Análisis de algoritmos 08 Programación dinámica Prof. Edgardo Adrián Franco Martínez

Fibonacci utilizando (Programación dinámica - Buttom-up) int fibonacci(int n) { int i; if (n<2) return n; } else tabla[0] = 0; tabla[1] = 1; for(i = 2; i < n; i++) tabla[i] = tabla[i-1] + tabla[i-2]; return tabla[n-1]; 𝚶(𝒏) Análisis de algoritmos 08 Programación dinámica Prof. Edgardo Adrián Franco Martínez

Principio de optimalidad Cuando hablamos de optimizar nos referimos a buscar alguna de las mejores soluciones (solución optima) de entre muchas alternativas posibles. Dicho proceso de optimización puede ser visto como una secuencia de decisiones que nos proporcionan la solución optima. En este caso sigue siendo posible el ir tomando decisiones elementales, en la confianza de que la combinación de ellas seguirá siendo óptima, pero será entonces necesario explorar muchas secuencias de decisiones para dar con la correcta, siendo aquí donde interviene la programación dinámica. Análisis de algoritmos 08 Programación dinámica Prof. Edgardo Adrián Franco Martínez

“En una secuencia de decisiones óptima toda subsecuencia ha de ser también óptima” Contemplar un problema como una secuencia de decisiones equivale a dividirlo en problemas más pequeños y por lo tanto más fáciles de resolver como hacemos en Divide y Vencerás. La programación dinámica se aplica cuando la subdivisión de un problema conduce a: Una enorme cantidad de problemas. Problemas cuyas soluciones parciales se solapan. Grupos de problemas de muy distinta complejidad. Análisis de algoritmos 08 Programación dinámica Prof. Edgardo Adrián Franco Martínez

Diseño de un algoritmo de programación dinámica Para que un problema pueda ser abordado por esta técnica ha de cumplir dos condiciones: La solución al problema ha de ser alcanzada a través de una secuencia de decisiones, una en cada etapa. Dicha secuencia de decisiones ha de cumplir el principio de optimalizad. Análisis de algoritmos 08 Programación dinámica Prof. Edgardo Adrián Franco Martínez

El diseño de un algoritmo de Programación Dinámica consta de los siguientes pasos: Planteamiento de la solución como una sucesión de decisiones y verificación de que ésta cumple el principio de óptimo. Definición recursiva* o iterativa de la solución. Cálculo del valor de la solución óptima mediante una estructura de datos en donde se almacenan soluciones a problemas parciales para reutilizar los cálculos. Construcción de la solución óptima haciendo uso de la información contenida en la estructura de datos. Análisis de algoritmos 08 Programación dinámica Prof. Edgardo Adrián Franco Martínez

Cálculo del coeficiente binomial Los coeficientes binomiales o números combinatorios son una serie de números estudiados en combinatoria que indican el número de formas en que se pueden extraer subconjuntos a partir de un conjunto dado. P.g. Se tiene un conjunto con 6 objetos diferentes {A,B,C,D,E,F}, de los cuales se desea escoger 2 (sin importar el orden de elección). ¿Cuántas formas de elección existen? Análisis de algoritmos 08 Programación dinámica Prof. Edgardo Adrián Franco Martínez A B C D E F A,B A,C A,D A,E A,F B,C B,D B,E B,F C,D C,E C,F D,E D,F E,F

El coeficiente binomial 𝑛 𝑘 está dado por la fórmula 𝑛 𝑘 = 𝑛! 𝑘! 𝑛−𝑘 ! El número de formas de escoger k elementos a partir de un conjunto de n, puede denotarse de varias formas: 𝐶 𝑛, 𝑘 , 𝑛 𝐶 𝑘, 𝑛 𝑘 𝐶 6,2 =6 𝐶 2= 6 2 =15 Los números C(n,k) se conocen como “coeficientes binomiales”, pero es frecuente referirse a ellos como “combinaciones de n en k”, o simplemente “n en k”. Análisis de algoritmos 08 Programación dinámica Prof. Edgardo Adrián Franco Martínez El coeficiente binomial 𝑛 𝑘 es el número de subconjuntos de k elementos escogidos de un conjunto con n elementos El coeficiente binomial 𝑛 𝑘 está dado por la fórmula 𝑛 𝑘 = 𝑛! 𝑘! 𝑛−𝑘 !

Forma recursiva del coeficiente binomial Si se desea calcular C(5,3), ¿Cuáles son los casos que se repiten? 𝑛 𝑘 = 1 𝑛−1 𝑘−1 + 𝑛−1 𝑘 0 𝑠𝑖 𝑘=0 𝑜 𝑘=𝑛 𝑠𝑖 0<𝑘<𝑛 𝑒𝑛 𝑐𝑎𝑠𝑜 𝑐𝑜𝑛𝑡𝑟𝑎𝑟𝑖𝑜 Análisis de algoritmos 08 Programación dinámica Prof. Edgardo Adrián Franco Martínez funcion C(n,k) { Si k = 0 o k = n entonces devolver 1 sino si 0 < k< n devolver C(n-1,k-1) + C(n-1,k) sino devolver 0 }

Coeficiente binomial (Top-down) int tabla[n] [n]; // tabla[][] {-1,-1,…,-1} int coef_bino (int n) { if (k==0||k==n) return 1; else if(k>0&&k<n) if(tabla[n-1][k-1]==-1) tabla[n-1][k-1]=coef_bino(n-1,k-1); if(tabla[n-1][k]==-1) tabla[n-1][k]=coef_bino(n-1,k); return tabla[n-1][k-1]+tabla[n-1][k]; } else return 0; Análisis de algoritmos 08 Programación dinámica Prof. Edgardo Adrián Franco Martínez

El algoritmo recursivo que los calcula resulta ser de complejidad exponencial por la repetición de los cálculos que realiza. No obstante, es posible diseñar un algoritmo con un tiempo de ejecución de orden O(nk) basado en la idea del Triángulo de Pascal. Para ello es necesario la creación de una tabla bidimensional en la que ir almacenando los valores intermedios que se utilizan posteriormente. Análisis de algoritmos 08 Programación dinámica Prof. Edgardo Adrián Franco Martínez

Coeficiente binomial (Bottom-up) Se ira construyendo la tabla por filas de arriba hacia abajo y de izquierda a derecha mediante el siguiente algoritmo de complejidad polinómica (Bottom-up). int coef_bino(int n, int k) { int i, j; for(i = 0; i <= n; i++) tabla[i][0] = 1; for(i = 1; i<= n; i++) tabla[i][1] = i; for(i = 2; i<= k; i++) tabla[i][i] = 1; for(i = 3; i <= n; i++) for(j = 2; j <= i-1; j++) if(j <= k) tabla[i][j] = tabla[i-1][j-1] + tabla[i-1][j]; return tabla[n][k]; } Análisis de algoritmos 08 Programación dinámica Prof. Edgardo Adrián Franco Martínez

Resultado Triangulo de Pascal Análisis de algoritmos 08 Programación dinámica Prof. Edgardo Adrián Franco Martínez