Cómo Resolver Problemas de Programación Lineal Usando Linux

17
Cómo resolver problemas de programació lineal usando Linux Camilo Bernal 4 de diciembre de 2014 1

description

Programacion lineal con linux

Transcript of Cómo Resolver Problemas de Programación Lineal Usando Linux

Page 1: Cómo Resolver Problemas de Programación Lineal Usando Linux

Cómo resolver problemas deprogramació lineal usando Linux

Camilo Bernal

4 de diciembre de 2014

1

Page 2: Cómo Resolver Problemas de Programación Lineal Usando Linux

1. Introducción

Aunque la realidad es compleja y la mayoría de los problemas computables que se pre-sentan no se pueden expresar como relaciones lineales (frecuentemente ni siquiera seconocen sus relaciones), dentro de las matemáticas aplicadas hay una vasta disciplinaque se llama Investigación de Operaciones, y dentro de esta se encuentra un géneroparticular de problemas que recibe el nombre de programación lineal.

La programación lineal se encarga de encontrar soluciones a problemas complejos cuyasrelaciones entre sus elementos se pueden expresar como relaciones lineales. Esta técnicatiene buenas posibilidades de aplicación a problemas de asignación de recursos, gestiónlogística, búsqueda del mínimo costo o de la máxima utilidad. . . sujetos a una serie derestricciones.

Este documento tiene como objetivo presentar una propuesta para resolver problemasde programación lineal usando el sistema operativo GNU/Linux, el programa GLPK y ellenguaje de modelamiento GNUMathProg. Se busca ofrecer una metodología muy simplee intuitiva para resolver problemas de programación lineal simples y de programaciónlineal mixta.

En la sección 2 se describe el programa GLPK. La sección 3 presenta el lenguaje de mo-delamiento GNU MathProg. La sección 4 explica cómo usar el lenguaje GNU MathProgen el programa GLPK. Las secciones 5 y 6 contienen la metodología propuesta pararesolver problemas lineales y las conclusiones, respectivamente.

2

Page 3: Cómo Resolver Problemas de Programación Lineal Usando Linux

2. ¿Qué es GLPK?

GLPK (GNU Linear Programming Kit) es un conjunto de rutinas escritas en el lenguajede programación ANSI C organizadas en forma de librerías que se pueden invocar. Suintención es resolver problemas de programación lineal (LP), Programación entera mixta(MIP), y otros problemas relacionados [Markhorin, 2010a].

3

Page 4: Cómo Resolver Problemas de Programación Lineal Usando Linux

3. ¿Qué es GNU MathProg?

GNU MathProg es un lenguaje de modelamiento que sirve para escribir modelos deprogramación lineal. Estos modelos consisten en una serie de bloques de sentencias ydatos construidos por el usuario [Markhorin, 2010b].

En un proceso llamado traducción, un programa llamado el traductor del modelo analizala descripción del modelo y lo traduce a estructuras de datos internos, los cuales puedenser usados tanto para generar una instancia del problema de programación matemáticacomo para obtener una solución numérica del problema con un programa llamado solver[Íbid].

4

Page 5: Cómo Resolver Problemas de Programación Lineal Usando Linux

4. ¿Cómo usar GNU MathProg en GLPK?

El paquete GLPK incluye el programa glpsol, que actúa como solver de problemasLP/MIP. Este programa se puede lanzar desde la línea de comandos para resolver mo-delos escritos en el lenguaje GNU MathProg [Markhorin, 2010b, Op. Cit.].

Para conocer los fundamentos de la sintaxis de GNU MathProg, véase el anexo A.

5

Page 6: Cómo Resolver Problemas de Programación Lineal Usando Linux

5. Construcción de modelos de programación lineal

5.1. Formulación básica de un modelo matemático deprogramación lineal

Un modelo matemático de programación lineal se puede definir de la forma:

Minimizar/Maximizar Z = F (X)

sujeto a:

G (x ⊆ X) = B (B ∈ R)

Donde:

Z: Valor que toma la función objetivo de la cual se busca obtener el mínimo o máximovalor, según sea el caso.

F : Función dada en términos de X

X: Conjunto de variables que conforman el problema planteado

G: Conjunto de funciones de restricción que están dadas en términos de un subconjuntode X y que deben satisfacer un valor B

B: Conjunto de valores que debe satisfacer el conjunto de restricciones G

5.2. Metodología planteada para la resolución de modelos deprogramación lineal

5.2.1. Organización del problema

Se sugiere seguir los siguientes pasos:

1. Crear un directorio específico para el problema:mkdir ./’Nombre del problema’

2. Crear dos ficheros de texto, uno llamado Nombre_modelo.mod con contendrá ladescripción del modelo, y otro llamado Datos.dat, donde se almacenarán los valoresde los parámetros del modelo planteado.

6

Page 7: Cómo Resolver Problemas de Programación Lineal Usando Linux

5.2.2. Invocación del solver

Una vez que se haya completado la descripción del modelo (ficheros Nombre_modelo.mody Datos.dat), se puede invocar al solver en la línea de comandos para resolver el modelode 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 solución numérica al pro-blema

–math: Indica que el modelo está escrito en el lenguaje GNU MathProg

-m: Indica que a continuación se escribirá el nombre del fichero que contiene la descrip-ción del modelo

-d: Indica que a continuación se escribirá el nombre del fichero que contiene los valoresde los parámetros del modelo

-o: Indica qué nombre se le dará a la solución encontrada por el solver

–wlp: Indica qué nombre se le dará al fichero que va a contener una versión compactadel modelo planteado, la cual servirá para realizar análisis

7

Page 8: Cómo Resolver Problemas de Programación Lineal Usando Linux

6. Conclusiones

Es posible usar herramientas GNU/Linux y/o Software Libre para solucionar pro-blemas lineales de una forma intuitiva y sistemática.

La metodología planteada permite la resolución de problemas de programaciónlineal y programación mixta de una manera detallada y fácil de comprender.

8

Page 9: Cómo Resolver Problemas de Programación Lineal Usando Linux

Referencias

[Markhorin, 2010a] Makhorin, Andrew. GNU Linear Programming Kit - Reference Ma-nual. Department for Applied Informatics, Moscow Aviation Insti-tute, Moscow, Russia. 2010.

[Markhorin, 2010b] Makhorin, Andrew. Modeling Language GNUMathProg - LanguageReference for GLPK Version 4.45. Department for Applied Informa-tics, Moscow Aviation Institute, Moscow, Russia. 2010.

9

Page 10: Cómo Resolver Problemas de Programación Lineal Usando Linux

A. Fundamentos de la sintaxis de MathProg

El lenguaje de modelamiento MathProg se usará para escribir dos ficheros: el problemay el valor de los parámetros. Aunque se puede hacer todo en un único fichero, dividirloen dos resulta más práctico para analizar secciones particulares, y hacer el proceso dedepuración1.

El fichero de descripción del modelo puede tener la siguiente estructura:

Descripción preliminar

Definición de índices

Definición de parámetros

Definición de variables

Definición de función objetivo

Definición de restricciones

Finalizar

El fichero que contiene los valores de los parámetros tiene una estructura más simple:

Descripción de parámetro 1

Asignación de valores al parámetro 1

Descripción de parámetro 2

Asignación de valores al parámetro 2

. . .

Descripción de parámetro n

Asignación de valores al parámetro n1Cuando los modelos son muy grandes, es inevitable cometer errores, y por lo tanto se debe iniciar un

proceso de depuración similar al que se usa cuando se depura un módulo escrito en algún lenguajede programación y que hace parte de una aplicación más grande

10

Page 11: Cómo Resolver Problemas de Programación Lineal Usando Linux

Finalizar

Para realizar comentarios se puede usar el símbolo # para comentarios de una solalínea o se pueden realizar comentarios de múltiples líneas que deben comenzar con /* yterminar con */. Por ejemplo:

# Este comentario tiene una sola línea/* Este comentariotienevarias líneas */

Los índices son etiquetas que identifican a una variable. Por ejemplo, supongamos queX representa un conjunto de variables del costo de transportar una mercancía de unpunto a otro. Entonces se puede codificar la variable como sigue:

xij: Costo de transportar la mercancía 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 orígenes y destinos, respectivamente.

En este ejemplo i, j son índices que sirven para identificar un origen y un destino,respectivamente. En MathProg se codificarían los índices como sigue:

set I;/* Origenes de mercancia */set J;/* Destinos de mercancía */

Los parámetros son valores conocidos que harán parte del modelo. Por ejemplo, supon-gamos que B representa al número de camiones disponibles para transportar mercancia.En MathProg se codifican los parámetros como sigue:

param B{i in I, j in J};/* Número de camiones disponibles para transportar mercancia desde i hasta j */

La variables son términos indeterminados que pueden tomar algún valor en un rango dedatos. 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

Page 12: Cómo Resolver Problemas de Programación Lineal Usando Linux

La función objetivo es una magnitud dependiente de las variables en función de las cualesestá expresada. Esta magnitud se intenta reducir al mínimo a agrandar tanto como seposible. 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 máximo unnúmero MCj de camiones. En MathProg se expresaría así:

s.t. camiones_destino{j in J}: sum{i in I} x[i,j] <= MC[j];/* Máximo número 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 parámetros se utiliza para palabra reservada set óparam. Supongamos que queremos dar valor a algunos parámetros de nuestro ejemplo.En MathProg podría ser como sigue:

Set I := Bogota Caracas Lima Quito;/* Orígenes de mercancia */Set J := Rio Buenos-Aires Santiago;/* Destinos de mercancia */param B : Rio Buenos-Aires Santiago :=Bogota 78 86 56Caracas 88 . .Lima 89 90 .Quito . . 100;/* Camiones disponibles para los diferentes trayectos */

Aquí, ’.’ significa que no hay información disponible.

B. Problema de transporte de mercancía

Un problema de transporte puede consistir en llevar mercancías desde distintas plantas defabricación hasta diferentes mercados. Las distancias entre los puntos de producción y los

12

Page 13: Cómo Resolver Problemas de Programación Lineal Usando Linux

puntos de consumo son diferentes para cada caso y por lo tanto sus costos de transportetambién varían. Además, las plantas tienen diversas capacidades de producción y losmercados demandan diversas cantidades de producto. El problema consiste en llevar lasmercancías desde los puntos de producción hasta los puntos de consumo reduciendo almínimo los costos de transporte. El modelo matemático de programación lineal se puedeplantear como sigue:

Min Z = ∑ij cij ∗ xij

s.a:

∑j xij ≤ cpi(Capacidad de producción)

∑i xij ≥ dej(Demanda)

xij ≥ 0

Donde:

cij: Costo de transporte de mercancia por unidad de longitud desde la planta i hasta elmercado j

xij: Cantidad de mercancia transportada desde la planta i hasta el mercado j

cpi: Capacidad de producción 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 mercancía.mod):

# ======================# Descripción preliminar# ======================

/* Se requiere transportar mercancias. Las distancias entre los puntos de producción

y los puntos de consumo son diferentes para cada caso y por lo tanto sus costos de

transporte también varían. Además, las plantas tienen diversas capacidades de

producción y los mercados demandan diversas cantidades de producto. El problema

consiste en llevar las mercancías desde los puntos de producción hasta los puntos de

13

Page 14: Cómo Resolver Problemas de Programación Lineal Usando Linux

consumo reduciendo al mínimo los costos de transporte.*/

# =====================# Definición de índices# =====================set I;/* Plantas de producción */set J;

/* Mercados */

# ========================# Definición de parámetros# ========================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*/

# =======================# Definición de variables# =======================var x{i in I, j in J} >= 0;

/* Cantidad de mercancia transportada */

# ==============================# Definición de función objetivo# ==============================minimize costo_trnasporte: sum{i in I, j in J} c[i,j] * x[i,j];

/* Costo total de transporte */

# ===========================# Definición de restricciones# ===========================s.t. suministro{i in I}: sum{j in J} x[i,j] <= cp[i];

14

Page 15: Cómo Resolver Problemas de Programación Lineal Usando Linux

/* límite 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 350Caracas 600;

/* Capacidad de planta*/

param dm := Rio 325B-Aires 300Santiago 275;

/* Demanda de mercado */

param dist : Rio B-Aires Santiago :=Bogota 2.5 1.7 1.8Caracas 2.5 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

Page 16: Cómo Resolver Problemas de Programación Lineal Usando Linux

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 lasolución:

Problem: ProblemaRows: 6Columns: 6Non-zeros: 18Status: OPTIMALObjective: costo_trnasporte = 153.675 (MINimum)No. Row name St Activity Lower bound Upper bound Marginal------ ------------ -- ------------- ------------- ------------- -------------1 costo_trnasporte

B 153.6752 suministro[Bogota]

NU 350 350 < eps3 suministro[Caracas]

B 550 6004 demanda[Rio] NL 325 325 0.2255 demanda[B-Aires]

NL 300 300 0.1536 demanda[Santiago]

NL 275 275 0.126

No. Column name St Activity Lower bound Upper bound Marginal------ ------------ -- ------------- ------------- ------------- -------------1 x[Bogota,Rio]

B 50 02 x[Bogota,B-Aires]

B 300 03 x[Bogota,Santiago]

NL 0 0 0.0364 x[Caracas,Rio]

B 275 05 x[Caracas,B-Aires]

NL 0 0 0.0096 x[Caracas,Santiago]

B 275 0

Karush-Kuhn-Tucker optimality conditions:

16

Page 17: Cómo Resolver Problemas de Programación Lineal Usando Linux

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

High quality

KKT.PB: max.abs.err = 0.00e+00 on row 0max.rel.err = 0.00e+00 on row 0

High quality

KKT.DE: max.abs.err = 2.78e-17 on column 1max.rel.err = 1.91e-17 on column 1

High quality

KKT.DB: max.abs.err = 0.00e+00 on row 0max.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 *\

Minimizecosto_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 Tosuministro(Bogota): + x(Bogota,Rio) + x(Bogota,B~Aires)+ x(Bogota,Santiago) <= 350suministro(Caracas): + x(Caracas,Rio) + x(Caracas,B~Aires)+ x(Caracas,Santiago) <= 600demanda(Rio): + x(Bogota,Rio) + x(Caracas,Rio) >= 325demanda(B~Aires): + x(Bogota,B~Aires) + x(Caracas,B~Aires) >= 300

demanda(Santiago): + x(Bogota,Santiago) + x(Caracas,Santiago) >= 275

End

17