Está en la página 1de 15
rogramacién dinamica En el capitulo anterior vefamos que es posible dividir los ejemplares en sul jemplares, resolver los subejemplares (posiblemente, subdividiéndolos nuevo) y combinar entonces las soluciones de los subejemplares para resol el caso original. A veces sucede que la forma natural de dividir un ejemplar, como lo sugiere la estructura del problema, nos lleva a considerar subejemp res solapados. Si los resolvemos todos independientemente, éstos darén a su lugar a toda una coleccién de subejemplares idénticos. $i no prestamos aten aesta duplicacién, es probable que acabemos por tener un algoritmo ineficier si por el contrario aprovechamos la duplicacién y nos las arreglamos para res ver cada subejemplar una sola vez, guardando la solucién para su uso posteri entonces tendremos un algoritmo mas eficiente. La idea que subyace a la p gramacién dindmica es, por tanto, bastante sencilla: evitar calcular dos ve: una misma cosa, normalmente manteniendo una tabla de resultados conacic que se vaya Ilenando a medida que se resuelven los subcasos. El método de divide y vencerds es un método de refinamiento progresivo. Cus do se resuelve un problema mediante divide y vencerds, atacamos de inmedi: el. caso completo, que a continuacién dividimos en subcasos mds y més pequeA a medida que progresa el algoritmo. La programacién dindmica, por otra parte, una técnica ascendente. Normalmente, se empieza por los subcasos mas pequen y por tanto més sencillos. Combinando sus soluciones, obtenemos las respues para subcasos de tamaios cada vez mayores, hasta que finalmente llegamos ¢ solucién del caso original ‘Comenzaremos el capitulo por dos ejemplos sencillos de programacién dinar ca, que ilustran la técnica general en una situacién poco complicada. Las secciot Programacién dindmica Capitule siguientes abordan los problemas de devolver cambio, que mencionébamos en Seccién 6.1, y el dela mochila, que encontrébamos en la Seccidn 65. 8.1 DOS EJEMPLOS SENCILLOS 8.1.1 Calculo del coeficiente binomial ‘Considere el problema consistente en calcular el coeficiente binomial ff) seer ‘Supongamos que 0 SS 1, Si calculamos directamente ({) mediante funei6n CC, b) sik =00k=n entonces devolver 1 sino devolver C(—1, k-1) + Cit-1, entonces muchos de los valores de C(i, j), con # 1 en donde ¢ y d son constantes. Reescribiendo T(k-1) en términos de TUk-2), ¥ asi sucesivamente, obtenemos Capitulc TU) <4T(k-2)+ ded, kod S2UITUD + (244 Be DED = he 4 (Dt = Me/2#d/2t Por tanto TU) esté en O12, que es O14") si i = j= st, De hecho, si examinamos forma en que se generan las lamadas recursivas, encontramos e] patron que muestra en la figura 8.2, que es idéntico al calculo menos sofisticado del cor ciente binomial, Para ver esto imaginemos que toda llamada a Pins, n) en la fig ra se sustituye por Cf + 11,1. De esta manera, P(i, 1) se sustituye por Ci + i, ),Pli- 1, /) se sustituye | CG + j-1, Py PG, FD se sustituye por Cli + j—1, 1). Ahora el patrén de flan das que muestran las flechas corresponde al calculo CU + P= CU + j-1, + CG 4j-1, 7-0) de un coeficiente binomial. El mimero total de Ilamadas recursivas, por tanto, exactamente de 2";")-2; véase el Problema 8.1. Asi pues para calcular la proba lidad Pl, 2) de que el equipo A sea el ganador, dado que todavia no ha empe do el campeonato, el tiempo requerido esta, por tanto, en Q' >. PG, k corresponde a izquien lama oa PG-LD Pi j=. L corresponde a izquien quellama ua ak PG,-2,)) PU-Lf-1) PU, ,-2) k—2 corresponde a izquien ete. Figura 8.2, Hamadas recursivas efectuadas por una Uamada a Pe.) E] Problema 1.42 pide al lector demostrar que "24" / Qi + D. Combinando tos resultados, se ve que el tiempo necesario para calcular P(i, n) esta. en OCA en QW / 1). El método, por tanto, no resulta practico para valores grandes de (Aun cuando las competiciones deportivas con 1 > 4 sean la excepcién, jeste p blema tiene otras aplicaciones!) Para acelerar el algeritmo, procederemos mas menos igual que con el tri gulo de Pascal: declaramos un vector del tamaito adecuado y después vamos llenando las entradas. Esta vez, sin embargo, en lugar de ir llenando el vector nea por linea, vamos. a trabajar diagonal por diagonal. Este es el algoritmo p: calcular Po, 1) cién 8.2 Devolver cambio (2). funcién serie(, p) matriz P(0..»,0..n) qe l-p {Llenamos desde la esquina izquierda hasta la diagonal principal} para s+ 1 hasta n hacer PIO, s) 1; Pls, 0] — 0 parak < 1 hasta s~1 hacer lk, s-k] = pP[k-1, s—k] + P[k, s—k-1] {Llenamos desde debajo de la diagonal principal hasta la esquina derecha} paras ~ 1 hasta n hacer para k < 0 hasta 1 ~s hacer Pls + ky n-K]— PIs + k—1, n—Kl + qPls + k,n -k—1] devolver Piri, 1] Dado que el algoritmo tiene que Henar una matriz mx n, y dado que se necesita una constante temporal para calcular cada entrada, su tiempo de ejecucién se encuentra en O(rr). Aligual que en el triingulo de Pascal, resulta sencillo implementar este al- goritme de tal manera que baste con un espacio de almacenamiento en @(). 2 DEVOLVER CAMBIO (2) Recuerde que el problema consiste en desarrollar un algoritmo para pagar una cier- tacantidad a un cliente, empleando el menor nimero posible de monedas. En la Sec- ci6n 6.1 describiamos un algoritmo voraz para este problema. Desafortunadamen- te, aunque el algoritmo voraz es muy eficiente, funciona solamente en un niimero limitado de casos. Con ciertos sistemas monetarios, o cuando faltan monedas de una cierta denominacién (0 su nimero es limitado), el algoritmo puede encontrar una respuesta que no sea dptima, o incluso puede no hallar respuesta ninguna. Por ejemplo, supongamos que vivimos en un lugar en el cual hay monedas de 1,4 y 6 unidades. Si tenemos que cambiar & unidades, el algoritmo voraz propon- drd hacerlo con una moneda de 6 unidades y dos de una unidad, con un total de tres monedas. Sin embargo, estd claro que podemos hacerlo mejor: basta con dar al cliente su cambio empleando tan sélo dos monedas de cuatro unidades. Aun- que el algoritmo voraz no halla esta solucién, resulta sencillo obtenerla emplean- do programacién dinamica. Como en la seccién anterior, el guid del método consiste en preparar una ta- bla que contenga resultados intermedias ittiles, que seran combinados en la so- lucién del caso que estamos considerando. Supongamos que el sistema moneta- rio que estamos considerando tiene monedas de 1 denominaciones diferentes, y que una moneda de denominacién i, con 1« i< 1 tiene un valor de d, unidades. Supondremos, como es habitual, que todos los d, > 0. Por el momento, supon- dremos también que se dispone de un suministro ilimitado de monedas de cada denominacién. Por ultimo, supongamos que tenemos que dar al cliente monedas por valor de N unidades, empleando el menor nimero posible de monedas. 6 Programacién dinamica Capitulo Para resolver este problema mediante programaci6n dindmica, preparan una tabla ¢[1..n, 0..N] con una fila para cada denominacién posible y una colum para las cantidades que van desde 0 unidades hasta N unidades. En esta tabla, j] serd el ntimero mfnimo de monedas necesarias para pagar una cantidad ck unidades, con 0 = j < N, empleando solamente monedas de las denominaci desde 1 hasta i, con 1 si <1. La solucién del ejemplar, por tanto, esta dada | clu, N] si lo Gnico que necesitamos saber es el niimero de monedas que se nec¢ tan, Para rellenar la tabla, obsérvese primero que cli, 0) es cero para todos los lores de f. Después de esta inicializacién, la tabla se puede rellenar o bien fila | fila de izquierda a derecha, 0 bien columna por columna avanzando hacia ab: Para abonar una cantidad j utilizando monedas de las. denominaciones entre 1 tenemos dos opciones en general. En primer lugar, podemos decidir que no ut zaremos monedas de la denominacién i, aun cuando esto est permitido ahora, cuyo caso cli, j] = efi - 1, j]. Como alternativa, podemos decidir que emplearen al menos una moneda de la denominacién i. En este caso, una vez que hayan entregado la primera moneda de esta denominaci6n, quedan por pagar j—d, u dades. Para pagar esto se necesitan cli, j—d)] unidades, asi que cfi, j] = 1 + cli, j~ Dado que deseamos minimizar el némero de monedas utilizadas, seleccionaren aquella alternativa que sea mejor. En general, por tanto: cli, fl = min(cli-1, jJ+cli, j- 4) ‘Cuando i = 1, uno de los elementos que hay que comparar cae fuera de la tabla. mismo sucede cuando j < d.. Resulta cémodo pensar que tales elementos poseet valor +. Sii = 1 yj < d, entonces los dos elementos que hay que comparar cz fuera de la tabla. En este caso, hacemos ¢[i, ] igual a +2 para indicar que es i posible pagar una cantidad j empleando solamente monedas del tipo 1 La figura 8.3 ilustra el caso dado anteriormente, en el que teniamos que paj 8 unidades con monedas que valian 1, 4 y 6 unidades. Por ejemplo, c[3, 8] se « tiene en este caso como el menor de c[2, §]= 2 y 1 + 43,8- dj = 1+ c[3,2] = 3.1 entradas en el resto de la tabla se obtienen de forma similar. La respuesta para te caso concreto es que podemos pagar ocho unidades empleando tnicamente « monedas. De hecho, la tabla nos da la solucién de nuestro problema para todos casos que supongan un pago de 8 unidades o menos. Cantidad: | 0 1 2 3 4 5 6 7 8 ae1 o 1 2 3 4 «5 6 7 8 = 4 o 1 2 3 1 2 3 4 2 4-6 o 1 2 3 12 1 2 2 Figura 8.3 Devolver cambio empleando programacién dinémica \Véase a continuaci6n una versién mas formal del algoritmo: cién 8.2 Devolver cambio (2) 7 funeién mowedas(N) {Devuelve el minimo niimero de monedas necesarias para cambiar N unidades. Fl vector {1 .] especifica las denominaciones: en el ejemplo hay monedas de 1, 4 y 6 unidades} vector d[1. = [1, 4, 6) matriz.¢{1..i, O..N] para i <1 hasta hacer cli, 0] —0 para i <1 hasta hacer para j <— 1 hasta N hacer sii Ly j 0, > Oy x,€ 10, 1} para 1 Sin. Aqui las condiciones que afectan av, y am; son limitaciones que afectan al caso; las de, son restricciones que afectan a la s0- lucién, Dado que el problema se parece mucho al de la Seccién 6.5, es natural pre- guntarse en primer lugar si una ligera modificacién del algoritme voraz que utilizé- bamos antes podria funcionar ahora. Supongamos entonces que se adapta el algorit- mo de la forma evidente, de tal modo que vaya examinando los objetos en orden des cendente de valor por unidad de peso. Si la mochila no esta Ilena, el algoritmo tiene que seleccionar un objeto completo si es posible, antes de pasar al siguiente. 9. Programacién dindmica Desafortunadamente, el algoritmo voraz no funciona cuando x, tiene que se bien 0 o bien 1. Por ejemplo, supongamos que estan disponibles tres objetos, el p mero de los cuales pesa 6 unidades y tiene un valor de 8, mientras que los ott dos pesan 5 unidades cada uno y tienen un valor de 5 cada uno. Si la mochila pt de llevar 10 unidades, entonces la carga éptima incluye a los dos objetos mas eros, con un valor total de 10. E! algoritmo voraz, por otra parte, comenzaria p seleccionar el objeto que pesa 6 unidades, puesto que es el que tiene un mayor + lor por unidad de peso. Sin embargo, si los objetos no se pueden romper, el alg ritmo no podra utilizar la capacidad restante de la mochila. La carga que produ: por tanto, consta de un sole objeto, y tiene un valor de 8 nada mas. Para resolver el problema por programacién dindmica, preparamos una tal V{1..n, 0..] que tiene una fila para cada objeto disponible, y una columna pe cada peso desde 0 hasta W. En la tabla, V\j, j] sera el valor maximo de los objet que podemos transportar si el limite de peso es j, con 0-< j s W, si solamente cluimos los objetos numerados desde el 1 hasta el i, con 1 si

También podría gustarte