Vous êtes sur la page 1sur 54

Introduccin al lenguaje GAMS

Jose Ignacio Marn Alberdi


Ao 2000

ndice General
1 Acerca de este documento

2 Qu es GAMS?

3 Cmo podemos emplear Gams?

4 De que partes consta un programa GAMS?

5 Escribiendo en GAMS

6 Cabecera del programa

7 Declaracin de conjuntos

8 Declaracin de parmetros

11

9 Declaracin de variables

13

10 Algunas expresiones numricas

15

11 Declaracin de ecuaciones

16

12 Expresiones condicionales con dolar ($)

18

13 Includes

20

14 Declaracin de modelos

20

15 Lanzamiento del programa de optimizacin. Invocando a GAMS 21


16 Sentencia Display. Informes de resultados

24

17 Elementos de programacin

25
1

18 Un ejemplo completo y la librera de modelos de GAMS

27

19 Ms all de lo explicado aqu

28

1 Acerca de este documento


Este documento se organiza por secciones, cada una de las cuales trata un aspecto
concreto relativo al sistema que deseo describir.
La descripcin se centra en un comentario acerca del uso general de la herramienta
y la gramtica bsica que dene el lenguaje GAMS. Los ejemplos no son demasiado
completos pero hay que tener en cuenta que se ha tratado sobre todo de dar las ideas
bsicas que permitan construir un programa ms o menos complejo en GAMS. La
sugerencia puede ser examinar los programas de la coleccin de modelos de GAMS
o bien intentar la construccin de algunos ejemplos completos.
Al mismo tiempo este documento puede servir como guia de referencia rpida a la
hora de emplear el sistema GAMS, pues resume muchos de los puntos que desarrolla
el manual del usuario a lo largo de ms de 200 pginas. Sin embargo, aunque se
recogen los temas ms importantes, este documento no puede sustituir por completo
a dicho manual que ser necesario a la hora de hacer consideraciones ms avanzadas.
Este documento se ha preparado como introduccin a la parte de prcticas de
optimizacin con GAMS que actualmente se est dando dentro del Departamento.
Ms adelante se puede pensar en otro documento que describa usos ms complejos
del lenguaje as como casos prcticos interesantes relativos a la industria qumica
implementados por personas de este departamento o tomados de la literatura. O se
puede considerar el empleo de los ejemplos desarrollados en CACHE.
Cada vez que mencione un elemento del lenguaje en medio del discurso lo insertar
entre parntesis. Los ejemplos de cdigo GAMS aparecern en prrafos centrados
independientes. El tipo de letra cambia para enfatizar que se est hablando de
cdigo GAMS.

2 Qu es GAMS?
En pocas palabras dir que GAMS es un lenguaje, soportado por un paquete informtico, que permite especicar un problema de programacin matemtica independientemente del mtodo de resolucin asociado al mismo. Los problemas a
tratar han de ser de naturaleza algebraica no pudiendo especicarse problemas de
optimizacin con ecuaciones diferenciales de forma directa.
Adems de poder describir el problema de nuestro inters GAMS puede llamar a
los programas encargados de resolver el caso, siempre que estn dentro de su lista
de resolvedores disponibles.
La idea detrs de GAMS es la de encapsular la fase de descripcin del problema,
aislndola de la fase de resolucin del mismo. A medida que se desarrollan nuevos
programas para resolver determinados tipos de problemas estos pueden ser incorporados al entorno GAMS.

3 Cmo podemos emplear Gams?


Para poder plantear y resolver un problema empleando el sistema GAMS es necesario completar una serie de etapas.
La primera, y no siempre obvia, pasa por tener claro que programa queremos resolver. Es decir tenemos que determinar cuales son las ecuaciones, variables y datos
numricos que manejaremos as como la estructura general del programa. Cuando
digo estructura me reero a los tipos de variables y relaciones entre las mismas que
vamos a emplear. Como principales estructuras de programacin tenemos disponibles en GAMS las siguientes:






Programacin Lineal (LP), todas las variables son de tipo continuo y solamente
se permiten relaciones lineales entre las mismas.
Programacin Lineal Entera Mixta (MILP), las variables pueden ser de tipo
continuo o discreto y solamente se permiten relaciones lineales entre las mismas.
Programacin No Lineal (NLP), todas las variables son de tipo continuo y se
permiten relaciones lineales y no lineales entre las mismas.
Programacin No Lineal Entera Mixta (MINLP), las variables pueden ser de
tipo continuo o discreto y se permiten relaciones lineales y no lineales entre
las mismas.

Con la primera de estas opciones (LP) podemos plantear problemas simplicados


o sencillos y alcanzar la solucin ptima de una forma bastante eciente y segura
al ser la programacin lineal un campo prcticamente cerrado. Las capacidades de
modelar con este tipo de programacin son menores que en los otros casos, an as
a veces es conveniente contar con versiones (LP) orientativas de nuestros modelos.
La siguiente opcin en cuanto a riqueza expresiva es la programacin lineal entera
mixta (MILP). Con ella se pueden tratar casos muy complejos de planicacin, que
tengan en cuenta una casustica compleja. Este tipo de programas es ms o menos
difcil de resolver dependiendo del nmero y la inuencia de las variables discretas
consideradas. Para casos de gran nmero de variables existen numerosas tcnicas
heursticas que permiten encontrar soluciones muy buenas, vlidas pese a no ser la
ptima en cada caso. Muchas veces, por ser un tipo de programacin ms sencillo de
tratar, los casos que cuentan con partes no lineales son transformados en instancias
(MILP) para asegurar su resolucin, esto es ms verdad cuanto mayor sea el caso.
El tipo de programacin ms evidente a emplear en muchos casos de modelado de
sistemas complejos o que estudien fenmenos naturales es la programacin no lineal
(NLP). Sin embargo este tipo de programacin es muy compleja y los resolvedores,
en el mejor de los casos, pueden encontrar soluciones locales, o incluso soluciones
arbitrarias, o a veces no encuentran soluciones cuando estas existen. Para casos
de elevado nmero de variables este tipo de programacin es un reto todava en la
actualidad.
La mayor riqueza expresiva, y por ende la mayor dicultad en su tratamiento, la
aporta la programacin no lineal entera mixta (MINLP), que ana las dicultades del
tratamiento no lineal y del tratamiento de posibilidades discretas. Casos de incluso
muy reducido tamao pueden ser casi imposibles de resolver.
Una vez que hemos decidido acerca de como vamos a plantear nuestro caso concreto
hemos de ser capaces de escribirlo en lenguaje GAMS. El lenguaje GAMS incorpora
3

muchos elementos que hacen sencillo el poder dar una descripcin de numerosos
problemas incluso de grandes dimensiones y elevada complejidad.
Muchas veces, dependiendo de como escribamos el programa los resolvedores tendrn un mejor o peor comportamiento. Hemos de tener esto en cuenta y tender
a escribir nuestros programas de forma que el comportamiento del resolvedor sea
ptimo en la medida de lo posible.
La ltima fase, una vez realizadas las pruebas que determinan cual es la mejor forma
de escribir nuestro modelo GAMS, consiste en realizar las pasadas oportunas para
obtener los resultados deseados.
Una pasada consta de dos partes, una primera en la que GAMS analiza el archivo
de datos que hemos preparado con el editor (compilacin) y otra, si todo ha ido
bien el resolvedor que GAMS tenga que invocar para solucionar el pase lo completa
(ejecucin).
Normalmente no es fcil interpretar toda la informacin que se puede obtener de los
pases, habitualmente se obtiene mucha informacin sobre el sistema en s tratando
de ver porque la solucin es la que es.
Dependiendo de lo obtenido en la fase de interpretacin podemos querer volver a
formular el modelo cambiando sus datos o hiptesis de partida hasta conseguir que
el resultado se parezca al comportamiento real objeto de estudio.
Como conclusin decir que podemos emplear GAMS principalmente como una herramienta de desarrollo rpido de prototipos de programacin matemtica.
En otros casos GAMS es una herramienta que participa de lleno en la fase operativa
del modelo desarrollado, no solamente en la elaboracin del prototipo en s, pudiendo
interaccionar con otros programas de forma sencilla.

4 De que partes consta un programa GAMS?


Las partes ms habituales que podremos encontrar en un programa GAMS son las
siguientes:



Cabecera del programa. Aqu se colocan ciertos comentarios descriptivos del


programa, ttulo, autores del mismo, informacin relativa a la versin etc.
Opciones de programacin. Los programadores activan o desactivan ciertas
opciones generales de GAMS a su conveniencia. Estas opciones pueden especicar la forma en la que se ensean los resultados, iteraciones mximas para
los algoritmos, declaracin de smbolos especiales de comentarios, etc.
Declaracin de conjuntos. En muchas ocasiones los programas requieren que
las variables, los parmetros y las ecuaciones sean descritos mediante subndices. As, por ejemplo, una ecuacin de balance material puede ser requerida
para cada elemento del conjunto de platos de una columna de destilacin.
Tambin podemos tener la variable temperatura denida para cada plato. Es
por ello por lo que en esta seccin se especican los diversos conjuntos a tener
en cuenta y los elementos que a ellos pertenecen. Ciertos conjuntos pueden ser
declarados como combinacin de elementos de otros conjuntos. As podemos
tener, por ejemplo, si existen los conjuntos centros y procesos, un nuevo conjunto que diga que procesos consideramos en cada centro, no siendo vlidas
todas las posibles combinaciones de elementos entre ambos.
4

Declaracin de parmetros numricos. Un programa adems de tener variables y relaciones entre las mismas, es decir ecuaciones, ha de alimentarse de
ciertos valores numricos constantes que denominaremos parmetros. En su
forma ms sencillas estos parmetros sern constantes que no se ven afectadas por ningn subndice. De forma ms compleja podemos considerar uno
o varios subndices que afectan a un parmetro determinado. Los datos denidos pueden combinarse mediante expresiones matemticas para dar lugar a
nuevos valores para otros parmetros.
Declaracin de variables. Aqu deniremos que variables vamos a emplear
y de que tipo es cada variable. Podremos tambin jar los lmites de las
variables que queramos y especicar valores iniciales a considerar en los pases
del resolvedor.
Declaracin de ecuaciones. En esta parte se pueden denir las ecuaciones del
modelo. Siempre es necesario denir un tipo especial de ecuacin que es la
funcin objetivo, que necesita de la participacin de una variable especial que
es la que hemos de maximizar o minimizar en el pase de optimizacin.
Declaracin de modelo. Normalmente a cada programa GAMS le va a corresponder un modelo. Sin embargo, podemos considerar varios modelos dentro
de un programa GAMS. Cada modelo est denido por las ecuaciones que se
consideran dentro del mismo.
Lanzamiento del programa de optimizacin. Esta parte puede ser muy sencilla si solamente queremos lanzar el programa que resuelve el caso una vez.
En otras ocasiones podemos querer realizar varias llamadas a diferentes resolvedores con diferentes modelos, realizando operaciones intermedias con los
datos o los valores iniciales de las variables, incluyendo bucles y condiciones.
Esto puede valer para implementar complejos algoritmos de optimizacin.
Informes de resultados. En este caso podemos optar por tener los informes
que GAMS prepara de forma automtica o bien podemos darle instrucciones
para preparar nuestros propios informes en el archivo de salida o en diversos
archivos a nuestra conveniencia.

Las diversas partes de un programa GAMS pueden ordenarse como he sugerido o


pueden cambiarse de orden a voluntad del programador. Lo nico que hay que
tener en cuenta es que no se puede usar un smbolo dentro del programa que no
haya sido declarado con anterioridad.
Adems de todo lo dicho es preciso saber que podemos declarar los conjuntos y
parmetros independientemente del momento en el que les asignamos valores, amen
de poder incorporar archivos externos en el cuerpo del programa en forma de includes. Esto permite desarrollar programas que albergan la estructura de un tipo de
problema y poder cambiar los datos del mismo de forma externa, tanto los relativos
a conjuntos (topologa del problema) como las constantes numricas.
Iremos desarrollando cada una de las partes vistas hasta ahora al mismo tiempo
que introducimos la sintaxis del lenguaje que emplea GAMS.

5 Escribiendo en GAMS
Antes de pasar a describir cada una de las partes tpicas de un programa GAMS
quiero hacer una serie de comentarios acerca de la forma en la que hemos de intro5

ducir los datos en GAMS, que como todos los lenguajes de un pelaje similar tiene
sus propias reglas de ortograa.
Conviene saber que GAMS:







Acepta solamente archivos de tipo texto plano ASCII, con cualquier extensin,
aunque la ms empleada sea la extensin gms.
No distingue entre minsculas y maysculas.
Tiene un conjunto de caracteres vlidos. Una buena recomendacin aqu es
olvidarse de tildes, la letra y casi de todo lo que no entre de serie en un
teclado americano.
Tiene una lista de palabras y smbolos reservados del sistema que conguran
el lenguaje e iremos viendo poco a poco.
Las sentencias en GAMS pueden introducirse en formato libre, esto es con
blancos y saltos de lneas arbitrarios entre medias. La longitud mxima de
una lnea es de 120 caracteres.

Sentencias
Suelen empezar con una palabra reservada como (equation) o (parameter) por
ejemplo y normalmente terminan con punto y coma (;). Algunas sentencias no
comienzan con una palabra clave o reservada, tal es el caso de las sentencias de
asignacin de valores a constantes numricas por ejemplo.
Las directivas de compilacin, palabras reservadas precedidas por un dolar ($) suelen
ir en lneas propias que no necesitan terminar en punto y coma (;). Veremos algunas
a lo largo del texto.
Identicadores
Son los nombres que les ponemos a los conjuntos, parmetros, variables, etc. Para
que un identicador sea vlido es necesario que comience con una letra y vaya
seguido de letras o dgitos hasta completar un mximo de 10 caracteres.
Etiquetas
Son los nombres que damos a los elementos de los conjuntos, pueden tener un
mximo de 10 caracteres.
Han de comenzar por letra o dgito y los caracteres empleados a continuacin tambin han de ser letras o dgitos.
Existe otra forma de especicar etiquetas que se basa en el empleo de comillas
como delimitadores de las mismas, pero es ms conveniente emplear la forma que
he mencionado antes.
Textos descriptivos
Los identicadores y las etiquetas pueden ir acompaados de textos descriptivos
que el compilador retiene como comentarios a emplear en los archivos de salida.
Este texto puede ir entre comillas o sin comillas. Si se usan las comillas es mejor
ya que podemos emplear cualquier carcter en el comentario excepto las comillas
(simples o dobles) que empleemos para delimitar el texto. El texto tiene que ir en
una lnea y no puede superar los 80 caracteres.
6

Si no se usan comillas, no podemos emplear palabras reservadas al principio del


texto, ni separadores como coma (,), punto y coma (;) o slashes (/) en el cuerpo
del mismo.
Nmeros
Los nmeros se almacenan en GAMS como valores reales.
GAMS tiene smbolos especiales para innito (INF), valores no denidos (UNDF),
valores muy pequeos (EPS) y valores no disponibles (NA). La palabra (UNDF) aparece
siempre como resultado de una operacin ilegal como dividir por cero y no puede
ser introducida por el usuario como valor numrico.
Normalmente se pueden introducir hasta 10 cifras signicativas. Conviene no introducir nmeros mayores que 1.0e+20.
Delimitadores
Los puntos y coma (;) separan sentencias de programa.
La coma (,) separa elementos dentro de un conjunto de datos.
El slash (/) marca el comienzo o el nal de una lista de datos.
Comentarios
Los comentarios pueden ser:
Lneas que comienzan con asterisco (*)
Un bloque de texto. Por ejemplo:
$ontext
Este es un bloque de texto, aqu puede aparecer cualquier carcter que
queramos,
Por ejemplo la !!!
$offtext

El bloque de texto va delimitado por las directivas de compilacin adecuadas ($ontext)


y ($offtext). Las directivas de compilacin aparecen siempre precedidas por el
smbolo dlar ($) al principio de lnea.
Podemos declarar nuestros propios caracteres como delimitadores de comentarios
mediante las siguientes directivas:
$eolcom #
$inlinecom {}
x = 1; #ahora este es un comentario
y = 2; {este tambien lo es} z = 3;

6 Cabecera del programa


Una vez que sabemos como escribir en GAMS pasaremos a describir las partes ms
habituales de un programa GAMS.
Normalmente comenzaremos con una directiva ($title) que nos permite introducir
el ttulo del pase que estemos preparando. Este ttulo pasar a encabezar las pginas
del archivo de salida.
7

$title

PROGRAMA DE EJEMPLO

Luego puede venir una seccin comentada que de informacin acerca de la versin,
los autores, etc.
$ontext
Este programa se ha realizado para que los alumnos de la especialidad
de qumica tengan una idea de cmo emplear la herramienta GAMS
$offtext
*Autor : Jimba
*
*Version : 1.0

Despus pondremos una serie de opciones mediante directivas de compilacin ($)


o sentencias de opciones (OPTIONS) que nos van a permitir sobre todo especicar
como queremos que sea el archivo de resultados que tengamos al nal de pasar el
programa. Tambin podremos denir nuestros propios smbolos de comentarios u
opciones que pasaremos al optimizador de turno.
Las palabras reservadas para dar opciones son (option) y (options), que como ya
sabemos pueden venir en minsculas o maysculas. Las sentencias que empiecen
con esta palabra estarn dedicadas a dar valores a ciertas opciones que el compilador
pone a nuestro servicio y que hay que conocer. Dentro de una sentencia de opciones
podemos dar valores a varios campos siempre que los separemos por comas, espacios
o lineas en blanco. Este tipo de sentencias pueden aparecer en cualquier parte del
programa, afectando al mismo desde el momento en que aparecen. Como todas las
sentencias han de acabar en punto y coma (;).
Las opciones que considero de mayor uso son las siguientes, lo que hace cada opcin
se explica en el comentario del nal del trozo de cdigo que viene a continuacin:
option LIMCOL=0,LIMROW=0;
$offlisting
$onempty
$inlinecom /* */
option solprint=off;
/* las dos primeras evitan que gams desarrolle las ecuaciones y variables
en forma de listado en el archivo de salida
Si quiero ver esos desarrollos para comprobar solo tengo que cambiar
los ceros por otros numeros mas convenientes
la directiva de compilacion offlisting desactiva otra opcion que por
defecto GAMS utiliza y que es la de desarrollar un listado
de los simbolos empleados en el programa en el archivo de salida
la directiva onempty hace que GAMS admita conjuntos vacios
la directiva inlinecom habilita este tipo de comentario
la opcion solprint=off desactiva el listado de las soluciones estandar
de GAMS en el archivo de salida
creo que es mejor decirle que soluciones quiero ver o en algunos casos
escribir las soluciones directamente a otros archivos que no sean el de defecto

esto ultimo puede venir bien si quiero pasar datos a otros programas
como por ejemplo I LOVE MATLAB para hacer graficas con esos datos
Veremos otras opciones en el transcurso del texto
*/

7 Declaracin de conjuntos
Los conjuntos se introducen en GAMS dentro de sentencias que empiezan con la
palabra clave (set) o (sets) y acaban en punto y coma (;).
El conjunto se dene por los elementos que lo forman. As al nombre del conjunto
sigue la lista de sus elementos entre slashes (/). Los elementos del conjunto se
separan entre s por saltos de lnea o comas. A los elementos del conjunto, o al
conjunto en s, pueden acompaarles textos descriptivos de los que les separan al
menos un carcter en blanco.
Sets
i

plantas de proceso

ciudades

/ Madrid, Gijon /

Cordoba

Malaga
Barcelona /
T

periodos de tiempo /1*5/

Ntese que en el caso del ltimo conjunto especicado las etiquetas empleadas para
los elementos son numricas. El asterisco (*) viene a especicar un rango en este
caso, es decir que consideramos los periodos 1 a 5. Si queremos, para el mejor seguimiento de la informacin a lo largo del programa aclarar que el subndice empleado
tiene algo que ver con el conjunto  T podemos eliminar la lnea de denicin de este
conjunto y especicar en la misma o en otra sentencia de declaracin de conjuntos:
SET
T

periodos de tiempo

/t1*t5/

Creo que es mas claro de esta forma.


Recordad que si queris especicar algo con unidades, el tpico ejemplo de los precios,
es til emplear comentarios entre comillas. As podemos introducir el slash (/)
dentro del comentario sin confundir al compilador.
Set
P

"precios de material en euros/tonelada"

/
precseco

precio en la estacion seca

prechumi

precio en la estacion humeda

/;

En este ultimo ejemplo, los elementos del conjunto  P tienen asociado un comentario que no va entre comillas, ojo con poner las tildes en las palabras  estacion
o  humeda, ya que el compilador se os quejar en este caso.
Un subconjunto se declara de igual forma que un conjunto. La nica particularidad
es que hay que indicar el nombre del conjunto que incluye al que declaramos entre
parntesis a continuacin del nombre de este.
set jc(j)

ciudades costeras

/Malaga,Barcelona/;

Veamos como declarar conjuntos multidimensionales. El ejemplo ms sencillo es el


bidimensional. En la declaracin del conjunto aparecen entre parntesis los conjuntos de los cuales se toman elementos para establecer las posibles combinaciones. Un
elemento del conjunto vendr dado por un par (elemento del conjunto 1 . elemento
del conjunto 2), en este caso el punto (.) actua de separador.
set

/salamanca,cuenca,albacete/;

set

/madrid,barcelona,valencia/;

set

ij(i,j)

/salamanca.madrid,albacete.barcelona
cuenca.valencia/;

Podemos pensar en ejemplos ms complicados a medida que incrementamos el nmero de dimensiones e incluimos la posibilidad de utilizar secuencias. En la siguiente
tabla se recoge en la primera columna lo que aparece entre los slashes (/) que sigen
a la declaracin de un conjunto multidimensional. En la columna de la derecha
viene la expansin a elementos sencillos de dicha expresin.
/(a,b).c.d/
/(a,b).(c,d).e/
/(a.1*3).c/
/1*3.1*3.1*3/

a.c.d, b.c.d
a.c.e, b.c.e, a.d.e, b.d.e
a.1.c, a.2.c, a.3.c
1.1.1, 1.1.2, 1.1.3, ..., 3.3.3

En ciertas ocasiones queremos declarar parmetros, variables o ecuaciones que se


reeren ms de una vez a los elementos de un mismo conjunto. La gramtica de
GAMS no permite especicar ningn elemento que se reera directamente varias
veces a un mismo conjunto. La nica forma de poder hacerlo es mediante el truco
de emplear copias del conjunto, para que GAMS los tenga por dos conjuntos
diferentes pero idnticamente iguales. Estas copias se declaran mediante la sentencia
(alias). En el siguiente ejemplo vemos que quiere decir todo esto, y tambin
nos adelantamos un poco a la siguiente seccin que habla de la declaracin de
parmetros.
set c

ciudades

/pamplona,sansebas,almeria/;

/*creamos el conjunto c prima que tambien se refiere a las ciudades*/


alias(c,cprima);
*alternativamente podiamos haber dicho alias(cprima,c)
*empleamos el conjunto cprima
parameter
dis(c,cprima)

distancia entre ciudades

;
*dis(c,c) no hubiera sido valido

10

8 Declaracin de parmetros
Hay tres tipos de parmetros en GAMS. Por un lado los escalares, asimilables a
constantes numricas, por otro los parmetros, asimilables a listas de constantes
numricas y por ltimo las tablas que son listas de al menos dos dimensiones de
constantes numricas.
Para declarar un escalar o varios hemos de emplear una sentencia que comience
con la palabra reservada (scalar) o, indistintamente, (scalars). Los nombres de
los escalares han de comenzar por letra y pueden ir seguidos de letras y nmeros
hasta completar 10 caracteres. En la declaracin de varios escalares es necesario
separar unos de otros mediante saltos de lneas o comas. A continuacin de cada
nombre de escalar puede venir un texto descriptivo de no ms de 80 columnas que
necesariamente ha de estar en la misma lnea que el smbolo declarado. Tambin
puede aparecer, a continuacin del texto descriptivo, y delimitado por slashes (/)
el valor que toma la constante. Los escalares pueden participar en sentencias de
asignacin en cualquier momento a partir de su declaracin. Notar que una sentencia
de asignacin no ha de ir precedida de palabra clave alguna.
scalars
grav

aceleracion de la gravedad

velocidad de la luz

constante de los gases

ggrav

cuadrado de grav

/9.8/
/300000/

;
*aqui pueden venir otras sentencias
r=0.082;
ggrav = grav * grav;

Para declarar una o varias listas de constantes numricas asociadas a un ndice o


conjunto, las reglas son muy similares. La palabra clave a emplear es (parameter)
o (parameters). Al nombre del parmetro le puede seguir un texto descriptivo con
las mismas caractersticas ya mencionadas en el caso escalar. Los nombres de los
parmetros guardan las mismas reglas que todos los identicadores mencionados
hasta ahora. Si se dan valores a los elementos de la lista estos han de ir encerrados
entre slashes (/). A los elementos de una lista los ha de separar un salto de lnea
o una coma, cada elemento se dene con la etiqueta del elemento del conjunto
correspondiente separado del valor que el parmetro adquiera para este ndice por
un blanco o un signo igual (=). Podemos asignar valores en cualquier momento
a partir de la declaracin del parmetro. Si asignamos el valor solamente a un
elemento concreto de la lista, hemos de indicarlo empleando la etiqueta de ese
elemento entre comillas simples en la sentencia de asignacin.
parameters
presplato (i)
volatirel(j)

presion en el plato i
volatilidad relativa componente j

/
j1 = 5.8
j2 = 1.89 , j3 = 1

11

/
;
*la siguiente sentencia afecta a todos los platos
presplato (i) = 14 ;
*y esta afecta a un solo elemento
presplato ('i4') = 14.5 ;

Como es natural previamente necesitamos de la declaracin de los conjuntos  i,


platos y  j, componentes.
Una asignacin interesante que se puede hacer con un parmetro es la de asignar
valores distribuidos regularmente sobre un intervalo. Para ello solamente hay que
hacer como se dice a continuacin. Lo nico que hay que tener en cuenta es que
(ord) signica ordinal de un conjunto, es decir la posicin relativa que un elemento
ocupa en el mismo, y (card) su cardinal, es decir el nmero de elementos totales del
mismo.
presplato (i) = 14 + (15-14)*(ord(i)-1)/(card(i)-1);

Los parmetros pueden llegar a tener hasta 10 dimensiones. Veamos nuevamente


un par de ejemplos inventados:
set

empleado

set

manager

set

dept

/marcos,cecilia,martin/;
/luis,rober/;
/juguetes,cazaypes,quimica/;

parameter salario(empleado,manager,dept)
/

marcos.luis.cazaypes

90

cecilia.luis.juguetes

92

martin.rober.quimica

78

/;
SET

row

/row1*row10/

col

/col1*col10/ ;

parameter a(row,col)
/ (row1,row4).col2*col7

12

row10.col10

17

row1*row7.col10

33

/ ;

Para introducir valores en el caso de parmetros multidimensionales las tablas,


(table), pueden ser una alternativa a las sentencias (parameter) basadas en listas,
pero en el fondo son ms o menos lo mismo. Vemos un par de ejemplos solamente:
set

plantas

/inchon,ulsan,yosu/
m

secciones

/atmos-dis,steam-cr,aromatics,hydrodeal/ ;

12

TABLE ka(m,i)
atmos-dis

capacidad inicial produccion


inchon

ulsan

3702

12910

steam-cr

517

aromatics

181

hydrodeal

180

yosu

atmos-dis

9875

steam-cr

1287

hydrodeal

148

Las entradas para las que no se da un valor se consideran iguales a 0. Ntese el


signo ms (+) para indicar la continuacin de la tabla. Cuando se tiene ms de
dos dimensiones es necesario poner, ya sea en las las o en las columnas, varias de
ellas unidas por el punto (.) que ya intervino en la denicin de las n-tuplas en la
seccin de conjuntos. Por ejemplo:
table

upgrade (strateg,size,tech)

small.tech1

small.tech2

medium.tech1

medium.tech2

s1

0.05

0.05

0.05

0.07

s2

0.27

0.24

0.21

0.29

Una cosa importante es que los datos han de estar alineados correctamente con las
etiquetas.
A recordar, si no se dice nada un parmetro o un escalar son inicializados con el
valor 0.

9 Declaracin de variables
A la hora de declarar variables hemos de considerar de que tipo se tratan. Existen cinco tipos bsicos de variables en GAMS: variables libres, variables negativas,
variables positivas, variables enteras y variables binarias.
Las palabras clave que aparecen al comienzo de una denicin de variables de cada
uno de estos tipos son: (variable), (negative variable), (positive variable),
(integer variable) y (binary variable).
Las variables libres son las que estn limitadas por menos innito e innito, las
negativas las que estn limitadas por menos innito y cero, las positivas por cero
e innito. Mientras no se diga lo contrario una variable es continua. Una variable
discreta cae dentro del tipo entero, de estas un caso especial son las variables binarias
que solamente pueden tener valor de cero o uno.
Para declarar variables de un tipo es necesario emplear la palabra clave que designa
ese tipo, a continuacin una lista de variables separadas por comas o cambios de
13

lnea y para nalizar el clsico punto y coma (;). La palabra clave puede venir en
maysculas o minsculas en singular o plural como viene siendo habitual.
Una variable puede aparecer en varios apartados. Por ejemplo puede aparecer bajo
la palabra clave (variable) y posteriormente aparecer en una sentencia que empiece
como (positive variable). As se va restrigiendo cada vez ms el dominio de la
variable. Lo normal es introducir cada variable dentro de una sentencia que empiece
con las palabras clave de su tipo directamente.
Los nombres de las variables pueden ser combinaciones de hasta 10 letras y nmeros
siempre que comiencen por letra. Los nombres de las variables vienen separados
por saltos de lnea o comas. Los textos descriptivos funcionan igual que en otros
casos.
Algunos ejemplos inventados pueden ser:
VARIABLE
Beneficio

"cantidad obtenida en euros/mes"

;
positive variables x1,x2,x3;
INTEGER VARIABLES
conecta(i,j)

posibles modulos entre las ciudades i j

;
BINARY VARIABLE
activa1
activa2 ;

Observese que  conecta hace referencia a un conjunto de variables de tipo entero. Estas variables, para ser distinguidas unas de otras, vienen afectadas por dos
subndices  i y  j. Estos ndices podrn tomar valores dentro de lo permitido en
las correspondientes deniciones de los conjuntos  i y  j.
Cualquier variable dentro de GAMS tiene en todo momento denidos 4 valores
asociados o campos. Una vez denida podemos acceder a estos valores ya sea para
modicarlos o para consultarlos. Los campos denidos se acceden a travs del
nombre de la variable seguido de un punto y una palabra clave para el campo. As,
podemos tener:
activa1.LO = 0;
activa1.up = 0;
conecta.lo('i1','j5') = 6;
x1.L = 45.5;
costem = x2.m;

En los ejemplos vemos que los campos de las variables pueden darse en minsculas
o maysculas indistintamente, como es habitual.
En la primera lnea jamos el lmite inferior de la variable binaria  activa1 al
valor 0;
En la segunda lnea jamos el lmite superior de la misma variable al valor 0. Estas
dos lneas hacen que el nico valor posible que puede tomar la variable es 0, con lo
cual est ja. Otra forma de especicar esto es empleando el campo auxiliar  fx:
14

activa1.fx = 0;

En la tercera lnea modicamos el lmite inferior de la variable que corresponde al


subndice  i1 y  j5 del conjunto de variables enteras llamadas  conecta. Notar
que es necesario indicar el campo antes que el elemento en cuestin. Si entre parntesis encontramos las letras que designan los conjuntos sin los apstrofes, signicar
que nos referimos a todas las variables de esa clase en vez de a un elemento concreto.
conecta.lo(i,j) = 6;

En la siguiente lnea, decimos que el valor actual, campo (L) o level, de la variable
positiva  x1 toma el valor de 45.5. Si se hace esta asignacin antes de invocar a
un resolvedor se estar especicando una condicin inicial.
Por ltimo, en la siguiente lnea, se ve como el parmetro  costem adquiere el valor
del campo (M) o marginal de la variable  x2. Este campo hace referencia al coste
marginal de la variable en cuestin.
Las ecuaciones, que bajo cierto punto de vista son totalmente equivalentes a las
variables, tambin tienen denidos estos cuatro campos, pero su utilizacin no es
frecuente en los programas GAMS.

10 Algunas expresiones numricas


A modo de recetario rpido algunas funciones y expresiones numricas comunes.
Estas expresiones pueden afectar a parmetros o a variables en ecuaciones. En este
ltimo caso hay que ver que casi todas introducen no linealidades o discontinuidades
que afectarn al tipo de modelo que estemos construyendo. Si estamos haciendo un
modelo con ecuaciones lineales (LP) e introducimos una ecuacin con la expresin
 exp(pres(i)), por poner un ejemplo, pasaremos a tener un modelo no lineal
(NLP).
exp(x)
log(x)
log10(x)
normal(x,y)
uniform(x,y)
abs(x)
ceil(x)
floor(x)
max(x,y,..)
min(x,y,..)

exponencial
log natural
log decimal
num aleatorio segn normal media x std. y
num aleatorio segn uniforme entre x e y
valor absoluto
menor entero mayor o igual que x
mayor entero menor o igual que x
mximo de los argumentos
mnimo de los argumentos

power(x,y)
sqr(x)
sqrt(x)
sin(x)
cos(x)
arctan(x)
round(x)
mod(x,y)
sign(x)
errorf(x)

Sumatorios:
sum (i, a(i))
sum ((i,j,k), (a(i,j) * b(j,k)))

Productorios: Idem con la palabra reservada (prod) en vez de (sum).

15

x a la y, con y entero
cuadrado
raz cuadrada
seno
coseno
arc cuya tangente es x
entero ms prximo
resto de x/y
1 es +, -1 es -, 0 es 0
funcin error

11 Declaracin de ecuaciones
Las palabras clave que denen el principio de una sentencia de declaracin de
nombres de ecuaciones, y que se pueden usar indistintamente, son (equation) y
(equations). En esta sentencia podemos hacer uso de los habituales comentarios
descriptivos. Las comas y los saltos de lnea separan los nombres de las diversas
ecuaciones. Estos nombres han de empezar con una letra que puede ir seguida de
ms letras y nmeros hasta 10 caracteres.
Un pequeo ejemplo, inspirado en columnas de destilacin pero que no es completo,
puede bastar para ver las cosas ms importantes de esta seccin:
EQUATION
objetivo

especificacion de los costes de operacion

equil(i,j)

"equilibrio liquido/vapor plato i comp j"

bal(i,j)

balance masa componente j en el plato i

pureza

la pureza requerida en cabeza

*
*faltan bastantes ecuaciones
;

Despus de dar sus nombres, es necesario decir en que consiste cada ecuacin, esto
es lo que en GAMS se conoce como denicin de ecuaciones. Para especicar cada
ecuacin tendremos que dar un nombre vlido de ecuacin, seguir con los caracteres
reservados (..) y especicar una relacin entre variables y parmetros vlidos con
los operadores normales. En esta relacin pueden aparecer funciones y operadores
como el sumatorio. La sentencia concluye con el punto y coma (;) de rigor.
Las ecuaciones pueden ser de igualdad o de desigualdad. Las igualdades se especican con el smbolo reservado (=e=) o (=E=). Las desigualdades mediante el empleo
de (=l=) o (=L=) para las de tipo "menor o igual que" y (=g=) o (=G=) para las de
tipo "mayor o igual que".
As podemos tener:
objetivo .. z =e= Prod - 50 * RR;
equil(i,j) .. y(i,j) =E= x(i,j) * K(i,j);
bal(i,j) .. L(i,j) + V(i,j) =e= L(i+1,j) + V(i-1,j);
pureza .. x('i9','benceno') =g= 0.85;

As en la primera ecuacin "objetivo" decimos que la variable "z" (puede ser el


coste de operacin) es igual a la cantidad de producto que obtenemos por cabeza
(variable "Prod") menos 50 veces la relacin de reujo (variable "RR").
En las dos lneas siguientes especicamos dos conjuntos de restricciones de igualdad,
que se extienden a todas las combinaciones de los elementos de los conjuntos "i" y
"j" (platos y componentes, respectivamente).
El primero de estos conjuntos viene dado por las relaciones de equilibrio lquido
vapor. Si tomamos la constante de equilibrio "K(i,j)" como un parmetro conocido
la relacin ser lineal, si la declaramos como una variable la relacin pasar a
ser no lineal. En estas ecuaciones las variables "x(i,j)" e "y(i,j)" seran las
16

fracciones molares de componente "j" en el plato "i" en el lquido y en el vapor


respectivamente.
En el segundo vemos como se dan los balances por componentes para cada plato.
Es interesante ver como podemos hacer que en la ecuacin aparezcan variables del
plato anterior "V(i-1,j)" o posterior "L(i+1,j)" al considerado en cada caso "i".
Las "V" hacen referencia a los ujos de vapor y las "L" a ujos de lquidos.
Como se ve esta ecuacin se extendera sobre todas las parejas posibles de elementos de "i" y de "j". Si tenemos en cuenta que se referencian variables de platos
posteriores y anteriores al considerado qu pasar cuando GAMS intente escribir
la ecuacin para el primer o el ltimo plato?. Imaginemos que el conjunto de platos
ha sido declarado como:
Set
i Platos /i1,i9/ ;

Para el primer plato intentar encontrar los elementos "V('i0',j)" dependiendo


del componente "j" que estemos considerando, los cuales no existen porque el plato
"i0" no existe, y por lo tanto sern reemplazados por un cero.
Para el ltimo plato intentar encontrar los elementos "L('i10',j)" dependiendo
del componente "j" que estemos considerando, los cuales tampoco existen porque
el plato "i10" no existe, y sern igualmente reemplazados por un cero.
Esto podra arruinar las expresiones de los balances en cabeza y fondo. Por ello
es necesario conocer el mecanismo que GAMS tiene para no extender una ecuacin
o variable a todos los elementos del conjunto que la denen en la sentencia tipo
(equation). Veremos como se hace esto en la siguiente seccin.
La ltima ecuacin no se extiende sobre ningn conjunto ya que afecta solamente a
una variable del conjunto de variables  x(i,j) (fracciones molares del componente
 j en el liquido del plato  i). Esta variable es  x('i9','benceno'), es decir la
fraccin molar del componente  benceno en el lquido del plato  i9. Ntese el
mayor o igual en este caso.
En este ejemplo damos por supuesto que se han declarado las variables y parmetros
pertinentes, adems de los que hicieran falta para completar el modelo. Como creo
que es fcil de ver, una declaracin tal, que adems nos sirve de repaso, hubiera
podido ser:
SET
i platos /i1*i9/
j componentes /benceno,tolueno,polimero/;
*i1 es el fondo
*i9 es la cabeza
*
* aqui faltaria definir una tabla con las K(i,j)
* si las damos como parametros
*
VARIABLE
z

coste de operacion

17

;
POSITIVE VARIABLES
Prod

cantidad de producto obtenido por cabeza

RR

relacion de reflujo

L(i,j)

cantidad de componente j en el liquido del plato i

V(i,j)

cantidad de componente j en el vapor del plato i

x(i,j)

fraccion molar componente j en liquido del plato i

*
*etc... resto de variables necesarias incluyendo y(i,j)
;
*limites de las fracciones molares
x.up(i,j) = 1;
y.up(i,j) = 1;

12 Expresiones condicionales con dolar ( )


$

Una primera cosa que hay que saber llegados a este punto es que los smbolos
reservados de GAMS para establecer relaciones numricas entre datos son:
lt,
le,
eq,
ne,
ge,
gt,

<
<=
=
<>
>=
>

menor que
menor o igual que
igual que
no igual que
mayor o igual que
mayor que

Para realizar operaciones lgicas:


not
and
or
xor

negacin
and
or inclusivo
or exclusivo

Una forma muy empleada en GAMS para trabajar con condiciones lgicas, especialmente para restringir el campo de variacin posible de un conjunto, esto es,
trabajar con excepciones, es la de emplear la condicin dolar ($). Normalmente
aparece junto a una denicin de una ecuacin o junto a cualquier trmino de una
asignacin, suele ir como  $(condicin). Dentro de condicin podemos considerar
cualquier expresin que no afecte a variables. Los parmetros, escalares, y similares
pueden ser empleados aqu, tambin pueden aparecer campos de variables, esto es
 variable.campo.
La mejor forma de entender como funciona este operador es mediante una serie de
ejemplos:
a $(b > 1.5) = 2;

 a es igual a 2 siempre que  b sea mayor que 1.5. Si no es as no se hace nada.


18

x = 2 $(y > 1.5) + 5 $(y le 1.5);

 x es igual a 2 siempre que  y sea mayor que 1.5, si no es as  x ser 5. Si no


apareciese el trmino  + 5 $(y le 1.5), entonces  x sera 0 siempre que  y no
fuese mayor que 1.5.
Veamos el ejemplo que dejamos pendiente de la seccin anterior:
set i

platos

set ic(i)
set ifo(i)

/i1*i9/;

cabeza

/i9/;

fondo

/i1/;

*notese que no puedo llamar al ultimo subconjunto if(i)


*porque if es una palabra reservada
*ord es ordinal
*card es cardinal
bal(i,j)$(ord(i) gt 1 and ord(i) lt card(i))
.. L(i,j) + V(i,j) =e= L(i+1,j) + V(i-1,j);
*alternativamente
*bal(i,j)$((not ic(i)) and (not ifo(i)))
*

.. L(i,j) + V(i,j) =e= L(i+1,j) + V(i-1,j);

En este caso la expresin de los balances para cada componente solamente aplica a
los platos intermedios de la columna, no a los extremos de la misma. Los balances
en estos extremos deberan luego denirse como otras ecuaciones aparte. Lo que
se ha mostrado en este ejemplo es como limitar el dominio de denicin de una
ecuacin.
Como cosa curiosa hay que notar que cuando el ordinal de un conjunto (ord) es
igual a su cardinal (card) estamos hablando del ltimo elemento del mismo.
De la misma forma las condiciones ($) pueden afectar a alguna expresin de las que
toman parte en una ecuacin, entrando a formar parte de ella efectivamente si se
cumple algn requisito necesario.
mb(i) .. x(i) =g= y(i) + (e(i) - m(i)) $(t(i));

El trmino  e(i)-m(i) solamente entra en la ecuacin para los elementos del conjunto  i que tambin pertenezcan al conjunto  t(i)
Esto tambin funciona con conjuntos multidimensionales para mapear una serie
de relaciones. En este caso damos valores a un parmetro exclusivamente para
ciertas combinaciones vlidas de ciudades, el parmetro, claro est, ha tenido que
ser declarado previamente, as como los elementos que entran en su denicin.
set

/salamanca,cuenca,albacete/;

set

/madrid,barcelona,valencia/;

set

ij(i,j)

/salamanca.madrid,albacete.barcelona
cuenca.valencia/;

costenvio(i,j) $(ij(i,j)) = factor * distan(i,j);

19

Por ltimo vemos como extender un operador sumatorio a ciertos elementos exclusivamente de un conjunto.
costetot .. coste =e=
sum ( (i,j) $(ij(i,j)), costenvio(i,j) * x(i,j)) ;

Cuando se vean las expresiones de control del ujo del programa se volvern a ver
pequeos ejemplos con condiciones ($).

13 Includes
La directiva ($include) puede ser muy util a la hora de elaborar programas GAMS.
Si el programa GAMS consta de varias partes o mdulos cada una de ellas puede
ir en un archivo separado y pueden ser reunidas en un archivo principal mediante
el empleo de esta directiva.
Lo que hace la directiva es incluir el archivo cuyo nombre se especica a continuacin
de la misma justo en el punto en el que aparece dentro del archivo que se est
compilando.
Un ejemplo de buen uso de la directiva ($include) es el de hacer un programa
GAMS que declare toda su estructura de conjuntos, parmetros, variables y ecuaciones, as como la forma de resolver el pase en un archivo principal a compilar.
set j ciudades;
parameter
pob(j)

poblacion en ciudad j

*variables etc...

Los datos relativos a que elementos aparecen en cada conjunto y datos numricos de
valores de parmetros pueden aparecer en otros archivos que sern incluidos en el
principal antes de invocar al resolvedor o tener que mencionar un elemento concreto
de un conjunto.
*antes de que sea necesario
$include conj.dat
$include data.dat
*resto del programa

As, solamente hemos de cambiar los archivos auxiliares si queremos cambiar los
datos numricos del problema o la topologa (estructura que denan los conjuntos)
del mismo.

14 Declaracin de modelos
Supongamos que estamos en el caso ms sencillo de solamente querer considerar un
modelo en nuestro programa GAMS. Para especicar cual es este modelo lo primero
que hemos de hacer es pensar un nombre para el mismo.
20

Imaginemos que llamamos a nuestro modelo  prueba. Normalmente si solamente


hay un modelo en el programa, suele incluir todas las ecuaciones que hemos especicado en el mismo. As la sentencia para declarar nuestro modelo  prueba, el cual
ha de contener a todas las ecuaciones del modelo es:
model prueba /all/;

Las palabras (model) y (all) son palabras reservadas del sistema.


Como nombres vlidos podemos considerar asociaciones de letras y nmeros hasta
10 caracteres que empiecen con una letra. Podemos acompaar la denicin con un
texto explicativo que no exceda las 80 columnas y que est contenido en la misma
lnea de declaracin.
MODEL prueba2 Esta es una prueba con comentario /all/;

Si queremos declarar varios modelos dentro de un mismo programa hemos de decir


que ecuaciones intervienen en cada uno de ellos.
Supongamos ahora que tenemos las ecuaciones  ecu1,  ecu2,  ecu3,  ecu4, y
que vamos a declarar un modelo  completo que las incluya a todas, otro, modelo
 parte1, que incluya solamente a las ecuaciones  ecu1,  ecu2 y  ecu3, y por
ltimo un modelo  parte2 que solamente considere las ecuaciones  ecu1,  ecu3
y  ecu4. Las sentencias GAMS que describen esta situacin son:
model completo /all/;
model parte1 /ecu1,ecu2,ecu3/;
model parte2 /ecu1,ecu3,ecu4/;

Observese que en cada modelo es necesario que aparezca una funcin objetivo, que
no tiene porque ser la misma en cada caso. En nuestro ejemplo ecu1 puede ser la
funcin objetivo que sera la misma para los tres modelos denidos.

15 Lanzamiento del programa de optimizacin. Invocando a GAMS


Nos falta ver que instruccin activa el proceso de optimizacin.
La sentencia que empieza por la palabra reservada (solve) cumple exactamente
ese cometido. En la sentencia es necesario especicar el modelo que se pretende
resolver, adems del tipo de programa del que se trata (LP, NLP, MILP, MINLP) y
que variable queremos maximizar o minimizar, es decir cual es el objetivo.
El orden en el que se den estos dos ltimos parmetros no es importante.
Un par de ejemplos:
Solve prueba1 using lp minimizing z;
Solve completo maximizing obj2 using minlp;

21

La variable a maximizar o minimizar ha de ser continua y de tipo libre, esto es no


puede ser ni positiva ni negativa, y al menos ha de participar en una ecuacin de
las que componen el modelo.
A partir de esta instruccin GAMS realiza un paso de compilacin, verica los
lmites de las variables (que los inferiores no excedan a los superiores) y que no se
realicen operaciones no permitidas como divisiones por cero. Luego el control pasa
al programa optimizador encargado de resolver cada tipo de modelo. Por defecto
GAMS sabe a que programa acudir, pero el programador siempre puede disponer
del resolvedor de su eleccin siempre que este pueda atacar el tipo de problemas del
que se trate. Para ello, antes de una sentencia (solve):
Option lp=minos5;

Esta sentencia dice que los modelos lineales pasan a ser competencia del resolvedor
minos, en vez de la opcin por defecto que pudiera existir en aquel momento, por
ejemplo osl.
A travs de ciertos sujos el programador puede controlar o acceder a ciertas opciones relativas al modelo. Las ms interesantes, los comentarios explican sucintamente
lo que cada una signica, pueden ser:
Model prueba /all/;
*PONER un limite maximo de iteraciones
prueba.iterlim=5000;
*ESTABLECER archivo de opciones para el resolvedor
*algunas opciones solamente pueden ser dadas de esta forma
prueba.optfile=myoptionfile;
*ESTABLECER criterio absoluto de terminacion
prueba.optca=0;
*ESTABLECER criterio relativo de terminacion
prueba.optcr=0.1;
*ESTABLECER MBytes a emplear por el resolvedor
prueba.workspace=500;
*PARA preguntar por el estado del modelo
*prueba.modelstat, este puede dar lo siguiente
*1 solucion optima, 2 optimo local,
*3 ilimitado, 4 infactible
*5 local infactible, 6 intermedio infactible,
*7 intermedio suboptimo, 8 solucion entera,
*9 intermedio no entero, 10 entero infactible
*PARA preguntar por el numero de ecuaciones generadas
*prueba.numequ
*PARA preguntar por el numero de variables generadas
*prueba.numvar

22

Una vez editado el archivo de texto y guardado este es necesario invocar al programa
ejecutable GAMS que ha de hacer el pase de compilacin y el pase de ejecucin si
el paso anterior no ha dado ningn error.
Si se ha instalado GAMS en el sistema lo normal es que su directorio raiz este en
denido en el PATH. Si no es as deberemos incluir una lnea en el script de inicio de
sesin, que bajo el sistema operativo Windows es el autoexec.bat, que se encargue
de esta cuestin. Si suponemos que el sistema GAMS est en el directorio c:\gams,
en Windows esa lnea sera:
PATH=c:\gams;%PATH%
Al iniciar la mquina el operativo tendra actualizada la variable de entorno PATH
que dice donde se han de buscar los archivos requeridos por lnea de comandos. A
partir de ahora suponemos que estamos trabajando en Windows.
Una vez comprobado que invocando GAMS desde una ventana DOS el sistema
responde, pasamos a decirle que procese nuestro archivo. Lo adecuado en este punto es trabajar en un directorio propio de trabajo, que bien pudiera ser
c:\trabajo\prueba. Imaginemos que nuestro archivo se llama prueba.txt. As
las cosas la forma ms facil de invocar a GAMS y decirle lo que tiene que hacer es:
>: gams prueba.txt wdir=c:\trabajo\prueba
De esta forma le decimos que archivo procesar y en que directorio trabajar. Es la
forma ms limpia y cmoda. As todos los archivos que genere GAMS se encontrarn bajo el directorio que le hemos marcado, los archivos que necesite (si hemos
especicado algn include) sern buscados en este directorio.
Normalmente la gente emplea la extensin .gms para los archivos GAMS, esta es
la extensin que el ejecutable de GAMS busca por defecto. Si nuestro archivo se
llama prueba.gms la instruccin anterior puede resumirse a:
>: gams prueba wdir=c:\trabajo\prueba
El archivo de salida por defecto de GAMS tiene el mismo nombre que nuestro archivo
de entrada y tiene la extensin .lst. Si hemos lanzado el ejecutable de GAMS con
la instruccin anterior, al nalizar el proceso aparecer el archivo prueba.lst bajo
el directorio c:\trabajo\prueba.
En este archivo GAMS deposita:





Una copia del listado de entrada, para poder vericar ciertos errores. Aparece
siempre. En esta listado, all donde se produzca un error de compilacin
aparecer un simbolo dolar ($) seguido de un cdigo numrico bajo la lnea
en cuestin. Al nal de la copia del listado de entrada se explica lo que cada
cdigo quiere decir. Esto vale como ayuda a la hora de depurar un programa.
Una lista de smbolos declarados. Conviene desactivarla con ($offlisting).
El desarrollo de las variables y ecuaciones del modelo, limitado por las opciones (limcol) y (limrow). Para comprobar algunas deniciones basadas en
conjuntos conviente no poner estas opciones a 0, cuando vemos que todo va
bien, lo mejor es si hacerlo.
23




Estadsticas del modelo, nmero de variables, ecuacines, tiempo de generacin, clculo, estados nales del resolvedor y del modelo, etc. Interesa verlo.
Listado de la solucin. Primero el valor del objetivo, luego el listado de
las ecuaciones, con sus campos (.lo,.up,.l,.m), y luego lo mismo para las
variables. Si una ecuacin o variable no cumple sus lmites se marca con la
palabra (INFES), si una variable participa en una direccin de crecimiento
ilimitado del objetivo se marca con la palabra (UNBD). Si queremos eliminar
este listado hemos de hacer  option solprint=off;.

16 Sentencia Display. Informes de resultados


Hemos visto que si no especicamos nada GAMS genera un archivo de resultados
bastante completo en el que nos muestra la solucin obtenida en el pase. Mucha
de la informacin vertida en este archivo puede ser desactivada a nuestra voluntad
empleando las pertinentes opciones como hemos comentado con anterioridad.
Si hemos podido eliminar todo vestigio de informacin que GAMS pudiera poner
en este archivo tambin hemos de tener la capacidad de mostrar informacin acerca
de los elementos denidos en nuestro programa a nuestro criterio.
La sentencia ms sencilla para lograrlo es la sentencia que comienza con la palabra
reservada (display). En esta sentencia, a continuacin de la palabra reservada,
aparecen los nombres de parmetros o campos vlidos (.l,.m,.lo,.up) de ecuaciones y variables, separados por comas o por saltos de lneas. El resultado es que
en el archivo de salida, a la altura correspondiente a la sentencia (display) aparece
el desarrollo de lo que hayamos solicitado. No es necesario indicar los conjuntos de
los que depende el smbolo a desarrollar. Un ejemplo sencillo:
*ggrav es un escalar, x es una variable que depende de (i,j)
display ggrav, x.l;

As podemos seleccionar de forma sencilla que informacin tenemos al nalizar el


proceso.
Otro punto interesante, sobre el que no nos extenderemos en absoluto, es la posibilidad de escribir la informacin que queramos a un archivo que no sea el normal
que emplea GAMS como salida. Rpidamente, sobre un ejemplo:
*tras invocar el resolvedor
*abrir archivo
file resul /resul.dat/

*escribir en resul
put resul

/*
la siguiente linea escribe la palabra Resultados
un slash es un cambio de linea
*/
put 'Resultados'//;
/*

24

bucle para escribir varios elementos


la arroba seguida de unumero indica a partir de que columna se escribe
el sufijo .tl indica el texto de etiqueta del elemento del conjunto
dado
los dos puntos tras el elemento a mostrar indica el formato numerico
a emplear
8 de ancho total con 4 decimales
*/
loop((i,j),
put

i.tl,

@12,

j.tl

@24,

x.l(i,j):8:4/

);
*cerrar archivo
putclose resul

Existen muchas opciones dedicadas a controlar como se muestra la informacin


en los archivos de salida. Si alguien quiere profundizar en estas cuestiones puede
consultar el captulo 14 del manual de GAMS disponible en el Departamento.

17 Elementos de programacin
Las estructuras de control del ujo del programa son las sentencias (loop), (if),
(while) y (for).
Como veremos en algn ejemplo las sentencias que lanzan la optimizacin (solve)
pueden aparecer dentro de este tipo de sentencias de control de ujo. Lo que no
puede ir dentro de este tipo de sentencias son las declaraciones de elementos del
programa, como variables, parmetros, ecuaciones, etc.
Tambin veremos que es posible tomar acciones diferentes segn los resultados de
la optimizacin. Para ello hemos de preguntar por el valor del campo (.modelstat)
del modelo que hayamos denido.
loop ( (conjuntos) $(condicin) , sentencias );
loop (i $(sub(i)),
d(i)=1.5+aumento;
aumento=aumento+0.5;
);
loop ((i,j) $(ord(i) eq ord(j)),
a(i,j)=1;
);

En el primer caso ejecutamos las sentencias en la intruccin (loop) solamente en


caso que el elemento del conjunto  i correspondiente entre en la denicin del
subconjunto  sub(i) del conjunto  i.  aumento es un escalar que tenemos que
haber denido previamente.
En el segundo, miramos que los ordinales de los conjuntos  i y  j coincidan. Esta
sentencia hace lo mismo que:
25

a(i,j) $(ord(i) eq ord(j)) = 1;

if ( condicion, sentencias else sentencias);


if ( condicin, sentencias elseif ( condicin, sentencias ); );
if ( (mymodel.modelstat eq 4),
*mymodel era infactible
*vamos a probar a relajar los limites de una variable
x.up(j) = 2*x.up(j) ;
solve mymodel using nlp minimizing z ;
else
if ( (mymodel.modelstate 1),
abort error al resolver mymodel;
);
);

En este ejemplo tomamos diversas acciones as haya transcurrido la optimizacin.


En el ltimo (if) si no obtenemos una solucin al problema lanzamos una sentencia
(abort) que para la ejecucin de GAMS lanzando un mensaje de error.
while ( condicion, sentencias );
scalar count /1/;
scalar globmin;
globmin = inf;
while ( count le 1000,
x.l(j)=uniform(0,1);
solve prueba using nlp minimizing obj ;
if (obj.l le globmin,
globmin = obj.l;
globinit(j) = x.l(j) ;
);
count = count+1;
);

En este ejemplo hemos visto como invocamos al optimizador (solve) tantas veces
como permite la condicin de la sentencia (while). Si la solucin obtenida en una
pasada es mejor que la que tenamos apuntada, actualizamos los parmetros que nos
sirven para llevar la cuenta. No hay que olvidar incrementar el contador  count si
queremos que el bucle tenga un nal.
for ( i= start to end by incremento, sentencias );
for (s= -3.4 to 0.3 by 1.4,
display s;
);

Este ejemplo tan sencillo vale para ver que los valores de inicio y nal no tienen
porque ser enteros. Tampoco tiene que serlo el incremento. La nica restriccin
es que el incremento sea un nmero real positivo. En el ejemplo anterior de la
sentencia (while) puede hacerse casi de idntica forma con una sentencia (for).
26

18 Un ejemplo completo y la librera de modelos de


GAMS
El siguiente es un ejemplo tomado del manual de GAMS, es tan sencillo que a estas
alturas debe ser autoexplicativo:
$title Modelo sencillo de transporte
option limcol=0,limrow=0;
$offlisting;
option solprint=off;
SETS
i

plantas de envasado

mercados

/ Seattle, San-Diego /

/ Washington, Chicago, Topeka / ;

PARAMETERS
A(i)

capacidad de la planta i

Seattle

350

San-Diego

600

/
B(j)

demanda del mercado j

/
Washington

325

Chicago

300

Topeka

275

/ ;
TABLE D(i,j)

distancia en miles de millas


Washington

Chicago

Topeka

Seattle

2.5

1.7

1.8

San-Diego

2.5

1.6

1.4

;
Scalar

F coste de envio por mil millas /90/;

PARAMETER C(i,j)

coste transporte en miles de dolares;

C(i,j) = F * D(i,j) / 1000;


VARIABLES
x(i,j)

cantidades enviadas

precio total transporte ;

POSITIVE VARIABLE x;

27

EQUATIONS
cost

define la funcion objetivo

supply(i)

respetar capacidad planta i

demand(j)

respetar demanda mercado j

cost .. z =e= sum((i,j), C(i,j)*x(i,j))


supply(i) .. sum(j, x(i,j)) =l= A(i)

demand(j) .. sum(i, x(i,j)) =l= B(j)

model transport /all/;


SOLVE transport using LP minimizing z;
display x.l,x.m;

Para ver este y otros ejemplos ms completos con detalles puede ser de utilidad el
consultar la libreria de modelos que GAMS incorpora.
La libreria es invocada con el comando gamslib seguido del nombre del problema
a estudiar o, alternativamente, del nmero que este tenga asignado dentro de la
coleccin. Por ltimo puede aparecer un nombre de archivo sobre el que queramos
que GAMS copie el problema de la coleccin. Si no decimos nada este archivo sera
prob[nmero].gms.
Para ver el ndice de la coleccin se puede hacer:
>: gamslib index
Algunos de los ejemplos de la coleccin son relativos a casos de la industria qumica.

19 Ms all de lo explicado aqu


Aunque en el texto se han tratado ms aspectos que los mencionados en el captulo
de introduccin a GAMS del manual an nos hemos dejado bastantes cosas en el
tintero como cabe suponerse.
As por ejemplo, en este documento no he explicado como preparar algoritmos
complejos de resolucin con GAMS. Estos algoritmos pueden necesitar del concurso
de elementos ms avanzados del lenguaje que los explicados hasta aqu ahora.
Un ejemplo de lo que digo puede ser implementar la resolucin de un programa
MILP mediante una tcnica llamada descomposicin de Benders, la cual necesita
que intervenga un tipo especial de conjuntos en GAMS que se denomina dinmico.
Tampoco he dado listados de casos de inters dentro del sector de la industria
qumica, ni he explicado nada de las tcnicas de optimizacin que corren por debajo
del nivel externo de GAMS.
Todo ello puede quedar para documentos posteriores.

28

GAMS, ejemplos introductorios


Hector Manuel Mora Escobar
Marzo de 2009
hectormora@yahoo.com
El programa comercial Gams, General Algebraic Modeling System, es una herramienta de alto
nivel para modelamiento y solucion de problemas de optimizacion y programacion matematica.
Su pagina es www.gams.com. All se puede descargar un demo de Gams, la gua del usuario, un
tutorial, ...
Su calidad, versatilidad y gran uso han hecho que se convierta en un estandar para la escritura de problemas de optimizacion. En NEOS, servidor para problemas de optimizacion,
www-neos.mcs.anl.gov , la mayora de los solucionadores (solvers) tienen como uno de los
formatos predeterminados el de Gams.
Es posible descargar e instalar Gams sin haber comprado la licencia, pero funciona como un
demo de uso libre que tiene restricciones de tama
no. Para la mayora de los ejemplos academicos
es mas que suficiente. Muchas gracias a los directivos de Gams. Los lmites superiores de tama
no
son, entre otros:
N
umero de restricciones y variables: 300.
N
umero de elementos no nulos: 2000.
N
umero de variables discretas: 50.
Gams viene para muchas plataformas, Windows, Linux, Solaris, Mac, ..., 32 y 64 bits. A
continuacion hay indicaciones someras para los primeros pasos de Gams en Windows y Linux.

0.1

Windows

En Windows, Gams tiene un IDE (ambiente integrado de desarrollo) que permite, entre muchas
cosas mas, editar (escribir) el archivo y ejecutar Gams. Este archivo donde se escribe el problema tiene extension .gms.
El archivo .gms es de tipo ASCII y puede ser escrito con cualquier editor para este tipo de
archivos (Emacs, Bloc de notas, ...). El editor del ambiente Gams tiene una gran ventaja,
resalta con diferente color las palabras especficas de Gams.
Tambien desde el ambiente Gams se puede activar Gams mediante la tecla F9 o mediante el
boton de la barra de men
u Run Gams.
Gams mira el archivo .gms y si esta bien escrito resuelve el problema. Gams enva algunos
resultados al ambiente y crea un archivo .lst donde esta la informacion sobre la solucion.
Si en el archivo .gms hay errores, entonces en el archivo .lst aparece una transcripcion del
archivo .gms, con numeracion de los renglones, e inmediatamente despues de una lnea erronea,
aparece algo semejante a
****

$409
1

El valor 409 (u otro valor) es un codigo de error. Un poco mas adelante, en el archivo .lst,
aparece el significado de cada uno de los codigos de los errores ocurridos.

0.2

Linux

En Linux, Gams no viene con ambiente integrado. El archivo .gms se puede escribir con
cualquier editor de texto (Emacs, vi, Kate, ... ). Para invocar Gams, desde una ventana se da
la orden
gams archivo.gms
Tambien se puede dar la orden sin explicitar la extension
gams archivo
De nuevo, se crea un archivo .lst donde esta el resultado, bien sea la solucion, o bien informacion sobre los errores de la misma manera que en Windows (ver seccion anterior).

0.3

Un archivo explcito de datos

Los ejemplos de modelos en Gams de este documento estan muy lejos de ser exhaustivos con el
n
umero de temas o con la profundidad utilizada. El proposito es explicar someramente algunos
de los conceptos involucrados en un ejemplo. El lector interesado podra encontrar informacion
mas amplia y precisa en la gua del usuario de Gams.
Consideremos un problema de fabricacion de sillas y escritorios, cuyo modelo sea:

min z = x1 1.4x2
x1 + x2 400
x1 + 2x2 580
x1 300
x 0.
El archivo de datos en Gams puede ser el siguiente:
* problema de OL, formulacion explicita
VARIABLES x1, x2, z;
POSITIVE VARIABLES x1, x2;
EQUATIONS obj, restr1, restr2;
obj..
z =e= -x1 - 1.4*x2;
restr1.. x1 + x2 =l= 400;
restr2.. x1 + 2*x2 =l= 580;
2

x1.UP = 300;
MODEL ejemplo /ALL/;
SOLVE ejemplo USING LP MINIMIZING z;
Supongamos que el archivo se llama ej01.gms . Al utilizar Gams, este producira un archivo
con los resultados, llamado ej01.lst .
En el archivo anterior las palabras propias de Gams estan escritas en may
usculas simplemente por presentacion pero no es necesario.
Algunas de estas palabras se pueden escribir en singular o plural, SET o SETS, VARIABLE,
EQUATION, SCALAR, PARAMETER
Si en la primera columna de una lnea hay un asterisco, esta se considera como una lnea
de comentarios.
Las igualdades y desigualdades en las restricciones y funcion objetivo se escriben con
=e= ( para = ), =l= ( para ), =g= ( para ) .
Las cotas inferiores y superiores se escriben utilizando .LO y .UP
Algunos de los procesos de solucion previstos por Gams son:
lp
nlp
mip
rmip
minlp
mcp
cns

linear programming
nonlinear programming
mixed integer programming
relaxed mixed integer programming
mixed integer nonlinear programming
mixed complementarity problems
constrained nonlinear systems

Si en el archivo de resultados, en el sitio donde debera aparecer un valor, vemos


esto quiere decir que el valor es 0.0 .

En la definicion de las cotas no se usa =e= , se usa simplemente = .


Las variables no tienen que llamarse x1, x2, etc. El nombre de una variable (el identificador)
puede tener hasta 63 caracteres alfanumericos (letras o dgitos) sin espacios. Aparentemente
tambien se puede utilizar el guion bajo ( _ ) pero no puede ser el primer caracter del identificador.
$ONTEXT
Problema de OL.
Estos son renglones de comentarios.
$OFFTEXT
VARIABLES Sillas, escrit, z;
3

POSITIVE VARIABLES /ALL/;


EQUATIONS obj, madera, m_obra;
obj.. z =e= sillas + 1.4*escrit;
madera.. sillAs + escrit =l= 400;
m_obra.. sillas + 2*escrit =l= 580;
sillas.UP = 300;
MODEL ejemplo /obj, madera, m_obra/;
SOLVE ejemplo USING LP MAXIMIZING z;
Observaciones:
Gams no diferencia entre min
usculas y may
usculas, pero, por ejemplo, el nombre principal de la primera variable sera Sillas (el primero que aparece). Las otras escrituras
equivalentes se le asimilaran.
$ONTEXT y $OFFTEXT sirven para empiezo y fin de comentarios. Estas dos palabras deben
empezar en la primera columna.
Cuando se define el modelo ejemplo, es posible considerar todas las ecuaciones con ALL
o explicitarlas todas una por una o solamente algunas de ellas.

0.4

Estructura de un modelo en Gams

Un modelo en Gams es una sucesion de comandos o enunciados (statement) en lenguaje Gams.


El orden no importa pero, cualquier entidad (variable, parametro, ...) debe ser declarada antes
de ser usada.
Es posible tener renglones en blanco y varios comandos en el mismo renglon. Usualmente cada
comando acaba con punto y coma.
En el archivo de entrada .gms los comandos son:
SETS
Datos: PARAMETERS, TABLES, SCALARS.
VARIABLES : declaracion y asignacion de tipo.
Asignacion de cotas [y valores iniciales].
EQUATIONS: declaracion y definicion.
MODEL y SOLVE.
DISPLAY (opcional).
En los modelos que siguen hay varios ejemplos de los comandos.
4

0.5

Un problema de transporte

Consideremos un problema clasico de transporte con 3 fabricas y 4 destinos. En la siguiente


tabla estan los costos unitarios de transporte (en miles de pesos), las capacidades maximas de
produccion de cada fabrica y los pedidos o demandas de cada destino.

Macondo
Cali
Faca
demanda

1 2 3
23 29 19
12 16 20
11 13 17
105

80

99

4
31
10
19

cap. max.
200
180
100

135

Usualmente el planteamiento de este problema se hace con las variables xij , i = 1, ..., 3, j =
1, ..., 4 que indican en n
umero de unidades que van de la fabrica i al destino j. Denotemos
por cij los costos unitarios de transporte, dj las demandas en los destinos y pi las capacidades
maximas de produccion en las fabricas. El modelo matematico es:

min z =

3 X
4
X

cij xij

i=1 j=1
4
X

xij pi ,

i = 1, ..., 3

xij = dj ,

j = 1, ..., 4

j=1
3
X
i=1

xij 0 i, j .
A continuacion estan dos formulaciones del problema en Gams. La primera formulacion es mas
explcita y no es estructurada.
$ONTEXT
Problema de transporte,
formulacion NO estructurada.
$OFFTEXT
VARIABLES x11, x12, x13, x14, x21, x22, x23, x24, x31, x32,
x33, x44, z;
POSITIVE VARIABLES x11, x12, x13, x14, x21, x22, x23, x24,
x31, x32, x33, x34;
EQUATIONS obj, f1, f2, f3, d1, d2, d3, d4;
obj.. z =e=

1000*( 23*x11 + 29*x12 + 19*x13 + 31*x14 +


5

12*x21 + 16*x22 + 20*x23 + 10*x24 +


11*x31 + 13*x32 + 17*x33 + 19*x34 );
f1.. x11 + x12 + x13 + x14 =l= 200;
f2.. x21 + x22 + x23 + x24 =l= 180;
f3.. x31 + x32 + x33 + x34 =l= 100;
d1..
d2..
d3..
d4..

x11
x12
x13
x14

+
+
+
+

x21
x22
x23
x24

+
+
+
+

x31
x32
x33
x34

=e= 105;
=e= 80;
=e= 99;
=e= 135;

MODEL transporte0 /ALL/;


SOLVE transporte0 USING LP MINIMIZING z;
Esta segunda formulacion aprovecha las facilidades algebraicas de Gams.
$ONTEXT
Problema de transporte,
formulacion estructurada.
$OFFTEXT
SETS
i fabricas u origenes /Macondo, Cali, Faca/
j destinos
/1*4/;
PARAMETERS
p(i) capacidad de produccion de las fabricas
/ Macondo 200
Cali
180
Faca
100 /
d(j) demanda en los destinos
/ 1 105
2
80
3
99
4 135 /;
TABLE
c(i,j) costo
1
Macondo
23
Cali
12
Faca
11

unitario entre una fabrica y un destino


2
3
4
29
19
31
16
20
10
13
17
19 ;
6

SCALAR k coeficiente para costos unitarios /1000/;


VARIABLES
x(i,j) numero de unidades de una fabrica a un destino
z
costo total de transporte;
POSITIVE VARIABLES x;
EQUATIONS
costo
capacidad(i)
demanda(j)

costo total de transporte


capacidad en cada fabrica
demanda en cada destino;

costo..
z =e= k*sum( (i,j), c(i,j)*x(i,j) );
capacidad(i).. sum(j, x(i,j) ) =l= p(i);
demanda(j)..
sum(i, x(i,j) ) =e= d(j);
MODEL transporte /ALL/;
SOLVE transporte USING LP MINIMIZING z;
DISPLAY x.l, x.m;
En la orden display, para mostrar resultados, x.l se refiere al valor (level ) de las
variables x; x.m se refiere al costo reducido o valor marginal de las variables x .
PARAMETER sirve para definir arreglos en una dimension (vectores). TABLE sirve para
definir arreglos de dos o mas dimensiones (matrices, ...).
Es permitido, despues de un identificador (conjunto, variable, ecuacion, parametro, tabla,
...), colocar texto explicativo. Por ejemplo,
p(i) capacidad de produccion de las fabricas
El nombre del parametro es p(i). Lo que sigue es un texto explicativo. No debe tener
mas de 254 caracteres. No debe tener tildes ni / ni comas ni smbolos raros, o sea,
preferiblemente debe tener u
nicamente letras, dgitos y espacios. Por ejemplo, no es
correcto escribir toneladas/mes, es preferible ton por mes. Sin embargo, es posible tener
un texto explicativo mas complejo si se coloca todo entre comillas sencillas o dobles. Por
ejemplo,
cp(i) capacidad de produccion en ton/mes

0.6

Un problema de vigilantes

Una compa
na de vigilancia evaluo sus necesidades de vigilantes, por periodos de 4 horas, en
un gran conjunto residencial, de la siguiente manera:
7

Periodo
Cantidad
2 a.m. a
6 a.m
84
6 a.m. a 10 a.m
48
10 a.m. a 2 p.m
37
2 p.m. a 6 p.m
35
6 p.m. a 10 p.m
32
10 p.m. a
2 a.m
30
Cada vigilante trabaja 8 horas al da, pero de manera continua. La compa
na desea organizar
la distribucion de sus vigilantes de tal forma que el n
umero total de vigilantes sea mnimo.
Plantee el anterior problema de OL.
Variables:
x1 el n
umero de vigilantes que empiezan su turno a las 2,
x2 el n
umero de vigilantes que empiezan su turno a las 6, ...,
x6 el n
umero de vigilantes que empiezan su turno a las 22,
Para hacer mas compacto el planteamiento, denotemos por v1 (un dato) el n
umero mnimo
de vigilantes necesarios en el primer periodo (2 a 6), ..., v6 el n
umero mnimo de vigilantes
necesarios en el sexto periodo (22 a 2).

min z =

6
X

xi

i=1

x1 + x6 v1 ,
xi + xi1 vi , i = 2, ..., 6,
x 0.
El problema se puede escribir en Gams as:
$ONTEXT
Problema de vigilantes,
formulacion estructurada.
uso del simbolo pesos y ord
$OFFTEXT
SETS
i periodos

/2-6, 6-10, 10-14, 14-18, 18-22, 22-2/;

PARAMETERS
v(i) necesidad de vigilantes
/ 2-6
84
6-10
48
10-14 37
14-18 35
18-22 32
22-2
30 /;
8

VARIABLES
x(i) numero de vigilantes que empiezan su trabajo
*
en el periodo i
ntv numero total de vigilantes;
POSITIVE VARIABLES x;
EQUATIONS objetivo, numVig1, numVigi(i);
objetivo..

ntv =e= sum(i, x(i) );

numVig1..
x(2-6) + x(22-2) =g= v(2-6);
numVigi(i)$(ord(i) gt 1 ).. x(i) + x(i-1) =g= v(i);
MODEL vigilantes /ALL/;
SOLVE vigilantes USING LP MINIMIZING ntv;
DISPLAY x.l;
La solucion es
---2-6

37 VARIABLE x.L
84.000,

6-10

numero de vigilantes que empiezan su trabajo


4.000,

10-14 33.000,

14-18

2.000,

18-22 30.000

El smbolo $, que se puede leer como tales que, permite tener restricciones u operaciones para
elementos de un conjunto que cumplen cierta condicion. En el ejemplo anterior, la restriccion
numVigi(i) se define u
nicamente para los elementos del conjunto i tales que su ordinal es
mayor que 1, es decir, para los elementos de ordinal 2, ..., 5.
Tambien se puede hacer usando el smbolo -- que considera un conjunto como una lista circular
(cuando se resta 1 al primer elemento, se toma el u
ltimo):
$ONTEXT
Problema de vigilantes,
formulacion estructurada,
uso de -FUNCIONA BIEN
$OFFTEXT
SETS
i periodos

/2-6, 6-10, 10-14, 14-18, 18-22, 22-2/;

PARAMETERS
v(i) necesidad de vigilantes
/ 2-6
84
6-10
48
9

10-14
14-18
18-22
22-2

37
35
32
30 /;

VARIABLES
x(i) numero de vigilantes que empiezan su trabajo
*
en el periodo i
ntv numero total de vigilantes;
POSITIVE VARIABLES x;
EQUATIONS objetivo, numVig(i);
objetivo..

ntv =e= sum(i, x(i) );

numVig(i).. x(i) + x(i--1) =g= v(i);


MODEL vigilantes /ALL/;
SOLVE vigilantes USING LP MINIMIZING ntv;
DISPLAY x.l;

0.7

Un problema de dieta

Un ama de casa desea hacer un almuerzo equilibrado utilizando los siguientes productos: carne,
papas, habichuela, leche y guayaba. Los precios por kilo de estos alimentos son respectivamente:
$700, $80, $250, $70 y $80. Aqu estamos suponiendo que la leche se vende por kilos, o lo que es
aproximadamente lo mismo, que un litro de leche pesa un kilo. La familia esta compuesta por 6
personas y cada persona debe consumir 800 caloras (en el almuerzo). Para que la alimentacion
sea equilibrada debe estar compuesta, idealmente, de 25% de protenas, 25% de grasas, 50%
de gl
ucidos o carbohidratos. En la practica, los porcentajes reales no deben diferir en mas de
5% de los porcentajes ideales. Estos porcentajes estan dados con respecto a la materia seca,
es decir, sin tener en cuenta el agua contenida en los alimentos. Obviamente, hay muchas mas
condiciones que se deben tener en cuenta y aqu se hace una simplificacion para facilitar el
planteamiento del problema. En la siguiente tabla se expresa la composicion de cada alimento
y su aporte calorico. Se supone que fuera de proteina, grasa y carbohidratos, solamente hay
agua con el porcentaje restante.
%
Protenas
Carne
10
Papas
2
Habichuelas
1
Leche
5
Guayaba
1

%
%
Caloras
Grasas Gl
ucidos por kilo
10
0
1300
0
20
880
0
5
240
3
5
670
0
15
640
10

El ama de casa desea saber como organizar su mercado de tal forma que se cumplan las
restricciones nutricionales y que, ademas, se minimice el costo.
Las variables pueden ser: xi : cantidad de kilos del alimento i que hay que comprar para el
almuerzo, i = 1, ..., 5
Para facilitar el planteamiento, introduzcamos unos nombres, unos valores intermedios y una
variable adicional:
ci = costo de un kilo del alimentos i,
rj = requerimiento ideal, en porcentaje, del componente j = 1, ..., 3,
uj = rj 5 = requerimiento mnimo, en porcentaje, del componente j,
vj = rj + 5 = requerimiento maximo, en porcentaje, del componente j,
pij = porcentaje, en el alimento i, del componente j,
ai = P
aporte calorico de un kilo del alimento i,
si = 3j=1 pij = porcentaje de materia seca en el alimento i,
y = cantidad (kilos) de materia seca de los alimentos comprados.

min z =

5
X

c i xi

i=1
5
X

ai xi = 6 800

i=1
5
X

0.01si xi = y

i=1
5
X

0.01pij xi 0.01uj y, j = 1, ..., 3,

i=1
5
X

0.01pij xi 0.01vj y, j = 1, ..., 3,

i=1

x0
Este modelo se puede escribir enGams as:
$ONTEXT
Problema de dieta,
formulacion estructurada,
$OFFTEXT
SETS
i alimentos
/carn, papa, habi, lech, guay/
j componentes /prot, gras, carb/;
VARIABLES
x(i) peso en kilos del alimento i
y
peso de la materia seca en kilos
11

costo del almuerzo;

POSITIVE VARIABLES x, y;
TABLE p(i,j) porcentaje
prot gras
carn
10
10
papa
2
0
habi
1
0
lech
5
3
guay
1
0

en el alimento i del componente j


carb
0
20
5
5
15
;

PARAMETER
r(j) requerimientos ideales de cada componente en porcentaje
/ prot
25
gras
25
carb
50 /
c(i) precio de un kilo de cada alimento
/ carn
700
papa
80
habi
250
lech
70
guay
80 /
ac(i) aporte calorico de un kilo de cada alimento
/ carn
1300
papa
880
habi
240
lech
670
guay
640 /;
SCALAR
k
n
calp
delta

coeficiente para convertir a fraccion /0.01/


numero de personas /6/
calorias por persona /800/
diferencia permitida en requerimientos /5/;

PARAMETER pms(i) porcentaje de materia seca de cada alimento;


pms(i) = sum(j, p(i,j)) ;
PARAMETER u(j) cota inferior para el porcentaje de j;
u(j) = r(j) - delta;
PARAMETER v(j) cota superior para el porcentaje de j;
v(j) = r(j) + delta;
12

DISPLAY pms, u, v;
EQUATIONS
obj
peso_ms
calorias
reqmin(j)
reqmax(j)

funcion objetivo
peso materia seca
total de calorias
requerimiento minimo
requerimiento maximo;

obj..

z =e= sum(i, c(i)*x(i));

peso_ms..

y =e= k*sum(i, pms(i)*x(i));

calorias..

sum(i, ac(i)*x(i) ) =e= n*calp;

reqmin(j).. k*sum(i, p(i,j)*x(i) ) =g= k*u(j)*y;


reqmax(j).. k*sum(i, p(i,j)*x(i) ) =l= k*v(j)*y;
MODEL dieta /ALL/;
SOLVE dieta USING LP MINIMIZING z;
DISPLAY x.l;
La solucion es
x = (0.768, 0, 0, 3.84, 1.92),

0.8

z = 960.

Optimizaci
on entera

Consideremos el siguiente problema

max z = 8x1 + 11x2 + 6x3 + 4x4


6.7x1 + 10x2 + 5.5x3 + 3.4x4 19
xj {0, 1} , j = 1, ..., 4.
Al resolver la siguiente relajacion lineal
max z = 8x1 + 11x2 + 6x3 + 4x4
6.7x1 + 10x2 + 5.5x3 + 3.4x4 19
x 0,
escrita en Gams as:
$ONTEXT
Ejemplo de Cornuejols, pag. 193
13

(1)

sin considerar integralidad de variables


ni cotas superiores
$OFFTEXT
VARIABLES x1, x2, x3, x4, z;
POSITIVE VARIABLES x1, x2, x3, x4;
EQUATIONS obj, restr;
obj.. z =e= 8*x1 + 11*x2 + 6*x3 + 4*x4;
restr.. 6.7*x1 + 10*x2 + 5.5*x3 + 3.4*x4 =l= 19;
MODEL pag193 /ALL/;
SOLVE pag193 USING LP MAXIMIZING z;
La solucion obtenida es
x = ( 2.8358, 0, 0, 0 ),

z = 22.6866 ,

muy diferente de lo esperado. Coloquemos ahora cotas superiores:


$ONTEXT
Ejemplo de Cornuejols, pag. 193
sin considerar integralidad de variables.
$OFFTEXT
VARIABLES x1, x2, x3, x4, z;
POSITIVE VARIABLES x1, x2, x3, x4;
EQUATIONS obj, restr;
obj.. z =e= 8*x1 + 11*x2 + 6*x3 + 4*x4;
restr.. 6.7*x1 + 10*x2 + 5.5*x3 + 3.4*x4 =l= 19;
x1.UP = 1;
x2.UP = 1;
x3.UP = 1;
x4.UP = 1;
MODEL pag193 /ALL/;
SOLVE pag193 USING LP MAXIMIZING z;
Se obtiene
x = ( 1, 0.89, 0, 1 ),

z = 21.7900 ,

que casi cumple con las restricciones de (1). Finalmente al escribir en Gams la informacion
sobre integralidad de las variables y diciendo que se trata de un problema MIP (mixed integer
programming),
$ONTEXT
ejemplo de Cornuejols, pag. 193
con variables enteras.
$OFFTEXT

14

VARIABLES x1, x2, x3, x4, z;


INTEGER VARIABLES x1, x2, x3, x4;
EQUATIONS obj, restr;
obj.. z =e= 8*x1 + 11*x2 + 6*x3 + 4*x4;
restr.. 6.7*x1 + 10*x2 + 5.5*x3 + 3.4*x4 =l= 19;
x1.UP = 1;
x2.UP = 1;
x3.UP = 1;
x4.UP = 1;
MODEL pag193 /ALL/;
SOLVE pag193 USING MIP MAXIMIZING z;
se obtiene
x = ( 0, 1, 1, 1), z = 20.
El problema (1) no solamente es de optimizacion entera, tambien es un problema de variables
binarias. Entonces en Gams se puede escribir mas corto
$ONTEXT
ejemplo de Cornuejols, pag. 193
con variables binarias.
$OFFTEXT
VARIABLES x1, x2, x3, x4, z;
BINARY VARIABLES x1, x2, x3, x4;
EQUATIONS obj, restr;
obj.. z =e= 8*x1 + 11*x2 + 6*x3 + 4*x4;
restr.. 6.7*x1 + 10*x2 + 5.5*x3 + 3.4*x4 =l= 19;
MODEL pag193 /ALL/;
SOLVE pag193 USING MIP MAXIMIZING z;
En los problemas de optimizacion entera es muy importante tener en cuenta un valor producido
por Gams, se trata de Relative gap. Normalmente Gams no realiza un estudio exhaustivo
del arbol (del metodo de ramificacion y acotamiento). Sea el valor absoluto de la diferencia
relativa entre el mejor valor de z obtenido para un punto entero y el valor estimado del mejor
valor posible de z. Gams se detiene cuando es menor que un valor predeterminado. Si en los
resultados Relative gap es cero, todo funciono bien y el valor de x y z producidos por Gams
son optimos. Cuando el valor no es cero, no hay seguridad sobre el resultado obtenido. En el
u
ltimo ejemplo de Gams el valor de Relative gap es cero y se obtuvo la solucion.
Consideremos un problema parecido a (1):

max z = 8x1 + 11x2 + 5x3 + 4x4


6.7x1 + 10x2 + 5.5x3 + 3.4x4 19
x {0, 1}4 .
Al resolverlo con
15

(2)

VARIABLES x1, x2, x3, x4, z;


BINARY VARIABLES x1, x2, x3, x4;
EQUATIONS obj, restr;
obj.. z =e= 8*x1 + 11*x2 + 5*x3 + 4*x4;
restr.. 6.7*x1 + 10*x2 + 5.5*x3 + 3.4*x4 =l= 19;
MODEL pag193 /ALL/;
SOLVE pag193 USING MIP MAXIMIZING z;
se obtiene
x = ( 1, 1, 0, 0), z = 19,
pero
Best possible:
Absolute gap:
Relative gap:

20.000000
1.000000
0.052632

El valor 0.052632 = 1/(20 1) deja dudas sobre el x obtenido. Entonces es mejor redefinir el
parametro OPTCR con un valor peque
no:
$ONTEXT
Optimizacion con variables binarias.
y definiendo OPTCR
$OFFTEXT
OPTION OPTCR = 0.0001;
VARIABLES x1, x2, x3, x4, z;
BINARY VARIABLES x1, x2, x3, x4;
EQUATIONS obj, restr;
obj.. z =e= 8*x1 + 11*x2 + 5*x3 + 4*x4;
restr.. 6.7*x1 + 10*x2 + 5.5*x3 + 3.4*x4 =l= 19;
MODEL pag193b /ALL/;
SOLVE pag193b USING MIP MAXIMIZING z;
As se obtiene
x = ( 1, 1, 1, 0), z = 20,
solucion optima ya que el valor de Relative gap es cero.

0.9

Un ejemplo de optimizaci
on estoc
astica

Tomado de [BiL97]. Un granjero cultiva trigo, maz y remolacha en un terreno de 500 acres.
El desea saber, en el invierno, cuantos acres dedicar a cada cultivo el a
no que viene. Para sus
animales el necesita por lo menos 200 T (toneladas) de trigo y 240 T de maz. Si su produccion
no es suficiente, el puede comprar cada tonelada a US$238 y US$210 respectivamente. Si
16

sobra de su produccion, el puede vender a US$170 y US$150 cada tonelada. Cada tonelada
de remolacha la puede vender a US$36 pero hasta un maximo de 600 T. Por encima de esa
cantidad, cada tonelada la puede vender a $10. El costo total de cultivar un acre es de US$150,
US$230 y US$260 para trigo, maz y remolacha.
En un planteamiento determinista se conoce el rendimiento de cada cultivo en toneladas por
acre: 2.5, 3 y 20 para trigo, maz y remolacha respectivamente. Cuantos acres debe dedicar
el granjero a cada cultivo para maximizar su beneficio?
Para facilitar el planteamiento y hacerlo mas general, denotemos los datos de la siguiente
manera:
si = costo total de sembrar un acre con el cultivo i = 1, 2, 3,
vi = precio de venta de una tonelada del cultivo i = 1, 2, 3,
vr = segundo precio venta para una tonelada de remolacha,
ci = precio de compra de una tonelada del cultivo i = 1, 2,
di = necesidad o demanda, en T, del cultivo i = 1, 2,
ri = rendimiento, en toneladas por acre, del cultivo i.
El problema se puede plantear u
nicamente con las variables relativas al n
umero de acres por
cultivo, pero puede ser mas claro si se introducen otras variables intermedias:
xi = n
umero de acres dedicados al cultivo i = 1, 2, 3,
yi = n
umero de toneladas compradas del cultivo i = 1, 2,
wi = n
umero de toneladas vendidas del cultivo i = 1, 2, 3,
w
r = n
umero de toneladas de remolacha vendidas al segundo precio,
pi = n
umero toneladas producidas del cultivo i = 1, 2, 3,
z i = ingreso por ventas de los tres cultivos,
z g = gastos por siembra y compras

max z = z i z g
i

z =
g

z =

3
X
i=1
3
X
i=1

3
X

vi wi + vr w r
s i xi +

2
X

c i yi

i=1

xi 500

i=1

pi
pi + yi wi
p3 w3 w
r
w3
x, y, w, w r

= ri xi , i = 1, ...3,
= di , i = 1, 2
=0
600
0

En Gams, se puede esribir as:


17

$ONTEXT
ejemplo del granjero,
Birge Louveaux, p. 4
modelo determinista
$OFFTEXT
SETS
i
clase de cultivo
j(i) granos

/tr, mz, rm/


/tr, mz/;

PARAMETERS
r(i) "rendimiento del cultivo en ton/acre"
/ tr 2.5
mz 3
rm 20 /
s(i) costo de siembra en dolares por ton
/ tr 150
mz 230
rm 260 /
v(i) precio de venta de cultivos en dolares por ton
/ tr 170
mz 150
rm 36 /
c(j) precio de compra de granos en dolares por ton
/ tr 238
mz 210/
d(j) requerimiento o demanda de granos en toneladas
/ tr 200
mz 240 /;
SCALARS
at
area total disponible en acres /500/
tmax tonelaje maximo de remolachas para primer precio /6000/
pr2
segundo precio de venta de la remolacha /10/ ;
VARIABLES
x(i) numero de acres sembrados con el cultivo i
p(i) produccion en toneladas del cultivo i
y(j) numero de ton compradas de grano j
w(i) numero de ton vendidas del cultivo i
wr2
num de ton de rem vendidas al segundo precio
egr
gastos o egresos
ing
ingresos
18

beneficio total;

POSITIVE VARIABLES
x, y, w, wr2;
EQUATIONS
benef
gastos
ingresos
requer(j) requerimiento del cultivo j
produc(i) produccion del cultivo j
area
remo ;
benef..
gastos..
ingresos..
produc(i)..
requer(j)..
area..
remo..

z =e= ing - egr;


egr =e= sum(i, s(i)*x(i) ) + sum(j, c(j)*y(j) );
ing =e= sum(i, v(i)*w(i) ) + pr2*wr2;
p(i) =e= r(i)*x(i);
p(j) + y(j) - w(j) =g= d(j);
sum(i,x(i)) =l= at;
w(rm) + wr2 =e= p(rm);

w.UP(rm) = tmax;
MODEL granjero /ALL/;
SOLVE granjero USING LP MAXIMIZING z;
DISPLAY x.l, p.l, y.l, w.l, wr2.l, z.l;
El resultado es:
----

79 VARIABLE x.L

tr 120.000,

---tr

----

mz

80.000,

79 VARIABLE p.L
300.000,

mz

numero de acres sembrados con el cultivo i


rm 300.000

produccion en toneladas del cultivo

240.000,

79 VARIABLE y.L

tr

----

79 VARIABLE w.L
100.000,

rm 6000.000

numero de ton compradas de grano j

( ALL

----

0.000 )

numero de ton vendidas del cultivo i

rm 6000.000

79 VARIABLE wr2.L

0.000

VARIABLE z.L

118600.000

num de ton de rem vendidas al segundo precio


beneficio total

En el modelo estocastico los rendimientos no son deterministas. El granjero prevee tres posibles
19

escenarios en funcion del tiempo de los u


ltimos tres meses anteriores a la cosecha: rendimiento
bajo, medio y alto:
alto medio bajo
trigo
3
2.5
2
maz
3.6
3
2.4
remolacha
24
20
16
Estos valores los podemos denotar rie = rendimiento del cultivo i en el escenario e.
El granjero cree que cada uno de los tres escenarios tiene una probabilidad de 1/3. Sean i los
valores de la tres probabilidades. Ahora se desea maximizar el valor esperado del beneficio.
Es comodo plantear el problema con variables semejantes a las anteriores, pero todas, salvo las
xi , tendran un subndice adicional correspondiente al escenario: yie , wie , wer , pie , zei , zeg , ze
.

max =

3
X

e ze

e=1

ze = zei zeg
zei
zeg

3
X

i=1
3
X

vi wie + vr wer , e = 1, ..., 3


s i xi +

i=1
3
X

2
X

ci yie , e = 1, ..., 3

i=1

xi 500

i=1

pie
pie + yie wie
p3e w3e w
er
w3e
x, y, w, w r

= rie xi , i = 1, ...3, , e = 1, ..., 3


= di , i = 1, 2 , e = 1, ..., 3
= 0 , e = 1, ..., 3
600 , e = 1, ..., 3
0

En Gams:
$ONTEXT
ejemplo del granjero,
Birge Louveaux, p. 4
modelo estocastico
representacion de escenarios
$OFFTEXT
SETS
20

i
clase de cultivo /tr, mz, rm/
j(i) granos
/tr, mz/
e
escenarios para el rendimiento/ alto, medio, bajo/;
TABLE
tr
mz
rm

r(i,e) rendimiento del cultivo


alto medio bajo
3
2.5
2
3.6 3
2.4
24
20
16 ;

segun escenario

PARAMETERS
s(i) costo de siembra en dolares por ton
/ tr 150
mz 230
rm 260 /
v(i) precio de venta de cultivos en dolares por ton
/ tr 170
mz 150
rm 36 /
c(j) precio de compra de granos en dolares por ton
/ tr 238
mz 210/
d(j) requerimiento o demanda de granos en toneladas
/ tr 200
mz 240 /
pr(e) probabilidad de escenarios
/ alto
0.333333
medio 0.333333
bajo
0.333333 /;
*
/ alto
0
*
medio 1
*
bajo
0 /;
SCALARS
at
area total disponible en acres /500/
tmax tonelaje maximo de remolachas para primer precio /6000/
pr2
segundo precio de venta de la remolacha /10/ ;
VARIABLES
x(i)
p(i,e)
y(j,e)
w(i,e)

numero de acres sembrados con el cultivo i


produccion del cultivo i en el escenario e
num de ton compradas de grano j en el escenario e
num de ton vendidas del cultivo i en el escenario e
21

wr2(e)
egr(e)
ing(e)
z(e)
zz

num de ton de rem vendidas al sdo precio en el escenario


gastos o egresos en el escenario e
ingresos en el escenario e
beneficio en un escenario
beneficio esperado;

POSITIVE VARIABLES
x, y, w, wr2;
EQUATIONS
ben_esp
ben_esc(e) beneficio en un escenario
gastos(e)
ingresos(e)
requer(j,e) requerimiento del cultivo j en un escenario
produc(i,e) produccion del cultivo i
area
remo(e) ;
ben_esp..
ben_esc(e)..
gastos(e)..
ingresos(e)..
produc(i,e)..
requer(j,e)..
area..
remo(e)..

zz =e= sum(e, pr(e)*z(e) );


z(e) =e= ing(e) - egr(e);
egr(e) =e= sum(i, s(i)*x(i) ) + sum(j, c(j)*y(j,e) );
ing(e) =e= sum(i, v(i)*w(i,e) ) + pr2*wr2(e);
p(i,e) =e= r(i,e)*x(i);
p(j,e) + y(j,e) - w(j,e) =g= d(j);
sum(i,x(i)) =l= at;
w(rm,e) + wr2(e) =e= p(rm,e);

w.UP(rm,e) = tmax;
MODEL granjero /ALL/;
SOLVE granjero USING LP MAXIMIZING zz;
DISPLAY x.l, p.l, y.l, w.l, wr2.l, z.l, zz.l;
Resultados:
----

88 VARIABLE x.L

tr 170.000,

----

tr
mz
rm

----

mz

numero de acres sembrados con el cultivo i

80.000,

88 VARIABLE p.L

rm 250.000

produccion del cultivo

alto

medio

bajo

510.000
288.000
6000.000

425.000
240.000
5000.000

340.000
192.000
4000.000

88 VARIABLE y.L

i en el escenario

num de ton compradas de grano j en el escenario

bajo

22

mz

48.000

----

tr
mz
rm

88 VARIABLE w.L

num de ton vendidas del cultivo i en el escenario

alto

medio

bajo

310.000
48.000
6000.000

225.000

140.000

5000.000

4000.000

----

88 VARIABLE wr2.L

num de ton de rem vendidas al sdo precio en el escenario

( ALL

---alto

88 VARIABLE z.L
167000.000,

----

0.10

0.000 )

beneficio en un escenario

medio 109350.000,

88 VARIABLE zz.L

bajo

48820.000

108389.892

beneficio esperado

El problema lockbox

Tomado de [CoT07]. Una compa


na de nivel nacional recibe cheques de todo el pas. Por el
correo mismo y por los tramites bancarios transcurre un tiempo (en das) entre el momento en
que el cheque es recibido en la oficina de correo y el momento en que la compa
na recibe en
su cuenta el valor del cheque. Este tiempo de tramite vara dependiendo de las ciudades. La
compa
na desea abrir algunas oficinas (lockboxes) para centralizar la recepcion de cheques.
Supongamos que hay cuatro regiones R1 , R2 , R3 y R4 y que habra oficinas centrales en cuatro
ciudades C1 , C2 , C3 y C4 . Los tiempos de tramite entre las regiones y las ciudades son:

Region
Region
Region
Region

1
2
3
4

Ciudad 1 Ciudad 2 Ciudad 3 Ciudad 4 $ 106


2
4
6
6
1200
4
2
5
5
480
6
5
2
5
1440
7
5
6
3
720

En la u
ltima columna aparece el promedio diario (en millones de pesos) de la suma total
proveniente de cada una de las cuatro regiones. El manejo y administracion anual de cada
central es de 180 millones de pesos.
Supongamos por facilidad que, para calcular la perdida de interes por la demora en el cheque,
la tasa nominal es de 5% anual y que para estas cuentas todos los da del a
no son habiles.
Supongamos ademas que como el n
umero de das es peque
no se puede usar la formula de
interes simple.
Los cheques de una region se envan a una sola ciudad pero es posible enviar los cheques de
dos regiones diferentes a la misma central. Se desea saber que centrales abrir y a que central
se deben enviar los cheques de cada region.
Consideremos las siguientes variables, todas binarias:
23

yj = 1 si se abre la oficina central en la ciudad j; yj = 0 en caso contrario.


xij = 1 si los cheques de la region i se envan a la ciudad j.
Sea n el n
umero de das en un a
no. Entonces la tasa diaria de interes es 0.05/n . As, por
ejemplo, si los cheques de R1 se envan a C2 , entonces diariamente se dejan de ganar
0.05
4
n
Al hacer la cuenta para todo el a
no, la perdida es de
$1.200 000.000

n $1.200 000.000

0.05
4 = $240 000.000
n

As podemos construir una tabla donde estan los valores pij de perdidass anuales en millones
de pesos.

Region
Region
Region
Region

1
2
3
4

min z =

Ciudad 1 Ciudad 2 Ciudad 3 Ciudad 4


120
240
360
360
96
48
120
120
432
360
144
360
252
180
216
108

4 X
4
X

pij xij + 180

i=1 j=1

4
X

yj

j=1
4
X

xij = 1,

i = 1, ..., 4

j=1
4
X

xij 4yj , j = 1, ..., 4

i=1

xij , yj {0, 1} .
La segunda restriccion quiere decir: si yj = 0, entonces x1j = x2j = x3j = x4j = 0 .
$ONTEXT
problema lockbox, Cornuejols, p. 213-215
escritura estructurada
$OFFTEXT
OPTION OPTCR = 0.0001;
SETS
i regiones /r1*r4/
j ciudades /c1*c4/ ;
TABLE p(i,j) perdida de intereses en millones
c1
c2
c3
c4

24

r1
r2
r3
r4

120
96
432
252

240
48
360
180

360
120
144
216

360
120
360
108;

SCALAR coc de una oficina central /180/;


VARIABLES
x(i,j) los cheques de la region ri van a la ciudad cj
y(j)
la central en la ciudad cj se abre
z
costo total en millones;
BINARY VARIABLES x, y;
EQUATIONS
costo
funcion ojetivo
sale(i) lo que sale de una region
llega(j) lo que llega a una ciudad;
costo..
z =e= sum( (i,j), p(i,j)*x(i,j) ) + coc*sum(j,
y(j) );
sale(i).. sum( j, x(i,j) ) =e= 1;
llega(j).. sum(i, x(i,j) ) - 4*y(j) =l= 0;
MODEL lockbox /ALL/;
SOLVE lockbox USING MIP MINIMIZING z;

0.11

Subasta combinatoria

Tomado de [CoT07]. En algunas subastas los elementos aparecen agrupados por paquetes no
necesariamente disyuntos y la oferta que hace el posible comprador por cada paquete no es la
suma de los precios de sus elementos, puede ser mayor o menor.
Sea M = {1, 2, ..., m} el conjunto de elementos. El subastador recibe n ofertas, cada una es una
pareja Bj = (Sj , pj ), donde Sj es un conjunto de elementos (Sj M ) y pj es el valor propuesto
por el posible comprador. El subastador desea saber cuales ofertas aceptar para maximizar los
ingresos.
Sea xj una variable que vale 1 si el subastador acepta la oferta j y vale cero en caso contrario.

max

n
X

p j xj

j=1

xj 1, i = 1, ..., m

j : iSj

xj {0, 1}, j = 1, .., n.


Ejemplo: Sean 4 elementos y 6 ofertas

25

B1
B2
B3
B4
B5
B6

= ({1}, 6)
= ({2}, 3)
= ({3, 4}, 12)
= ({1, 3}, 12)
= ({2, 4}, 8)
= ({1, 3, 4}, 16)

max 6x1 +3x2 +12x3 +12x4 +8x5 +16x6


x1
+x4
+x6
x2
+x5
x3
+x4
+x6
x3
+x5
+x6
xj

1
1
1
1
{0, 1}, j = 1, ..., 6.

En Gams
$ONTEXT
Subasta combinatoria, Cornuejols, p. 213
$OFFTEXT
VARIABLES x1, x2, x3, x4, x5, x6, z;
BINARY VARIABLES x1, x2, x3, x4, x5, x6;
EQUATIONS obj, el1, el2, el3, el4;
obj.. z =e= 6*x1 + 3*x2 + 12*x3 + 12*x4 + 8*x5 + 16*x6;
el1.. x1 + x4 + x6 =l= 1;
el2.. x2 + x5
=l= 1;
el3.. x3 + x4 + x6 =l= 1;
el4.. x3 + x5 + x6 =l= 1;
MODEL pag213 /ALL/;
SOLVE pag213 USING MIP MAXIMIZING z;
La solucion es
x = (1, 1, 1, 0, 0, 0),

z = 21.

REFERENCIAS
[Bil97] Birge J.R., Louveaux F., Introduccion to stochastic Programming, Spinger, New York,
1997.
[CoT07] Cornuejols G., Tutuncu R., Optimization Methods in Finance, Cambridge Univ. Press,
2007.

26