1 标准文件格式
标准文件的优点是易于解析,缺点是表达复杂的模型很费力。一个比较好的方式是使用建模语言,然后导出标准文件格式,再调用solver求解。
1.1 LP
LP文件的格式非常易于理解,表示如下:
\* test1 *\
Minimize
obj: x + 4 y + 9 z
Subject To
c1: x + y <= 5
c2: x + z >= 10
c3: - y + z = 7
Bounds
x <= 4
-1 <= y <= 1
End
1.2 MPS
MPS是线性规划的标准输入文件。总结来说,MPS使用系数矩阵的方式来存储标准形中的A,并且是用列存储的方式。注意bounds的格式和其他不一样。
bounds还有
FX(fixed)
FR(free)
BV(binary variable)
UI(upper integer)
LI(lower integer)
SC(semi-continuous)
下面是一个例子:
*SENSE:Minimize
NAME test1
ROWS
N obj
L c1
G c2
E c3
COLUMNS
x c1 1.000000000000e+00
x c2 1.000000000000e+00
x obj 1.000000000000e+00
y c1 1.000000000000e+00
y c3 -1.000000000000e+00
y obj 4.000000000000e+00
z c2 1.000000000000e+00
z c3 1.000000000000e+00
z obj 9.000000000000e+00
RHS
RHS c1 5.000000000000e+00
RHS c2 1.000000000000e+01
RHS c3 7.000000000000e+00
BOUNDS
UP BND x 4.000000000000e+00
LO BND y -1.000000000000e+00
UP BND y 1.000000000000e+00
ENDATA
对应这个数学模型:
2. 高级建模语言
2.1 PuLP
下面是PuLP的例子:
# Import PuLP modeler functions
from pulp import *
# A new LP problem
prob = LpProblem("test1", LpMinimize)
# Variables
# 0 <= x <= 4
x = LpVariable("x", 0, 4)
# -1 <= y <= 1
y = LpVariable("y", -1, 1)
# 0 <= z
z = LpVariable("z", 0)
# Use None for +/- Infinity, i.e. z <= 0 -> LpVariable("z", None, 0)
# Objective
prob += x + 4*y + 9*z, "obj"
# (the name at the end is facultative)
# Constraints
prob += x+y <= 5, "c1"
prob += x+z >= 10, "c2"
prob += -y+z == 7, "c3"
# (the names at the end are facultative)
# Write the problem as an LP file
prob.writeLP("test1.lp")
# Solve the problem using the default solver
prob.solve()
# Use prob.solve(GLPK()) instead to choose GLPK as the solver
# Use GLPK(msg = 0) to suppress GLPK messages
# If GLPK is not in your path and you lack the pulpGLPK module,
# replace GLPK() with GLPK("/path/")
# Where /path/ is the path to glpsol (excluding glpsol itself).
# If you want to use CPLEX, use CPLEX() instead of GLPK().
# If you want to use XPRESS, use XPRESS() instead of GLPK().
# If you want to use COIN, use COIN() instead of GLPK(). In this last case,
# two paths may be provided (one to clp, one to cbc).
# Print the status of the solved LP
print("Status:", LpStatus[prob.status])
# Print the value of the variables at the optimum
for v in prob.variables():
print(v.name, "=", v.varValue)
# Print the value of the objective
print("objective=", value(prob.objective))
2.2 Pyomo
这里举Pyomo为例,
可以使用的求解器包括:
MIP:Gurobi,CPLEX,CBC,GLPK
NLP:IPOPT, KNITRO, AMPL、GAMS
MINLP:Baron, COUENNE
下面是例子
from pyomo.environ import *
A = ['hammer', 'wrench', 'screwdriver', 'towel']
b = {'hammer':8, 'wrench':3, 'screwdriver':6, 'towel':11}
w = {'hammer':5, 'wrench':7, 'screwdriver':4, 'towel':3}
W_max = 14
model = ConcreteModel()
model.x = Var( A, within=Binary )
model.value = Objective(
expr = sum( b[i]*model.x[i] for i in A),
sense = maximize )
model.weight = Constraint(
expr = sum( w[i]*model.x[i] for i in A) <= W_max )
opt = SolverFactory('glpk')
result_obj = opt.solve(model, tee=True)
model.pprint()
可以用下面的语句写成mps类型:
model.write('a.mps','mps')
Benchmark
这里是Benchmark。
miplib2010.zib.de/ [1]
plato.asu.edu/ftp/lptestset/ [2]
www.netlib.org/lp/data/ [3,7]
www.sztaki.hu/~meszaros/public_ftp/lptestset/
(MISC[4], PROBLEMATIC[5], STOCHLP[6], INFEAS[8])
下面是用于测试的数据描述:
Problem sizes
s problem rows columns nonzeros
================================================
2 L1_sixm250obs 986069 428032 4280320
2 Linf_520c 93326 69004 566193
2 brazil3 14647 23968 133184
1 buildingenergy 277594 154978 788969
2 chrom1024-7 67584 73728 270328
2 cont1 160793 40398 399991
2 cont11 160793 80396 439989
4 dbic1 43200 183235 1038761
1 ds-big 1042 173029 4573582
2 ex10 69609 17680 1179680
2 fome13 48569 97840 334984
2 irish-e 104260 61728 538809
2 neos 479120 36786 1084461
2 neos1 131582 1892 468094
2 neos2 132569 1560 552596
2 neos3 512209 6624 1542816
2 neos5052403 38269 32868 4898304
1 ns1644855 40698 40200 2120696
2 ns1687037 50622 43749 1406739
2 ns1688926 32768 16587 1712128
4 nug15 6331 22275 110700
2 nug08-3rd 19728 20448 139008
2 pds-40 66845 212859 605678
2 pds-100 156244 505360 1390539
2 psched3-3 266228 79555 1062480
3 qap15 6331 22275 110700
1 rail02 95791 270869 756228
2 rail4284 4284 1092610 12372358
2 s100 14734 364417 2127672
2 s250r10 10963 273142 1572104
2 savsched1 295990 328575 1846351
8 self 960 7364 1148845
1 shs1023 133944 444625 1044725
2 square41 40161 62234 13628623
4 stat96v1 5995 197472 588798
4 stat96v4 3173 62212 490472
2 stormG2_1000 528186 1259121 4228817
1 stp3d 159488 204880 662128
2 support10 165685 14770 551152
2 watson_2 352014 671861 1843716
================================================