26
  AN Á LISIS DE  ALGORITMOS Escuela Superior de Cómputo

2_Programación dinámica

Embed Size (px)

DESCRIPTION

Algoritmos avidos, 2_Algoritmos de empate de cadenas, 2_AlgoritmosProbabilistas, 2_Divide y venceras, 2_Programación dinámica, AlgoritmosProgramaciónDinámica, Huffman voraz, Práctica6, Practica7, Practica8

Citation preview

  • ANLISIS DE

    ALGORITMOS Escuela Superior de Cmputo

  • Contenido

    Introduccin

    Programacin dinmica

    Enfoques de la programacin dinmica

    Principio de optimalidad

    Diseo de un algoritmo de programacin

    dinmica

    Ejemplos

    Fibonacci

    Clculo del coeficiente binomial

    Ejercicios: Programacin dinmica de Fibonacci

    y Coeficientes Binomiales

  • Introduccin La tcnica divide y vencers seala 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 idnticos.

    Si aprovechamos la duplicacin, resolviendo cada problema una sola vez, guardando la solucin para su uso posterior entonces tendremos un algoritmo ms eficiente.

  • La idea de la programacin dinmica es evitar repeticin de clculos.

    La base de la programacin dinmica es el razonamiento inductivo:

    Como resolver un problema combinando soluciones para problemas ms pequeos?

    Se resuelven primero los subproblemas ms pequeos y por tanto ms simples. Combinando las soluciones se obtienen las soluciones de ejemplares sucesivamente ms grandes hasta llegar al ejemplar original.

  • Programacin dinmica La programacin dinmica es un mtodo para reducir

    el tiempo de ejecucin de un algoritmo mediante la utilizacin de subproblemas superpuestos y subestructuras ptimas.

    Una subestructura ptima significa que se pueden usar soluciones ptimas de subproblemas para encontrar la solucin ptima del problema en su conjunto.

    Un problema tiene subproblemas superpuestos si se usa un mismo subproblema para resolver diferentes problemas mayores.

  • Los algoritmos divide y vencers estn dentro de los mtodos descendentes.

    Empezar con el problema original y descomponerlo en pasos sucesivos en problemas de menor tamao.

    La programacin dinmica por el contrario, es un mtodo ascendente:

    Resolver primero los problemas pequeos (guardando las soluciones) y despus combinarlas para resolver problemas ms grandes.

    La programacin dinmica hace uso de:

    Subproblemas superpuestos

    Subestructuras ptimas

    Memoizacion

  • En general, se pueden resolver problemas con subestructuras ptimas siguiendo estos tres pasos:

    1. Dividir el problema en subproblemas ms pequeos.

    2. Resolver estos problemas de manera ptima usando este proceso de tres pasos recursivamente.

    3. Usar estas soluciones ptimas para construir una solucin ptima al problema original.

    Los subproblemas se resuelven a su vez dividindolos en subproblemas ms pequeos hasta que se alcance el caso fcil, donde la solucin al problema es trivial.

  • Los subproblemas superpuestos provocan resolver varias veces el mismo problema, ya que la solucin de un subproblema requiere calcular soluciones que otro subproblema tambin tenga que calcular.

    Perder tiempo calculando varias veces la solucin al mismo subproblema se puede evitar guardando las soluciones que ya hemos calculado. Entonces, si necesitamos resolver el mismo problema ms tarde, podemos obtener la solucin de la lista de soluciones calculadas y reutilizarla. Este acercamiento al problema se llama memoizacion (no confundir con memorizacin; en ingls es llamado memoization).

    En programacin dinmica comnmente se utilizan tablas de resultados conocidos que se va generando a medida que se resuelven los subcasos.

  • Originalmente, el trmino de programacin dinmica se refera a la resolucin de ciertos problemas y operaciones fuera del mbito de la Ingeniera Informtica, al igual que haca la programacin lineal. Aquel contexto no tiene relacin con la programacin en absoluto; el nombre es una coincidencia. El trmino tambin lo us en los aos 40 Richard Bellman, un matemtico norteamericano, para describir el proceso de resolucin de problemas donde hace falta calcular la mejor solucin consecutivamente.

    Algunos lenguajes de programacin funcionales, sobre todo Haskell, pueden usar la memoizacion automticamente sobre funciones con un conjunto concreto de argumentos, para acelerar su proceso de evaluacin. Esto slo es posible en funciones que no tengan efectos secundarios.

  • Donde tiene mayor aplicacin la Programacin Dinmica es en la resolucin de problemas de optimizacin. En este tipo de problemas se pueden presentar distintas soluciones, cada una con un valor, y lo que se desea es encontrar la solucin de valor ptimo (mximo o mnimo).

    La solucin de problemas mediante esta tcnica 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 tambin ptima.

  • Enfoques de la programacin dinmica Top-down: El problema se divide en subproblemas, y

    estos se resuelven recordando las soluciones por si fueran necesarias nuevamente. Es una combinacin de memoizacin y recursin.

    Bottom-up: Todos los problemas que puedan ser necesarios se resuelven de antemano y despus 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.

  • Principio de optimalidad Cuando hablamos de optimizar nos referimos a buscar

    alguna de las mejores soluciones de entre muchas

    alternativas posibles. Dicho proceso de optimizacin

    puede ser visto como una secuencia de decisiones que

    nos proporcionan la solucin correcta.

    En este caso sigue siendo posible el ir tomando

    decisiones elementales, en la confianza de que la

    combinacin de ellas seguir siendo ptima, pero ser

    entonces necesario explorar muchas secuencias de

    decisiones para dar con la correcta, siendo aqu donde

    interviene la programacin dinmica.

  • En una secuencia de decisiones ptima toda subsecuencia ha de ser tambin ptima

    Contemplar un problema como una secuencia de

    decisiones equivale a dividirlo en problemas ms

    pequeos y por lo tanto ms fciles de resolver

    como hacemos en Divide y Vencers. La

    programacin dinmica se aplica cuando la

    subdivisin de un problema conduce a:

    Una enorme cantidad de problemas.

    Problemas cuyas soluciones parciales se solapan.

    Grupos de problemas de muy distinta complejidad.

  • Diseo de un algoritmo de programacin

    dinmica Para que un problema pueda ser abordado por esta

    tcnica ha de cumplir dos condiciones:

    La solucin al problema ha de ser alcanzada a travs de

    una secuencia de decisiones, una en cada etapa.

    Dicha secuencia de decisiones ha de cumplir el principio

    de optimalidad.

  • El diseo de un algoritmo de Programacin Dinmica

    consta de los siguientes pasos:

    1. Planteamiento de la solucin como una sucesin

    de decisiones y verificacin de que sta cumple el

    principio de ptimo.

    2. Definicin recursiva de la solucin.

    3. Clculo del valor de la solucin ptima mediante

    una estructura de datos en donde se almacenan

    soluciones a problemas parciales para reutilizar los

    clculos.

    4. Construccin de la solucin ptima haciendo uso

    de la informacin contenida en la estructura de

    datos.

  • Fibonacci

    ()

  • Si se llama a fib(5), se produce un rbol de llamadas que contendr

    funciones con los mismos parmetros varias veces:

    1. fib(5)

    2. fib(4) + fib(3)

    3. (fib(3) + fib(2)) + (fib(2) + fib(1))

    4. ((fib(2) + fib(1)) + (fib(1) + fib(0))) + ((fib(1) + fib(0)) + fib(1))

    5. (((fib(1) + fib(0)) + fib(1)) + (fib(1) + fib(0))) + ((fib(1) + fib(0)) + fib(1))

    En particular, fib(2) se calcula dos veces. En ejemplos mayores, se

    recalculan muchos otros valores de fib, o subproblemas.

    Para evitar este inconveniente, se puede resolver el problema mediante

    programacin dinmica, y en particular, utilizando el enfoque de

    memoizacin (guardar los valores que ya han sido calculados para

    utilizarlos posteriormente). As, rellenaramos una tabla con los

    resultados de los distintos subproblemas, para reutilizarlos cuando haga

    falta en lugar de volver a calcularlos. La tabla resultante sera una tabla

    unidimensional con los resultados desde 0 hasta n.

  • int fibonacci(int n)

    {

    int i;

    if (n

  • int tabla[n]; // tabla {-1,-1,,-1}

    int fibonacci(int n)

    {

    if (n

  • Clculo del coeficiente binomial Los coeficientes binomiales o nmeros combinatorios son

    una serie de nmeros estudiados en combinatoria que indican

    el nmero de formas en que se pueden extraer subconjuntos

    a partir de un conjunto dado. Sin embargo, dependiendo del

    enfoque que tenga la exposicin, se suelen usar otras

    definiciones equivalentes.

    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

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

    Cuntas formas de eleccin

    existen?

  • El nmero de formas de escoger k elementos a partir de

    un conjunto de n, puede denotarse de varias formas:

    (, ),

    (6,2) = 15

    Los nmeros 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.

    El coeficiente binomial es el nmero de

    subconjuntos de k elementos escogidos de un

    conjunto con n elementos

    El coeficiente binomial est dado por la frmula =

    !

    ! !

  • Forma recursiva del coeficiente binomial

    Si se desea calcular C(5,3), Cules son los casos que

    se repiten?

    =

    1 1

    1+

    1

    0

    = 0 =

    0 < <

    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

    }

  • El algoritmo recursivo que los calcula resulta ser de

    complejidad exponencial por la repeticin de los

    clculos que realiza. No obstante, es posible disear un

    algoritmo con un tiempo de ejecucin de orden O(nk)

    basado en la idea del Tringulo de Pascal. Para ello es

    necesario la creacin de una tabla bidimensional en la

    que ir almacenando los valores intermedios que se

    utilizan posteriormente.

  • Se ira construyendo la tabla por filas de arriba hacia

    abajo y de izquierda a derecha mediante el siguiente

    algoritmo de complejidad polinmica (Bottom-up).

    int coef_bino(int n, int k)

    {

    int i, j;

    for(i = 0; i

  • Resultado Triangulo de Pascal

  • Ejercicios: Programacin dinmica de Fibonacci y

    Coeficientes Binomiales

    Entender e implementar los algoritmos basados en

    programacin dinmica de Fibonacci (top down y botton

    up) y de coeficientes binomiales.

    Describir de manera detallada los algoritmos y su

    implementacin.

    *Enviar con su rbrica correspondiente.