You are on page 1of 17

Cmo resolver problemas de

programaci lineal usando Linux


Camilo Bernal
4 de diciembre de 2014

1.

Introduccin

Aunque la realidad es compleja y la mayora de los problemas computables que se presentan no se pueden expresar como relaciones lineales (frecuentemente ni siquiera se
conocen sus relaciones), dentro de las matemticas aplicadas hay una vasta disciplina
que se llama Investigacin de Operaciones, y dentro de esta se encuentra un gnero
particular de problemas que recibe el nombre de programacin lineal.
La programacin lineal se encarga de encontrar soluciones a problemas complejos cuyas
relaciones entre sus elementos se pueden expresar como relaciones lineales. Esta tcnica
tiene buenas posibilidades de aplicacin a problemas de asignacin de recursos, gestin
logstica, bsqueda del mnimo costo o de la mxima utilidad. . . sujetos a una serie de
restricciones.
Este documento tiene como objetivo presentar una propuesta para resolver problemas
de programacin lineal usando el sistema operativo GNU/Linux, el programa GLPK y el
lenguaje de modelamiento GNU MathProg. Se busca ofrecer una metodologa muy simple
e intuitiva para resolver problemas de programacin lineal simples y de programacin
lineal mixta.
En la seccin 2 se describe el programa GLPK. La seccin 3 presenta el lenguaje de modelamiento GNU MathProg. La seccin 4 explica cmo usar el lenguaje GNU MathProg
en el programa GLPK. Las secciones 5 y 6 contienen la metodologa propuesta para
resolver problemas lineales y las conclusiones, respectivamente.

2.

Qu es GLPK?

GLPK (GNU Linear Programming Kit) es un conjunto de rutinas escritas en el lenguaje


de programacin ANSI C organizadas en forma de libreras que se pueden invocar. Su
intencin es resolver problemas de programacin lineal (LP), Programacin entera mixta
(MIP), y otros problemas relacionados [Markhorin, 2010a].

3.

Qu es GNU MathProg?

GNU MathProg es un lenguaje de modelamiento que sirve para escribir modelos de


programacin lineal. Estos modelos consisten en una serie de bloques de sentencias y
datos construidos por el usuario [Markhorin, 2010b].
En un proceso llamado traduccin, un programa llamado el traductor del modelo analiza
la descripcin del modelo y lo traduce a estructuras de datos internos, los cuales pueden
ser usados tanto para generar una instancia del problema de programacin matemtica
como para obtener una solucin numrica del problema con un programa llamado solver
[bid].

4.

Cmo usar GNU MathProg en GLPK?

El paquete GLPK incluye el programa glpsol, que acta como solver de problemas
LP/MIP. Este programa se puede lanzar desde la lnea de comandos para resolver modelos escritos en el lenguaje GNU MathProg [Markhorin, 2010b, Op. Cit.].
Para conocer los fundamentos de la sintaxis de GNU MathProg, vase el anexo A.

5.

Construccin de modelos de programacin lineal

5.1.

Formulacin bsica de un modelo matemtico de


programacin lineal

Un modelo matemtico de programacin lineal se puede definir de la forma:


M inimizar/M aximizar Z = F (X)
sujeto a:
G (x X) = B (B R)
Donde:
Z: Valor que toma la funcin objetivo de la cual se busca obtener el mnimo o mximo
valor, segn sea el caso.
F : Funcin dada en trminos de X
X: Conjunto de variables que conforman el problema planteado
G: Conjunto de funciones de restriccin que estn dadas en trminos de un subconjunto
de X y que deben satisfacer un valor B
B: Conjunto de valores que debe satisfacer el conjunto de restricciones G

5.2.

Metodologa planteada para la resolucin de modelos de


programacin lineal

5.2.1.

Organizacin del problema

Se sugiere seguir los siguientes pasos:


1. Crear un directorio especfico para el problema:
mkdir ./Nombre del problema
2. Crear dos ficheros de texto, uno llamado Nombre_modelo.mod con contendr la
descripcin del modelo, y otro llamado Datos.dat, donde se almacenarn los valores
de los parmetros del modelo planteado.

5.2.2.

Invocacin del solver

Una vez que se haya completado la descripcin del modelo (ficheros Nombre_modelo.mod
y Datos.dat), se puede invocar al solver en la lnea de comandos para resolver el modelo
de la siguiente manera:

glpsol --math -m modelo.mod -d datos.dat -o solucion.sol --wlp modelo_lineal.txt

donde:
glpsol: Es la llamada al solver, que intentar encontrar una solucin numrica al problema
math: Indica que el modelo est escrito en el lenguaje GNU MathProg
-m: Indica que a continuacin se escribir el nombre del fichero que contiene la descripcin del modelo
-d: Indica que a continuacin se escribir el nombre del fichero que contiene los valores
de los parmetros del modelo
-o: Indica qu nombre se le dar a la solucin encontrada por el solver
wlp: Indica qu nombre se le dar al fichero que va a contener una versin compacta
del modelo planteado, la cual servir para realizar anlisis

6.

Conclusiones
Es posible usar herramientas GNU/Linux y/o Software Libre para solucionar problemas lineales de una forma intuitiva y sistemtica.
La metodologa planteada permite la resolucin de problemas de programacin
lineal y programacin mixta de una manera detallada y fcil de comprender.

Referencias
[Markhorin, 2010a] Makhorin, Andrew. GNU Linear Programming Kit - Reference Manual. Department for Applied Informatics, Moscow Aviation Institute, Moscow, Russia. 2010.
[Markhorin, 2010b] Makhorin, Andrew. Modeling Language GNU MathProg - Language
Reference for GLPK Version 4.45. Department for Applied Informatics, Moscow Aviation Institute, Moscow, Russia. 2010.

A.

Fundamentos de la sintaxis de MathProg

El lenguaje de modelamiento MathProg se usar para escribir dos ficheros: el problema


y el valor de los parmetros. Aunque se puede hacer todo en un nico fichero, dividirlo
en dos resulta ms prctico para analizar secciones particulares, y hacer el proceso de
depuracin1 .
El fichero de descripcin del modelo puede tener la siguiente estructura:
Descripcin preliminar
Definicin de ndices
Definicin de parmetros
Definicin de variables
Definicin de funcin objetivo
Definicin de restricciones
Finalizar
El fichero que contiene los valores de los parmetros tiene una estructura ms simple:
Descripcin de parmetro 1
Asignacin de valores al parmetro 1
Descripcin de parmetro 2
Asignacin de valores al parmetro 2
...
Descripcin de parmetro n
Asignacin de valores al parmetro n
1

Cuando los modelos son muy grandes, es inevitable cometer errores, y por lo tanto se debe iniciar un
proceso de depuracin similar al que se usa cuando se depura un mdulo escrito en algn lenguaje
de programacin y que hace parte de una aplicacin ms grande

10

Finalizar
Para realizar comentarios se puede usar el smbolo # para comentarios de una sola
lnea o se pueden realizar comentarios de mltiples lneas que deben comenzar con /* y
terminar con */. Por ejemplo:
# Este comentario tiene una sola lnea
/* Este comentario
tiene
varias lneas */

Los ndices son etiquetas que identifican a una variable. Por ejemplo, supongamos que
X representa un conjunto de variables del costo de transportar una mercanca de un
punto a otro. Entonces se puede codificar la variable como sigue:
xij : Costo de transportar la mercanca desde el punto i hasta el punto j.
{i I j J xij X(i, j) X R+ }
donde I, J representan los conjuntos de orgenes y destinos, respectivamente.
En este ejemplo i, j son ndices que sirven para identificar un origen y un destino,
respectivamente. En MathProg se codificaran los ndices como sigue:
set I;
/* Origenes de mercancia */
set J;
/* Destinos de mercanca */

Los parmetros son valores conocidos que harn parte del modelo. Por ejemplo, supongamos que B representa al nmero de camiones disponibles para transportar mercancia.
En MathProg se codifican los parmetros como sigue:
param B{i in I, j in J};
/* Nmero de camiones disponibles para transportar mercancia desde i hasta j */

La variables son trminos indeterminados que pueden tomar algn valor en un rango de
datos. Para la variable descrita arriba, en MathProg se escribe:
var x{i in I, j in J} >= 0;
/* Costo de transportar la mercancia desde el punto i hasta el punto j */

11

La funcin objetivo es una magnitud dependiente de las variables en funcin de las cuales
est expresada. Esta magnitud se intenta reducir al mnimo a agrandar tanto como se
posible. En MathProg se puede expresar como:
minimize/maximize cost: sum{i in I, j in J} x[i,j];
/* Minimizar el costo de transporte */

Las restricciones son condiciones que limitan los valores que puede tomar una variable.
Por ejemplo, supongamos que para ir hasta un punto j se pueden utilizar mximo un
nmero M Cj de camiones. En MathProg se expresara as:
s.t. camiones_destino{j in J}: sum{i in I} x[i,j] <= MC[j];
/* Mximo nmero de camiones que puede ir hasta un destino j */

Para indicar que se finaliza un fichero, en MathProg se escribe:


end;

Cuando hay que dar un valor a los parmetros se utiliza para palabra reservada set
param. Supongamos que queremos dar valor a algunos parmetros de nuestro ejemplo.
En MathProg podra ser como sigue:
Set I := Bogota Caracas Lima Quito;
/* Orgenes de mercancia */
Set J := Rio Buenos-Aires Santiago;
/* Destinos de mercancia */
param B : Rio
Buenos-Aires
Santiago :=
Bogota
78
86
56
Caracas
88
.
.
Lima
89
90
.
Quito
.
.
100;
/* Camiones disponibles para los diferentes trayectos */

Aqu, . significa que no hay informacin disponible.

B.

Problema de transporte de mercanca

Un problema de transporte puede consistir en llevar mercancas desde distintas plantas de


fabricacin hasta diferentes mercados. Las distancias entre los puntos de produccin y los

12

puntos de consumo son diferentes para cada caso y por lo tanto sus costos de transporte
tambin varan. Adems, las plantas tienen diversas capacidades de produccin y los
mercados demandan diversas cantidades de producto. El problema consiste en llevar las
mercancas desde los puntos de produccin hasta los puntos de consumo reduciendo al
mnimo los costos de transporte. El modelo matemtico de programacin lineal se puede
plantear como sigue:
M in Z =

ij

cij xij

s.a:
P
P

xij cpi (Capacidad de produccin)

xij dej (Demanda)

xij 0
Donde:
cij : Costo de transporte de mercancia por unidad de longitud desde la planta i hasta el
mercado j
xij : Cantidad de mercancia transportada desde la planta i hasta el mercado j
cpi : Capacidad de produccin de la planta i
dej : Demanda del mercado j
En MathProg se puede codificar el problema de la siguiente manera:
-> En el fichero del modelo (Problema de transporte de mercanca.mod):
# ======================
# Descripcin preliminar
# ======================
/* Se requiere transportar mercancias. Las distancias entre los puntos de produccin
y los puntos de consumo son diferentes para cada caso y por lo tanto sus costos de
transporte tambin varan. Adems, las plantas tienen diversas capacidades de
produccin y los mercados demandan diversas cantidades de producto. El problema
consiste en llevar las mercancas desde los puntos de produccin hasta los puntos de

13

consumo reduciendo al mnimo los costos de transporte.*/


# =====================
# Definicin de ndices
# =====================
set I;
/* Plantas de produccin */
set J;
/* Mercados */
# ========================
# Definicin de parmetros
# ========================
param cp{i in I};
/* Capacidad de la planta i */
param dm{j in J};
/* Demanda en el mercado j */
param dist{i in I, j in J};
/* Distancia entre la planta i y el mercado j */
param f;
/* Costo del flete por unidad de longitud */
param c{i in I, j in J} := f * dist[i,j] / 1000;
/* Costo del transporte desde la planta i hasta el mercado j*/
# =======================
# Definicin de variables
# =======================
var x{i in I, j in J} >= 0;
/* Cantidad de mercancia transportada */
# ==============================
# Definicin de funcin objetivo
# ==============================
minimize costo_trnasporte: sum{i in I, j in J} c[i,j] * x[i,j];
/* Costo total de transporte */
# ===========================
# Definicin de restricciones
# ===========================
s.t. suministro{i in I}: sum{j in J} x[i,j] <= cp[i];

14

/* lmite de suministro de la planta i */


s.t. demanda{j in J}: sum{i in I} x[i,j] >= dm[j];
/* satisfacer la demanda en el mercado j */
# ==========
# Finalizar
# ==========
end;

-> En el fichero que contiene los datos (Datos.dat):


set I := Bogota Caracas;
/* Plantas de produccion */
set J := Rio B-Aires Santiago;
/* Mercados */
param cp := Bogota 350
Caracas 600;
/* Capacidad de planta*/
param dm := Rio 325
B-Aires 300
Santiago 275;
/* Demanda de mercado */
param dist : Rio
Bogota
2.5
Caracas 2.5

B-Aires
1.7
1.8

Santiago :=
1.8
1.4;

/* Distancias*/
param f := 90;
/* Flete */
end;
/* Finalizar */

Una vez construidos los dos ficheros en el directorio correspondiente, se invoca al solver:

15

glpsol --math -m Problema de transporte de mercancia.mod -d Datos.dat


-o solucion.sol --wlp modelo_lineal.txt
Al hacer esto, se crean dos nuevos ficheros. En el fichero solucion.sol se encuentra la
solucin:
Problem: Problema
Rows:
6
Columns: 6
Non-zeros: 18
Status: OPTIMAL
Objective: costo_trnasporte = 153.675 (MINimum)
No.
Row name
St
Activity
Lower bound
Upper bound Marginal
------ ------------ -- ------------- ------------- ------------- ------------1 costo_trnasporte
B
153.675
2 suministro[Bogota]
NU
350
350 < eps
3 suministro[Caracas]
B
550
600
4 demanda[Rio]
NL
325
325
0.225
5 demanda[B-Aires]
NL
300
300
0.153
6 demanda[Santiago]
NL

275

275

0.126

No.
Column name St Activity
Lower bound
Upper bound
Marginal
------ ------------ -- ------------- ------------- ------------- ------------1 x[Bogota,Rio]
B
50
0
2 x[Bogota,B-Aires]
B
300
0
3 x[Bogota,Santiago]
NL
0
0
0.036
4 x[Caracas,Rio]
B
275
0
5 x[Caracas,B-Aires]
NL
0
0
0.009
6 x[Caracas,Santiago]
B
275
0
Karush-Kuhn-Tucker optimality conditions:

16

KKT.PE: max.abs.err = 1.06e-14 on row 1


max.rel.err = 3.44e-17 on row 1
High quality
KKT.PB: max.abs.err = 0.00e+00 on row 0
max.rel.err = 0.00e+00 on row 0
High quality
KKT.DE: max.abs.err = 2.78e-17 on column 1
max.rel.err = 1.91e-17 on column 1
High quality
KKT.DB: max.abs.err = 0.00e+00 on row 0
max.rel.err = 0.00e+00 on row 0
High quality
End of output

En el fichero modelo_lineal.txt se encuentra un modelo compacto:


\* Problem: Problema *\
Minimize
costo_trnasporte: + 0.225 x(Bogota,Rio) + 0.153 x(Bogota,B~Aires)
+ 0.162 x(Bogota,Santiago) + 0.225 x(Caracas,Rio)
+ 0.162 x(Caracas,B~Aires) + 0.126 x(Caracas,Santiago)
Subject To
suministro(Bogota): + x(Bogota,Rio) + x(Bogota,B~Aires)
+ x(Bogota,Santiago) <= 350
suministro(Caracas): + x(Caracas,Rio) + x(Caracas,B~Aires)
+ x(Caracas,Santiago) <= 600
demanda(Rio): + x(Bogota,Rio) + x(Caracas,Rio) >= 325
demanda(B~Aires): + x(Bogota,B~Aires) + x(Caracas,B~Aires) >= 300
demanda(Santiago): + x(Bogota,Santiago) + x(Caracas,Santiago) >= 275

End

17

You might also like