Hola, en Python hay diversidad de librerías para hacer programación lineal tanto la normal como la entera. En esta ocasión os voy ha hablar de PyMathPrpog, unas librerías basadas en Glpk y PyGlpk con las cuales podemos calcular nuestros problemas en métodos como el Simplex, Exacto e Interior; o Plain y Avanzado si lo que buscamos son soluciones enteras. También podemos obtener un informe detallado de nuestra solución, las primales, las primales factibles, las duales, etc. y todo ello de forma sencilla. Esta librería no se encuentra (que yo sepa) en los repositorios oficiales de Ubuntu, pero bueno si añades mi repositorio de Launchpad la puedes instalar bajo el nombre de python-mathprog. Supongamos que queremos solucionar el siguiente problema:


El código en Python usando estas librerías es el siguiente:
from pymprog import * # Importar el modulo
# indices y datos
xid, rid = range(3), range(3)
c = (10.0, 6.0, 4.0)
mat = [ (1.0, 1.0, 1.0),
(10.0, 4.0, 5.0),
(2.0, 2.0, 6.0)]
b = (100.0, 600.0, 300.0)
#definicion del problema
beginModel('basic') #Lo definimos como basico
verbose(True)
x = var(xid, 'X') #crear variables
maximize( #funcion objetivo
sum(c[i]*x[i] for i in xid), 'miobjetivo'
)
r=st( #Conjunto de restricciones
sum(x[j]*mat[i][j] for j in xid) <= b[i] for i in rid
)
solve() #Solucion e Informe
print "Estado Solucionador:", status()
print 'Z = %g;' % vobj() # Valor funcion Objetivo
#Impresion de nombre de las variables y las primales
print ';\n'.join('%s = %g {dual: %g}' % (
x[i].name, x[i].primal, x[i].dual)
for i in xid)
print ';\n'.join('%s = %g {dual: %g}' % (
r[i].name, r[i].primal, r[i].dual)
for i in rid)
print reportKKT()
print "Environment:", env
for pn in dir(env):
if pn[:2]=='__'==pn[-2:]: continue
print pn, getattr(env, pn)
print ' '
print evaluate(sum(x[i]*(i+x[i])**2 for i in xid))
print sum(x[i].primal*(i+x[i].primal)**2 for i in xid)
endModel() #Finalizar el Modelo
Y la solución por terminal es:
MAX 'miobjetivo': 10 X[0]+ 6 X[1]+ 4 X[2]
s.t. R0[0]: X[0]+ X[1]+ X[2] <= 100.0
s.t. R0[1]: 10 X[0]+ 4 X[1]+ 5 X[2] <= 600.0
s.t. R0[2]: 2 X[0]+ 2 X[1]+ 6 X[2] <= 300.0
Estado Solucionador: opt
Z = 733.333;
X[0] = 33.3333 {dual: 0};
X[1] = 66.6667 {dual: 0};
X[2] = 0 {dual: -2.66667}
R0[0] = 100 {dual: 3.33333};
R0[1] = 600 {dual: 0.666667};
R0[2] = 200 {dual: 0}
Karush-Kuhn-Tucker optimality conditions:
=========================================
1) Error in Primal Solutions:
-----------------------------
Largest absolute error: 0.000000 (row id: 1)
Largest relative error: 0.000000 (row id: 1)
Quality of primal solution: H
2) Error in Satisfying Primal Bounds:
-------------------------------------
Largest absolute error: 0.000000 (var id: 0)
Largest relative error: 0.000000 (var id: 0)
Quality of primal feasibility: H
3) Error in Dual Solutions:
-----------------------------
Largest absolute error: 0.000000 (col id: 0)
Largest relative error: 0.000000 (col id: 0)
Quality of dual solution: H
4) Error in Satisfying Dual Bounds:
-------------------------------------
Largest absolute error: 0.000000 (var id: 0)
Largest relative error: 0.000000 (var id: 0)
Quality of dual feasibility: H
Environment:
blocks 45
blocks_peak 72
bytes 27508
bytes_peak 28998
mem_limit None
term_hook None
term_on True
version (4, 38)
342288.888889
342288.888889
Como vemos en la salida por terminal obtenemos un informe muy detallado de la solución y sus posibles soluciones.
Obviamente al ser este ejemplo de 3 variables no es factible dibujar su región, al igual que no lo son la mayoría de estos problemas. Tan sólo son posibles sus soluciones gráficas para problemas de 2 variables, que se dan mayoritariamente en Bachiller. A mi estas librerías me parecen una buena alternativa al programa no libre LINGO. Me queda pendiente verlo con python-cvxopt, pero eso os lo cuento otro día
Saludos
Comentarios