Docsity
Docsity

Prepara tus exámenes
Prepara tus exámenes

Prepara tus exámenes y mejora tus resultados gracias a la gran cantidad de recursos disponibles en Docsity


Consigue puntos base para descargar
Consigue puntos base para descargar

Gana puntos ayudando a otros estudiantes o consíguelos activando un Plan Premium


Orientación Universidad
Orientación Universidad


Programación Dinámica: Resolución de Problemas de Optimización, Apuntes de Investigación de Operaciones

METODOS DE PROGRAMACIÓN DINAMICA

Tipo: Apuntes

2018/2019

Subido el 13/10/2019

Marleny150799
Marleny150799 🇵🇪

4.5

(4)

8 documentos

1 / 22

Toggle sidebar

Esta página no es visible en la vista previa

¡No te pierdas las partes importantes!

bg1
Capitulo 4. Programación Dinámica
Introducción
Una forma razonable y comúnmente empleada de resolver un problema es definir o
caracterizar su solución en términos de las soluciones de subproblemas del mismo. Esta
idea, cuando se emplea recursivamente, proporciona métodos eficientes de solución
para problemas en los que los subproblemas son versiones mas pequeñas del problema
original.
Una técnica de diseño de algoritmos, que sigue esta idea, es la conocida como divide
y vencerás que hemos estudiado en temas anteriores. Como allí se explicó, consiste
en descomponer cada problema en un numero dado de subproblemas, resolver cada
uno de ellos (quizás empleando el mismo método) y combinar estas soluciones
parciales para obtener una solución global. Desde el punto de vista de la complejidad de
los algoritmos que se obtienen por este procedimiento, lo mejor es que todos los
subproblemas tengan dimensión similar y que la suma de estas sea lo menor posible. No
obstante, en muchos casos, dado un problema de tamaño n solo puede obtenerse una
caracterización efectiva de su solución en términos de la solución de los
subproblemas de tamaño n-1 (n en total) lo que puede aplicarse recursivamente. En
estos casos, la técnica conocida como Programación Dinámica (PD) proporciona
algoritmos bastante eficientes. Algunos de estos problemas ya los conocemos. Es el
caso, por ejemplo, del Problema de la Mochila o del Problema del Camino Mínimo.
En efecto, para el primero, su solución puede entenderse como el resultado de una
sucesión de decisiones. Tenemos que decidir los valores de xi, 1 i n. Así, primero
podríamos tomar una decisión sobre x1 , luego sobre x2 , etc. Una sucesión optimal de
decisiones, verificando las restricciones del problema, será la que maximice la
correspondiente función objetivo. En el caso del camino mínimo, una forma de encontrar
ese camino mínimo desde un vértice i a otro j en un grafo dirigido G, es decidiendo que
vértice debe ser el segundo, cual el tercero, cual el cuarto, etc. hasta que
alcanzáramos el vértice j. Una sucesión optimal de decisiones proporcionaría entonces el
camino de longitud mínima que buscamos.
El nombre Programación Dinámica y la metodología que subyace en él lo ha tomado la
Teoría de Algoritmos de la Teoría de Control, donde la Programación Dinámica es una
técnica para obtener la política optima en problemas de control con n etapas,
caracterizando esta en términos de la política optima para un problema similar, pero con
n-1 etapas. Por este motivo comenzamos nuestra exposición analizando el método
de la Programación Dinámica en su contexto original, para pasar después a su
formulación dentro de la Teoría de Algoritmos.
El Lugar de la Programación Dinámica
El problema mas importante en la Teoría de Control es el del control optimal. Un típico
proceso supone en este contexto cuatro tipos de variables,
1. Variables independientes, que son las variables manipulables para el control del
proceso.
2. Variables dependientes, que sirven para medir y describir el estado del proceso en
cualquier instante de tiempo.
pf3
pf4
pf5
pf8
pf9
pfa
pfd
pfe
pff
pf12
pf13
pf14
pf15
pf16

Vista previa parcial del texto

¡Descarga Programación Dinámica: Resolución de Problemas de Optimización y más Apuntes en PDF de Investigación de Operaciones solo en Docsity!

Capitulo 4. Programación Dinámica

Introducción

Una forma razonable y comúnmente empleada de resolver un problema es definir o caracterizar su solución en términos de las soluciones de subproblemas del mismo. Esta idea, cuando se emplea recursivamente, proporciona métodos eficientes de solución para problemas en los que los subproblemas son versiones mas pequeñas del problema original.

Una técnica de diseño de algoritmos, que sigue esta idea, es la conocida como divide y vencerás que hemos estudiado en temas anteriores. Como allí se explicó, consiste en descomponer cada problema en un numero dado de subproblemas, resolver cada uno de ellos (quizás empleando el mismo método) y combinar estas soluciones parciales para obtener una solución global. Desde el punto de vista de la complejidad de los algoritmos que se obtienen por este procedimiento, lo mejor es que todos los subproblemas tengan dimensión similar y que la suma de estas sea lo menor posible. No obstante, en muchos casos, dado un problema de tamaño n solo puede obtenerse una caracterización efectiva de su solución en términos de la solución de los subproblemas de tamaño n-1 (n en total) lo que puede aplicarse recursivamente. En estos casos, la técnica conocida como Programación Dinámica (PD) proporciona algoritmos bastante eficientes. Algunos de estos problemas ya los conocemos. Es el caso, por ejemplo, del Problema de la Mochila o del Problema del Camino Mínimo.

En efecto, para el primero, su solución puede entenderse como el resultado de una sucesión de decisiones. Tenemos que decidir los valores de xi, 1 ≤ i ≤ n. Así, primero podríamos tomar una decisión sobre x 1 , luego sobre x 2 , etc. Una sucesión optimal de decisiones, verificando las restricciones del problema, será la que maximice la correspondiente función objetivo. En el caso del camino mínimo, una forma de encontrar ese camino mínimo desde un vértice i a otro j en un grafo dirigido G, es decidiendo que vértice debe ser el segundo, cual el tercero, cual el cuarto, etc. hasta que alcanzáramos el vértice j. Una sucesión optimal de decisiones proporcionaría entonces el camino de longitud mínima que buscamos.

El nombre Programación Dinámica y la metodología que subyace en él lo ha tomado la Teoría de Algoritmos de la Teoría de Control, donde la Programación Dinámica es una técnica para obtener la política optima en problemas de control con n etapas, caracterizando esta en términos de la política optima para un problema similar, pero con n-1 etapas. Por este motivo comenzamos nuestra exposición analizando el método de la Programación Dinámica en su contexto original, para pasar después a su formulación dentro de la Teoría de Algoritmos.

El Lugar de la Programación Dinámica

El problema mas importante en la Teoría de Control es el del control optimal. Un típico proceso supone en este contexto cuatro tipos de variables,

  1. Variables independientes, que son las variables manipulables para el control del proceso.
  2. Variables dependientes, que sirven para medir y describir el estado del proceso en cualquier instante de tiempo.
  1. Variables producto, que se usan para indicar y medir la calidad de la tarea que realiza el sistema de control, y
  2. Ruidos, que son variables incontrolables que dependen del ambiente en el que el sistema lleve a cabo su operación.

El problema general del control optimal de un proceso consiste en determinar la forma en que las variables producto pueden mantenerse en valores optimales, independientemente de las fluctuaciones que los ruidos, o los cambios de parámetros, puedan causar. Las variables producto se usan para describir el índice de eficacia del control del sistema. Así el problema del control optimo supone la optimización (maximización o minimización) de ese índice de eficacia.

Generalmente, un sistema físico de n-esimo orden puede describirse en cualquier instante de tiempo t por medio de un conjunto finito de cantidades (x 1 (t), x 2 (t),..., xn(t)). Estas cantidades se conocen como las variables de estado del sistema, y constituyen las componentes del vector de estado del sistema: x(t). La relación entre los cambios del parámetro tiempo y las variables de estado del sistema, se establece mediante una sencilla y útil hipótesis como es que la derivada del vector de estado, dx/dt, solo dependa del estado del sistema en curso y no de su historia anterior. Esta hipótesis básica lleva a una caracterización matemática del proceso por medio de una ecuación diferencial vectorial,

dx(t)/dt = f[x(t), m(t), t]

con la condición inicial x(0) = x 0. En esa ecuación m(t) nota el vector de control, y f es una función vectorial de las variables de estado, las señales de control, el tiempo y, posiblemente, las variables ambientales o ruidos externos. En cada instante, el vector de control m debe satisfacer la condición,

g(m) ≤ 0

que refleja las restricciones que el control del sistema tenga. La función g es una función conocida de la señal de control. Entonces, el problema del diseño de un control optimal puede plantearse en los siguientes términos: Dado un proceso que debemos controlar, determinar la ley de control, o sucesión, tal que el conjunto de índices de eficacia, previamente fijado, sea optimo.

A veces, las variables de estado de un sistema son todas accesibles para medirlas y observarlas. Para los sistemas lineales que tienen esta característica, aun en presencia de ruido, puede tratarse directamente de determinar la ley de control optimal como una función de las variables de estado. Sin embargo, es bastante frecuente que las variables de estado no sean todas accesibles para medirlas y observarlas. Entonces, la ley de control optimal se determina como una función de las mejores estimaciones de las variables de estado, que se calculan a partir de las señales de salida del sistema que se hayan medido. Por tanto, en el caso mas general, tendremos que considerar la resolución de problemas de control optimal y de estimación optimal.

La Teoría de Control parte de la caracterización de un sistema mediante sus variables de estado y del diseño del sistema por medio de técnicas basadas en su representación como espacio de estados. En una formulación general, el diseño del control optimal se ve generalmente como un problema variacional. Pero hay muchos métodos variacionales para optimizar un funcional sobre un espacio de funciones. El rango de tales métodos va desde los métodos clásicos del calculo de variaciones, a las técnicas numéricas de aproximaciones sucesivas de modelos experimentales. Entre los métodos mas frecuentemente usados para el diseño de sistemas de control están,

Los problemas de decisión multietápica pueden resolverse muy bien por medio del enfoque funcional, según el cual el problema de maximización original se convierte en un problema de determinar la solución de una ecuación funcional que se obtiene como sigue. El beneficio durante el primer año es,

Y 1 (x,y) = g(y) + h(x-y)

Así, para un periodo de un año, la máxima recompensa la da,

f 1 (x) = Max 0 ≤y≤x {Y 1 (x,y)} = Max 0 ≤y≤x {g(y) + h(x-y)} (1)

Nótese que la recompensa máxima es función de la cantidad a invertir inicialmente. Cuando g y h se conocen, ese máximo puede evaluarse mediante un proceso sencillo de derivación. Así que, en este caso de un año, el problema es trivial.

En nuestro caso, el dinero que queda para tratar, tras un año de operación, es la cantidad destinada al cambio de los CTT y los CCR, debido a la hipótesis de que los beneficios no se reinvierten. Por tanto, la cantidad de capital durante el segundo año de operación es,

x 1 = ay + b(x-y)

que escribiremos como

x 1 = y 1 + (x 1 –y 1 )

donde y 1 es la cantidad gastada en la adquisición de nuevos CTT y x 1 -y 1 la gastada en CCR. Entonces, durante el segundo año de operación tenemos,

 Beneficios de la inversión en CTT = g(y 1 )  Beneficios de la inversión en CCR = h(x 1 -y 1 )

y, al final del segundo año,

 Valor del cambio de CTT = ay 1  Valor del cambio de CCR = b(x 1 -y 1 )

Con lo que el beneficio total tras dos años de operación es,

Y 2 (x,y,y 1 ) = g(y) + h(x-y) + g(y 1 ) + h(x 1 -y 1 )

y la recompensa máxima tras esos dos años es,

f 2 (x) = Max (^0) ≤y≤x, 0≤y1≤x1 {Y 2 (x,y,y 1 )} = Max (^0) ≤y≤x, 0≤y1≤x1 {g(y)+h(x-y)+g(y 1 )+h(x 1 -y 1 )}

o bien, de acuerdo con la expresión (1),

f 2 (x) = Max (^0) ≤y≤x, 0≤y1≤x1 {g(y) + h(x-y) +f 1 (x 1 )}

con lo que, sustituyendo tenemos para el máximo beneficio,

f 2 (x) = Max (^0) ≤y≤x {g(y) + h(x-y) + f 1 [ay + b(x-y)]}

Esta ecuación supone que el máximo producido durante un periodo de dos años, puede determinarse derivando las funciones en ella, de acuerdo con las restricciones que comportan. El valor de y(x) que maximice esas funciones será la decisión optima a tomar al principio de una operación bianual que comienza con una cantidad x.

El análisis puede repetirse para una operación trianual y obtendríamos que,

f 3 (x) = Max (^0) ≤y≤x {g(y) + h(x-y) + f 2 [ay + b(x-y)]}

y así sucesivamente. Por tanto, para un periodo de N años, la recompensa máxima vendrá dada por,

fN(x) = Max (^0) ≤y≤x {g(y) + h(x-y) + fN-1 [ay + b(x-y)]} (2)

Esta es la ecuación funcional básica para este proceso de decisión N-etápico. Comenzando con f 1 (x), como lo determina (1), esta ecuación funcional se usa para calcular f 2 (x), que luego se usa para calcular f 3 (x),... En cada etapa, se obtiene también la decisión optima yj(x) a tomar al comienzo de la j-esima etapa. El valor de y(x) que maximiza las funciones entre corchetes en (2) es la decisión optimal a tomar al comienzo de la operación del año N, supuesto que inicialmente comenzamos con una cantidad x.

Para la obtención de la solución por un método directo, tendríamos que resolver las N ecuaciones simultaneas que se obtienen igualando a cero las correspondientes derivadas parciales, supuesto que esas ecuaciones fueran derivables, lo que se prevé complicado.

El Principio de Optimalidad

Como hemos visto, el enfoque funcional expuesto sirve para el estudio de los procesos de decisión multietápicos de modo que, aplicando repetidamente la ecuación funcional, se puede encontrar la sucesión de decisiones optimas para el proceso N- etápico considerado. Aunque el problema de inversión comentado se ha escogido como ilustración, el enfoque funcional proporciona una herramienta muy útil en general para resolver problemas de decisión multietápicos. Sin embargo, ahora nos vamos a dedicar a introducir el Principio de Optimalidad, que nos permitirá obtener la ecuación funcional que describe un proceso de decisión multietápico como una consecuencia inmediata.

Consideremos, en primer lugar, un proceso de decisión uni-etápico. Sea x el vector de estado que caracteriza al sistema físico en cuestión en cualquier instante de tiempo. Suponemos que x es un vector columna k-dimensional. Si el estado del sistema se transforma de x^1 a x^2 por medio de la transformación,

x^2 = g(x^1 , m 1 )

esta transformación producirá una respuesta, o recompensa,

R 1 = r(x^1 , m 1 )

El problema consiste en elegir una decisión m 1 que maximice la respuesta. A la decisión m 1 se le llama política uni-etápica. Esta claro que la solución a este problema de decisión uni-etápico no tiene dificultad, porque el máximo de la respuesta esta dado por,

f 1 (x^1 ) = Max (^) m1 {r(x^1 , m 1 )}

La decisión que da el máximo valor de la salida, se llama una decisión optimal, o estrategia de control optimal.

En un proceso de decisión bi-etápico, si el estado del sistema se transforma, primero, de x^1 a x^2 por la transformación,

x^2 = g(x^1 , m 1 )

y después, de x^2 a x^3 por,

x^3 = g(x^2 , m 2 )

esta sucesión de operaciones produce una única salida, o recompensa total,

R 2 = r(x^1 , m 1 ) + r(x^2 , m 2 )

Entonces, en este caso, el problema del diseño optimal consiste en elegir una sucesión de decisiones factibles m 1 y m 2 que maximicen la recompensa total. Este es

optimización multietápico original, por el problema de resolver una sucesión de procesos de decisión uni-etápicos que, indudablemente, son mas fáciles de manejar.

Como antes hemos deducido, para el proceso N-etápico que considerábamos el problema consiste en elegir aquella política N-etápica {m 1 , m 2 ... ,mN} tal que maximice la recompensa total,

RN = j r(xj, mj) , j∈J = {1,2,...,N}

Ahora, de acuerdo con el Principio de Optimalidad, la recompensa total del mismo proceso de decisión multietápico puede escribirse como,

RN = r(x^1 , m 1 ) + fN-1[g(x^1 , m 1 )]

donde el primer termino, del miembro de la derecha, es la recompensa inicial y el segundo representa la recompensa máxima debida a las ultimas N-1 etapas. Por tanto, la recompensa máxima estará dada por,

fN (x^1 ) = Max (^) m1 {r(x^1 , m 1 ) + fN-1[g(x^1 , m 1 )]}

Esta ecuación es valida solo para N ≥ 2, pero para N = 1 la recompensa máxima estaría dada por,

f 1 (x^1 ) = Max (^) m1 {r(x^1 , m 1 )}

Es obvio que, aplicando este principio fundamental, un proceso de decisión N-etápico se reduce a una sucesión de N procesos de decisión uni-etápicos, con lo que disponemos de un procedimiento iterativo y sistemático para resolver eficientemente aquel problema.

El enfoque de la PD

A la vista de lo anterior, para abordar la resolución de un problema con la técnica de la PD, habría que verificar, en primer lugar, la naturaleza N-etápica del problema bajo consideración, para caracterizar la estructura de una solución optimal. Posteriormente, se tendría que comprobar el cumplimiento del Principio de Optimalidad de Bellman como condición absolutamente necesaria para su aplicación, y si este se verificara, apoyándose en su propio significado en el caso concreto que estemos resolviendo, formular una ecuación de recurrencias que represente la forma de ir logrando etapa por etapa la solución optimal correspondiente. A partir de esa ecuación, a continuación, habrá que determinar la solución optimal resolviendo problemas encajados para, por ultimo, construir la solución. Con esos ingredientes, se podría iniciar la solución del problema que, a su vez, podría realizarse desde el primer estado hasta el ultimo, o bien a la inversa.

De forma mas concisa, el desarrollo de un algoritmo de PD correspondería a las siguientes etapas:

1.- Caracterizar la estructura de una solución optimal

2.- Definir recursivamente el valor de una solución optimal

3.- Calcular el valor de una solución optimal en forma encajada de menos a mas, y

4.- Construir una solución optimal a partir de la información previamente calculada.

Las etapas 1-3 constituyen la base de la solución de PD para un cierto problema. La etapa 4 puede omitirse si lo único que buscamos es el valor de una solución optimal. Cuando se realiza la etapa 4, a veces mantenemos información adicional durante la etapa 3 para facilitar la construcción de una solución optimal.

Vemos así que la PD, igual que la técnica Divide y Vencerás, resuelve problemas combinando las soluciones de subproblemas. Como sabemos, los algoritmos Divide y Vencerás particionan el problema en subproblemas independientes, resuelven estos recursivamente, y combinan sus soluciones para obtener la solución del problema original. En contraste, la PD es aplicable cuando los subproblemas no son independientes, es decir, cuando los subproblemas comparten sub-subproblemas. En este contexto, un algoritmo Divide y Vencerás hace mas trabajo del necesario, ya que resuelve repetidamente sub-subproblemas comunes. Un algoritmo de PD resuelve cada sub-subproblema solo una vez, salvando su solución en una tabla de cara a evitar el trabajo de recalcular la solución cada vez que se encuentra ese sub-subproblema.

Por otro lado, el enfoque que define la PD tiene también ciertos parecidos con el que propone la técnica greedy, pero la diferencia esencial entre el método greedy y el de la PD es que en el primero siempre se generaba solo una sucesión de decisiones, mientras que en PD pueden generarse muchas sucesiones de decisiones. Sin embargo las sucesiones que contengan subsucesiones suboptimales no pueden ser optimales (si se verifica el Principio de Optimalidad), y por tanto no se generaran. Pensemos por ejemplo en el problema del camino mínimo. Si queremos encontrar el camino de longitud mínima entre el vértice i y el j, sea A el conjunto de vértices adyacentes desde i. ¿Cual de los vértices en A debe ser el segundo vértice del camino?. No hay forma de tomar esa decisión en ese momento y garantizar que las decisiones futuras producirán una solución optimal.

Por ultimo, en lo que se refiere a similitudes, otra forma de resolver problemas en los que no es posible conseguir una sucesión de decisiones que, etapa por etapa, formen una sucesión optimal, es intentarlo sobre todas las posibles sucesiones de decisiones, es decir, lo que comúnmente se llama enfoque de la fuerza bruta. Según esa metodología, lo que se hace es enumerar todas esas sucesiones, y entonces tomar la mejor respecto al criterio que se este usando como objetivo. La PD haciendo uso explícito del Principio de Optimalidad de Bellman, a menudo, reduce drásticamente la cantidad de enumeraciones que hay que hacer, evitando la enumeración de algunas sucesiones que posiblemente nunca podrán ser optimales. De hecho mientras que el numero total de sucesiones de decisión diferentes es exponencial en el numero de decisiones (si hay d elecciones para cada una de las n decisiones, entonces hay dn posibles sucesiones de decisiones), los algoritmos de PD suelen tener eficiencia polinomial.

A continuación nos centramos en la aplicación de la técnica de la PD para el diseño de algoritmos, es decir en la ilustración de la aplicación de las anteriores fases para la resolución de un problema con PD, considerando algunas situaciones que ya conocemos de capítulos anteriores, como son el problema de la mochila y el del camino mínimo.

a) La naturaleza N-etápica de los problemas

En efecto, la solución al problema de la mochila puede entenderse como el resultado de una sucesión de decisiones. Tenemos que decidir los valores de xi , 1 ≤ i ≤ n. Así, primero podríamos tomar una decisión sobre x 1 , luego sobre x 2 , etc. Una sucesión optimal de decisiones, verificando las restricciones del problema, será la que maximice la correspondiente función objetivo. Por su parte, en el problema del camino mínimo, una forma de encontrar el camino mínimo desde un vértice i a otro j en un grafo dirigido G, es decidiendo que vértice debe ser el segundo, cual el tercero, cual el cuarto, etc. hasta que alcanzáramos el vértice j. Una sucesión optimal de decisiones proporcionaría entonces el camino de longitud mínima que buscamos.

b) Comprobación del Principio de Optimalidad

Consideremos ahora el Problema de la Mochila 0-1. Sea gj(y) el valor de una solución optimal del problema Mochila (j+1, n, y). Claramente g 0 (M) es el valor de una solución optimal de Mochila (1,n,M). Las posibles decisiones para x 1 son 0 o 1 (D 1 = {0,1}). A partir del Principio de Optimalidad se sigue que

g 0 (M) = Max {g 1 (M), g 1 (M-w 1 ) + p 1 } (3)

Hasta aquí el Principio de Optimalidad se ha establecido solo con respecto al estado y la decisión inicial, pero también puede aplicarse a estados y decisiones intermedios. Los dos siguientes ejemplos muestran como puede hacerse esto.

  1. Caminos mínimos. Sea k un vértice intermedio en una camino mínimo desde i a j, i, i 1 , i 2 , ...k, p 1 , p 2 , ... j. Los caminos i, i 1 , i 2 , ...k, y k, p 1 , p 2 , ... j, deben ser respectivamente los caminos mas cortos desde i a k y desde k a j.

  2. Mochila 0-1. Sea y 1 , y 2 , ...,yn una solución optimal del problema Mochila (1,n,M). Entonces para cada j, 1 ≤ j ≤ n, y 1 , ..., yj e yj+1, ..., yn deben ser soluciones optimales de los problemas

Mochila (1, j,  1 ≤i≤j w (^) iyi) y Mochila (j+1, n, M -  1 ≤i≤j w (^) iy (^) i)

respectivamente. Esta observación nos permite generalizar (3) a g (^) i(y) = Max {gi+1 (y), gi+1 (y - wi+1 ) + pi} (4)

La aplicación recursiva del Principio de Optimalidad produce una relación de recurrencia del tipo (4). Los algoritmos de Programación Dinámica resuelven estas recurrencias para obtener la solución del caso del problema que estemos considerando. La recurrencia (4) puede resolverse sabiendo que gn(y) = 0 para todo y. A partir de gn(y) puede obtenerse gn+1(y) usando la formula (4) con i = n-1. Entonces usando gn-1(y) podemos obtener gn-2(y). Repitiendo esto, podremos determinar g 1 (y), y finalmente g 0 (M) usando (4) con i = 0.

De la misma forma que hemos razonado la obtención de la ecuación recurrente en base al Principio de Optimalidad y al enfoque adelantado, podríamos haberlo hecho con respecto al enfoque atrasado, de modo que en este ultimo, la formulación para la decisión xi se hace en términos de sucesiones de decisiones optimales para x 1 , ..., xi-1, mirando por tanto hacia detrás la sucesión x 1 , ..., xn.

En lo que sigue aplicamos el enfoque de la PD al diseño de algoritmos que resuelven algunos problemas importantes, comenzando por ilustrar su aplicación sobre el siguiente sencillo y conocido ejemplo.

El problema de la subdivisión optimal

Se quiere dividir una cantidad positiva c en n partes de forma que el producto de esas n partes sea máximo. Para determinar la subdivisión optimal aplicamos la técnica de la Programación Dinámica. Sea fn(c) el máximo producto alcanzable, x el valor de la primera subdivisión, y (c-x) el valor de las (n-1) partes restantes. De acuerdo con el Principio de Optimalidad, la ecuación funcional que describe este problema de subdivisión optima es,

fn(c) = Max (^0) ≤x≤c {xfn-1 (c-x)}

Esta ecuación es valida para n ≥ 2. Es obvio que cuando n = 1,

f 1 (c) = c y f 1 (c-x) = c - x

Así, para n = 2

f 2 (c) = Max (^0) ≤x≤c {xf 1 (c-x)} = Max (^0) ≤x≤c {x(c-x)}

Haciendo cálculos se encuentra que el valor de x que maximiza ese producto es x = c/2, y así la política optima, es decir, la subdivisión optima para este proceso de decisión bi-etápico es,

{mj} = {c/2, c/2}

siendo el máximo valor del producto

f 2 (c) = (c/2)^2

Consideremos ahora el caso n = 3. El máximo producto alcanzable es,

f 3 (c) = Max (^0) ≤x≤c {xf 2 (c-x)} = Max (^0) ≤x≤c {x(c-x)^2 /4}

Realizando cálculos se obtiene que el valor máximo de x es x = c/3.

La subdivisión de la parte restante, 2c/3, constituye un proceso de decisión bi-etápico. De acuerdo con el anteior análisis, esa parte se divide en c/3 y c/3, y por tanto la subdivisión optima para el proceso tri-etápico es

{mj} = {c/3, c/3, c/3}

siendo el valor máximo del producto

f 3 (c) = (c/3)^3

Cuando la cantidad c dada se divide en cuatro partes, el máximo producto que se puede alcanzar es

f 4 (c) = Max (^0) ≤x≤c {xf 3 (c-x)} = Max (^0) ≤x≤c {x(c-x)^3 /27}

siendo el máximo valor de x, c/4. Ahora la subdivisión de la parte restante, 3c/4, constituye un proceso tri-etápico, de subdivisión optima c/4, c/4 y c/4, con lo que la subdivisión optima de este problema tetra-etápico es

{mj} = {c/4, c/4, c/4, c/4},

y el valor máximo del producto es f 4 (c) = (c/4)^4.

Todo el anterior análisis nos lleva a conjeturar que la solución para este problema, cuando n = k, seria

{mj} = {c/k, c/k, ..., c/k}

siendo el máximo valor del producto fk(c) = (c/k)k.

Realmente puede demostrarse por inducción matemática que las anteriores relaciones son ciertas para cualquier k. De acuerdo con el principio de Optimalidad, se sigue que,

fk+1(c) = Max (^0) ≤x≤c {xfk(c-x)} = Max (^0) ≤x≤c {x(c-x)k/k }

lo que por simple calculo nos lleva a que x = c/(k+1), siendo el máximo valor del producto,

fk+1(c) = [c/(k+1)] k+

Así, por inducción matemática, la subdivisión optimal del proceso n-etápico puede obtenerse como

{mj} = {c/n, c/n, ..., c/n}

con un valor máximo del producto fn(c) = (c/n)n

Evidentemente este problema es muy simple y podría resolverse fácilmente con métodos convencionales. Sin embargo hay que destacar que ilustra la idea de la resolución del mismo como un problema de decisión multi-etápico. La formulación del

la versión de Dijkstra que trabaja con una matriz de distancias, el tiempo de calculo total esta en n x O(n^2 ), es decir en O(n^3 ). El orden es el mismo que para el algoritmo de Floyd, pero la simplicidad de este supone que, en la practica, probablemente sea mas rápido. Por otro lado, si usamos la versión del algoritmo de Dijkstra que trabaja con una pila y, por tanto con listas de las distancias a los nodos adyacentes, el tiempo total esta en O((an+n^2 )log n), donde a es el numero de arcos en el grafo. Si el grafo no es muy denso (a << n^2 ) puede ser preferible usar el algoritmo de Dijkstra n veces, pero si el grafo es denso (a ≅ n^2 ), es mejor usar el algoritmo de Floyd.

Pero, generalmente, queremos saber por donde va el camino mas corto, y no solo su longitud. En este caso, podemos usar una segunda matriz P, inicialmente con valores cero, en la que P(i,j) al final contendrá el valor de la ultima iteración que causo un cambio en el arrray D(i,j). Si P(i,j) = 0, el camino mínimo entre i y j será directo a través del arco (i,j). De acuerdo con esto, si el ciclo mas interior del algoritmo de Floyd lo cambiamos para que haga que

If D(i,k) + D(k,j) < D(i,j) Then D(i,j) := D(i,k) + D(k,j) P(i,j) := k

nos queda el siguiente algoritmo,

Procedure Shortest (D:Array[1..n,1..n]; L:Array [1..n,1..n]; P:Array [1..n, 1..n]); Var i,j,k : Integer; Begin For i := 1 to n do For j := 1 to n do begin D[i,j] := L[i,j]; P[i,j] := 0 End; For i := 1 to n do D[i,i] := 0; For k := 1 to n do For i := 1 to n do For j := 1 to n do If D[i,k] + D[k,j] < D[i,j] then begin D[i,j] := D[i,k] + D[k,j]; P[i,j] := k End End;

Ahora, para obtener todos los vértices intermedios en el camino mínimo entre i y j, usamos el procedimiento siguiente,

Procedure Path (i,j: Integer); Var K : Integer; Begin k := P[i,j]; If k = 0 then Return; Path (i,k); Writeln (k); Path (k,j) End;

El Problema del Viajante de Comercio

Dado un grafo con longitudes no negativas asociadas a sus arcos, queremos encontrar el circuito mas corto posible que comience y termine en un mismo nodo, es decir, un camino cerrado que recorra todos los nodos una y solo una vez y que tenga longitud minimal.

Sea G = (N,A) nuestro grafo dirigido. Como antes, tomaremos N = {1,2,...,n}, y notaremos la longitud de los arcos por L (^) ij, con L(i,i) = 0, L(i,j) ≥ 0 si i es distinto de j, y L(i,j) = ∞ si no existe el arco (i,j).

Suponemos, sin perdida de generalidad, que el circuito comienza y termina en el nodo

  1. Por tanto, esta constituido por un arco (1, j), seguido de un camino de j a 1 que pasa exactamente una vez a través de cada nodo de N - {1, ,j}. Si el circuito es optimal, es decir, de longitud mínima, entonces ese es el camino de j a 1 y vale el principio de Optimalidad.

Consideremos un conjunto de nodos S ⊆ N - {1} y un nodo mas i ∈ N - S, estando permitido que i = 1 solo si S = N - {1}. Definimos el valor g(i,S) para cada índice i, como la longitud del camino mas corto desde el nodo i al nodo 1 que pasa exactamente una vez a través de cada nodo de S. Usando esta definición, g(1, N - {1}) es la longitud de un circuito optimal.

Por el principio de Optimalidad, vemos que

g(1, N-{1}) = Min (^2) ≤j≤n [L (^) 1j + g(j, N - {1,,j})] (5)

Mas generalmente, si i no es igual a 1, el conjunto S no es vacío y es distinto de N - {1} e i∉S,

g(i,S) = Min (^) j∈S [L (^) ij + g(j, S - {j})] (6)

Además,

g(i,∅) = L (^) i1 , i = 2,3,...n

Por tanto, los valores de g(i,S) se conocen cuando S es vacío.

Podemos aplicar (6) para calcular la función g en todos los conjuntos S que contienen exactamente un nodo (que no es el 1). Entonces, de nuevo, podemos volver a aplicar (6) para calcular g en todos los conjuntos S que contienen dos nodos (distintos del 1), y así sucesivamente. Cuando se conoce el valor de g[j,N - {1,j}] para todos los nodos j, excepto para el nodo 1, podemos usar (5) para calcular g(1,N - {1}) y, definitivamente, resolver el problema

El tiempo que consumirá este algoritmo puede calcularse como sigue,

a) Calcular g(j,∅) supone la realización de n-1 consultas de una tabla.

b) Calcular todas las g(i,S) tales que 1 ≤ #S = k ≤ n-2, supone realizar,

(n-1) × C n-2,k × k

adiciones (n-1 corresponden a los posibles valores que puede tomar la variable i, k provienen de los valores que puede tomar la variable j, y las combinaciones restantes son todos los conjuntos que podemos formar de n-2 elementos tomados de k en k.

c) Calcular g(1, N-{1}) implica n-1 adiciones.

Estas operaciones pueden usarse como referencia para calcular la eficiencia del algoritmo. Así el tiempo que se lleva el algoritmo en cálculos es,

El Problema de la Mochila 0-

Ya conocemos la terminología y notación de este problema. En definitiva, podemos obtener una solución para el problema de la mochila tomando una sucesión de decisiones sobre las variables x 1 , ..., xn. Una decisión sobre la variable xi supone decidir que valor (0 o 1) ha de tomar.

Supongamos que las decisiones sobre las xi se hacen en el orden xn, ..., x 1. Tras una decisión sobre xn nos podemos encontrar ante una de estas dos posibilidades: la capacidad restante de la mochila es M, y no se ha producido incremento de beneficio, o bien la capacidad restante es M - wn y hemos aumentado el beneficio en pn. Como las restantes decisiones xn-1, ..., x 1 deben ser optimales con respecto al estado del problema resultante de la decisión tomada sobre xn, ya que en otro caso, xn, ..., x 1 no seria optimal, se verifica el Principio de Optimalidad.

Sea fj(X) el valor de una solución optimal del problema Mochila(1,j,X). Como se verifica el Principio de Optimalidad, obtenemos,

fn(M) = Max {fn-1(M), fn-1(M-w 3 ) + pn }

que para un i > 0 arbitrario, se generaliza a,

fi(X) = Max {fi-1(X), fi-1(X-wi) + pi}

Esta ecuación puede resolverse para fn(M) teniendo en cuenta que f 0 (X) = 0 para todo X, y que fi(x) = ∞, x < 0. Entonces se pueden calcular sucesivamente f 1 , f 2 , ..., fn.

Por ejemplo, consideremos el problema definido por n = 3, M = 6, (w 1 ,w 2 ,w 3 ) = (2,3,4), y (p 1 , p 2 , p 3 ) = (1,2,5). Cada función fi esta perfectamente definida por los pares (Pj, Wj), donde Wj es el valor de X en el que fi da un salto. Pj = fi(Wj). Si hay r saltos entonces necesitamos conocer r pares (Pj, Wj), 1 ≤ j ≤ r. Por conveniencia podemos incluir el par (0,0). Así si suponemos que Wj < Wj+1, 0 ≤ j ≤ r, es evidente de la anterior ecuación que Pj < Pj+1. Además fi(X) = fi(Wi) para todo X tal que Wj ≤ X ≤ Wj+1, 0 ≤ j ≤ r. fi(X) = fi(Wr) para todo X, X ≥ Wr. Si Si-1^ es el conjunto de todos los pares para fi-1 (incluyendo el (0,0)) entonces se obtiene el conjunto Si 1 de todos los pares para gi(X) = fi-1(X – wi) + pi añadiendo a cada par en Si-1^ el par (pi, wi).

Si 1 = {(P,W) / (P- pi, W- wi ) ∈ Si-1}

Si 1 puede obtenerse ahora sin mas que mezclar juntos Si 1 y Si-1. Esta mezcla se corresponde a tomar el máximo de las dos funciones fi-1(X) y fi-1(X-wi) + pi. Así si Si-1^ y Si 1 tienen pares (Pj, Wj) y (Pk, Wk) y Pj ≤ Pk , pero Wj ≥ Wk, entonces el par (Pj, Wj) se elimina.

Por ejemplo en nuestro caso tendríamos:

S^0 = {(0,0)}; Si 1 = {(1,2)} S^1 = {(0,0), (1,2)}; S^21 = {(2.3), (3,5)} S^2 = {(0,0), (1,2), (2,3), (3,5)}; S^31 = {(5,4), (6,6), (7,7), (8,9)} S^3 = {(0,0), (1,2), (2,3, (5,4), (6,6), (7,7), (8,9)},

donde hay que notar como hemos eliminado el par (3,5) de S^3 como resultado de la anterior regla. Los detalles del algoritmo y de su aplicación los dejamos como practica. Pueden encontrarse en Horowitz-Sahni.

Ejemplos

  1. Se quieren asignar 12 personas a 3 tareas. La asignación de m personas a la tarea i produce fi(m) según la siguiente tabla,

m f 1 (m) f 2 (m) f 3 (m) 0 0 0 0 1 3 2 2 2 5 4 3 3 6 5 5 4 7 7 6 5 o mas 7 8 6

Como debería realizarse la asignación para que lo producido sea máximo?.

Tenemos que,

F 3 (12) = Max (^) y≤ 12 {f 3 (y) + F 2 (12-y)}

F 2 (n) = Max (^) y≤n {f 2 (y) + f 1 (n-y)}

donde n puede valer 12, 11, 10, etc. Así, por ejemplo,

F 2 (8) = Max (^) y≤ 8 {2+7, 4+7, 5+8, 7+7, 8+6, 7+5, ...}

Así,

N 12 11 10 9 8 7 6

F 2 (n) 15 15 15 15 14 13 12

y,

F 3 (12) = Max {15, 15+2, 15+3, 15+5, 14+6, 13+6, ...} = 20

Por tanto la solución optimal se alcanza al asignar 4,5,3 o 3,5,4 o 4,4,4; produciéndose en todos los casos un beneficio de 20.

  1. Supongamos ahora que queremos resolver con P.D. el siguiente problema,

Max: 10x 1 + 11x 2 + 12x 3 s.a: 4x 1 + 5x 2 + 6x 3 ≤≤≤≤ 10 xi ≥≥≥≥ 0 y enteros

Tenemos,

F 3 (10) = Max (^0) ≤x3≤ 1 {12x 3 + F 2 (10-6x 3 )}

Hay que calcular F 2 en los valores F 2 (10-0) y F 2 (10-6), por lo que n valdrá 10 y 4 en la siguiente formula,

F 2 (n) = Max (^0) ≤x2≤[n/5] {11x 2 + F 1 (n-5x 2 )}

Así hay que calcular F 1 (10), F 1 (5) y F 1 (4),

n = 10  F 1 (10-5x 2 )  F 1 (10), F 1 (5) y F 1 (4), n = 4  F 1 (4 - 5x 2 )  F 1 (4)

Pero,

F 1 (10) = Max {10x 1 } (^) x1=2 = 20 F 1 (5) = Max {10x 1 } (^) x1=1 = 10

numero de parentizaciones alternativas de una sucesión de n matrices por P(n). Como podemos dividir una sucesión de n matrices en dos (las k primeras y las k+ siguientes) para cualquier k = 1,2,...,n-1, y entonces parentizar las dos subsucesiones resultantes independientemente, obtenemos la recurrencia:

P(n) = 1 si n = 1 =  (^) k=1..n-1 P(k)P(n-k) si n ≥ 2

Puede demostrarse que la solución de esta ecuación es la sucesión de los Números de Catalan:

P(n) = C(n-1)

donde

C(n) = (n+1)-^1 C2n,n

es Ω(4n/n3/2), por lo que el numero de soluciones es exponencial en n y, consiguientemente, el método de la fuerza bruta es una pobre estrategia para determinar la parentización optimal de una cadena de matrices.

Estructura de una parentizacion optimal

La primera etapa de la tecnica de la PD es la de caracterizar la estructura de una solucion optimal. Para el problema de la multiplicacion encadenada de matrices, podemos realizar esta primera etapa como sigue. Por conveniencia, notemos Ai..j la matriz que resulte de evaluar el producto Ai × Ai+1 ×... × Aj. Una parentizacion optimal del producto A 1 × A 2 ×... × An divide el producto entre Ak y Ak+1 para algun entero k en el rango 1 ≤ k ≤ n. Es decir, para algun valor de k, primero calculamos las matrices Ai..k Ak+1..n y entonces las multiplicamos para obtener el producto final A1..n. El costo de esta parentizacion optimal es asi el costo de calcular el producto Ai..k, mas el costo de calcular el de Ak+1..n mas el costo de multiplicar ambas.

La clave esta en que la parentizacion de la primera subcadena A 1 ×... × Ak dentro de la parentizacion optimal de A 1 × A 2 ×... × An debe ser una parentizacion optimal de A 1 × A 2 ×... × Ak. Por que?. Si hubiera una forma menos costosa de parentizar A 1 × A 2 ×... × Ak entonces, sustiyendo esa parentizacion en la parentizacion optimal de A 1 × A 2 ×... × An, obtendriamos otra parentizacion de A 1 × A 2 ×... × An cuyo costo seria inferior a la de la optima: una contradiccion. Una observacion similar es valida para la parentizacion de la segunda sub-cadena Ak+1 ×... × An en la parentizacion optimal de A 1 × A 2 ×... × An , tambien debe ser una parentizacion optimal de Ak+1 ×... × An.

Asi, una solucion optimal para un caso del problema de la multiplicacion encajada de matrices contiene las soluciones de los subproblemas del caso considerado, es decir, se esta cumpliendo el Principio de Optimalidad de Bellman.

Una solucion recursiva

La segunda etapa de la tecnica de la PD es definir recursivamente el valor de una solucion optimal en terminos de las soluciones optimales de los subproblemas. Para nuestro problema, tomamos como subproblemas los de determinar el minimo costo de una parentizacion de Ai × Ai+1 ×... × Aj, 1 ≤ i ≤ j ≤ n.. Sea m[i,j] el minimo numero de multiplicaciones escalares necesarias para calcular la matriz A; el costo de la forma menos costosa de calcular A1..n debera ser por tanto m[1,n].

Se puede definir m[i,j] recursivamente como sigue. Si i = j, la cadena consiste de un solo elemento Ai..j = Ai, por lo que no hay que hacer ninguna multiplicacion para calcular el producto. Asi m[i,i] = 0 para i = 1,2,...,n. Para calcular m[i,j] cuando i < j, nos aprovecharemos de la estructura de una solucion optimal a partir de la etapa 1. Supongamos que la parentizacion optimal hace el producto Ai × Ai+1 ×... × Aj, tomando como punto de division Ak y Ak+1, con i ≤ k < j. Entonces m[i,j] es igual al costo minimo de calcular los subproductos Ai..k y Ak+1..j mas el costo de multiplicar esas dos matrices resultantes. Como calcular la matriz producto Ai..k ⋅ Ak+1..j supone hacert pi-1⋅pk ⋅pj multiplicaciones, obtenemos:

m[i,j] = m[i,k] + m[k+1,j] + pi-1⋅pk ⋅pj

Esta ecuacion recurrente supone que conocemos el valor de k, lo que no es cierto. Hay solo j - i posibles valores para k: k = i, i+1,...,j-1. Como la parentizacion optimal debe usar uno de estos valores de k, solo necesitamos chequearlos para encontrar el mejor. Asi nuestra definicion recursiva del costo minimo de la parentizacion del producto de Ai × Ai+ ×... × Aj es: 0 si i = j m[i,j] = Min 1 ≤ k < j {m[i,k] + m[k+1,j] + pi-1⋅pk ⋅pj} si i < j (2)

Los valores m[i,j] dan los costos de las soluciones optimales de los subproblemas. Ahora definimos tambien s[i,j] como el indice k en el que podemos dividir el producto Ai × Ai+1×... × Aj para obtener una parentizacion optimal. Esto es, s[i,j] es aquel k tal que

m[i,j] = m[i,k] + m[k+1,j] + pi-1⋅pk ⋅pj.

Calculo de los costos optimales

Llegados a este punto, es una sencilla tarea escribir un algoritmo recursivo que, basado en la ultima ecuacion recurrente, calcule el costo minimo m[1,n] asociado a la multiplicacion de A 1 × A 2 ×... × An. Sin embargo, este algoritmo va a consumir un tiempo exponencial. En efecto, el algoritmo quedaria como,

Matrices-Encadenadas-Recursivo (p,i,j) If i = 1 Then Return 0 m[i,j] = ∞ For k = 1 to j -1 do q = Matrices-Encadenadas-Recursivo (p,i,k)

  • Matrices-Encadenadas-Recursivo (p,k+1,j) + pi-1⋅pk ⋅pj If q < m[i,j] Then m[i,j] = q Return m[i,j]

Podemos plantear la siguiente recurrencia,

T(1) = 1

T(n) = 1 + k=1..n-1(T(k) + T(n-k) + 1) para n > 1

Notese que para i = 1,2, ..., n-1, cada termino T(i) aparece una vez como T(k) y una vez como T(n-k), por tanto la anterior ecuacion puede reescribirse como

T(n) = 2 ⋅ i=1..n-1T(i) + n