下面隆重介绍一下gurobi以及在python环境中调用gurobi, 首先gurobi的求解能力宣称>=cplex,这个没有测试过,不辨真假,但是从我求解问题的测试结果看,它的求解能力是高于lpsolve的,而且还可以申请到一个免费使用一年的许可证(这点就优于cplex的90天的许可证,而且还有求解规模限制)。
它的官方网站是http://www.gurobi.com/,在这里可以下到最新版本以及申请许可证,安装很简单,windows下下载对应的版本双击即可安装,安装好后第一次运行时会提示要许可证,这时输入申请的许可证号,如果生成的.lic文件不放在默认的C://users//user_name目录下,则需要设置一下环境变量,gurobi激活程序会提示详细步骤,非常简单。
将其集成到Matlab安装环境中仅需在Matlab中运行其安装目录下的win64/matlab/gurobi_setup.m.
我的问题是通过在python环境中调用gurobi得到解决的,下面叙述一下在python环境中集成gurobi的步骤,首先要选对python版本,我的gurobi版本是5.6.3,则对应的python版本是2.7.8(任意一个python2.7版本均可),同时python和gurobi必须同时是32bit或64bit,如果一个是32bit,一个是64bit则安装一定会失败,这两点注意了,一般后面的步骤就不会失败了。然后运行gurobi安装目录下win64/bin/pysetup.bat,没有报错则表明安装成功。在python环境下运行win64/examples/python目录下的任何一个实例代码,如果跑出了结果则表明gurobi环境已经正确集成到python中了
顺便说一下gurobi安装目录下自带了一些资料非常好,首先是win64/docs下的quickstart.pdf,指导gurobi环境的安装使用及其与其它编程语言的集成方法和实例,refman.pdf介绍了它支持的语言调用它的API接口,而examples.pdf则是各个实例的代码,各个实例可直接运行代码存放于win64/examples目录下,例如解决网络流问题可以参考win64/examples/python目录下的netflow.py,我觉得用python调用gurobi一个很大的好处就是从程序员的角度来说变量可以用m.addVar()随意定义,约束也可以用m.addConstr()随意定义,不像用其他方式解LP问题最终都要程序员显式地把变量或约束条件定义成矩阵形式,在解决特定问题时这种要求往往使代码结构非常复杂且需要很多冗余的存储空间,另外python由于它的语言特点写代码也非常方便,我的问题尝试过用matlab需要几百行,还需要定义一些复杂的存储结构,但python建模过程(不包含打印求解结果)一百行都不到,而且python的字典结构,tuplelist结构等等对于表示网络拓扑图是非常方便的,因此python+gurobi则是我最终采用的方法。
结合Python使用gurobi
首先解压:tar -xvfz gurobifile.gz
大多数人都不是直接使用,如果集成在python中使用,需要执行一个脚本:以gurobi 6.5为例,进入gurobi650/linux64目录,
运行:python setup.py install
这样写python脚本时from gurobipy import *这一句就不会报某个库文件找不到的错误了
然后设置环境变量,最好是在/etc/profile文件中,这样不在终端中运行python脚本,而是通过eclipse IDE运行就不会出问题,具体设置方法可以参考gurobi自带的安装说明
设置完成要source /etc/profile才可以生效
最后安装license,在gurobi官网注册生成license后,进入gurobi650/linux64/bin目录,运行grbgetkey license ID(申请时自动生成)
注意:注册license过程必须联网
会提示输入license文件存放位置,按实际情况输入即可。
当安装问题解决后,doc文件下的官方文档对各种接口和整个软件的使用都有很全的案例,可以参考
比如:
from gurobipy import *
try:
# Create a new model
m = Model("mip1")
# Create variables
x = m.addVar(obj = 1,vtype=GRB.BINARY, name="x")
y = m.addVar(obj = 1,vtype=GRB.BINARY, name="y")
z = m.addVar(obj = 2,vtype=GRB.BINARY, name="z")
# Integrate new variables
m.update()
# Set objective
m.setObjective(x + y + 2 * z, GRB.MAXIMIZE)
# Add constraint: x + 2 y + 3 z <= 4
m.addConstr(x + 2 * y + 3 * z <= 4, "c0")
# Add constraint: x + y >= 1
m.addConstr(x + y >= 1, "c1")
m.optimize()
for v in m.getVars():
print (v.varName, v.x)
print ('Obj:', m.objVal)
except GurobiError:
print ('Error reported')
建模过程和一般的数学语言如出一辙,因此很容易懂,当然也有复杂的,比如这种:
from gurobipy import *
# Model data
commodities = ['Pencils', 'Pens']
nodes = ['Detroit', 'Denver', 'Boston', 'New York', 'Seattle']
arcs, capacity = multidict({\
('Detroit', 'Boston'): 100,\
('Detroit', 'New York'): 80,\
('Detroit', 'Seattle'): 120,\
('Denver', 'Boston'): 120,\
('Denver', 'New York'): 120,\
('Denver', 'Seattle'): 120 })
arcs = tuplelist(arcs)
cost = {\
('Pencils', 'Detroit', 'Boston'): 10,\
('Pencils', 'Detroit', 'New York'): 20,\
('Pencils', 'Detroit', 'Seattle'): 60,\
('Pencils', 'Denver', 'Boston'): 40,\
('Pencils', 'Denver', 'New York'): 40,\
('Pencils', 'Denver', 'Seattle'): 30,\
('Pens', 'Detroit', 'Boston'): 20,\
('Pens', 'Detroit', 'New York'): 20,\
('Pens', 'Detroit', 'Seattle'): 80,\
('Pens', 'Denver', 'Boston'): 60,\
('Pens', 'Denver', 'New York'): 70,\
('Pens', 'Denver', 'Seattle'): 30 }
inflow = {('Pencils', 'Detroit'): 50,\
('Pencils', 'Denver'): 60,\
('Pencils', 'Boston'): -50,\
('Pencils', 'New York'): -50,\
('Pencils', 'Seattle'): -10,\
('Pens', 'Detroit'): 60,\
('Pens', 'Denver'): 40,\
('Pens', 'Boston'): -40,\
('Pens', 'New York'): -30,\
('Pens', 'Seattle'): -30 }
# Create optimization model
m = Model('netflow')
# Create variables
flow = {}
for h in commodities:
for i,j in arcs:
flow[h,i,j] = m.addVar(ub=capacity[i,j], obj=cost[h,i,j],\
name = 'flow_%s_%s_%s'%(h,i,j))
m.update()
# Arc capacity constraints
for i,j in arcs:
m.addConstr(quicksum(flow[h,i,j] for h in commodities) <= capacity[i,j],\
'cap_%s_%s' % (i, j))
# Flow conservation constraints
for h in commodities:
for j in nodes:
m.addConstr(
quicksum(flow[h,i,j] for i,j in arcs.select('*',j)) +\
inflow[h,j] ==
quicksum(flow[h,j,k] for j,k in arcs.select(j,'*')),\
'node_%s_%s' % (h, j))
# Compute optimal solution
m.optimize()
# Print solution
if m.status == GRB.Status.OPTIMAL:
for h in commodities:
print ('\nOptimal flows for', h, ':')
for i,j in arcs:
if flow[h,i,j].x > 0:
print (i, '->', j, ':', flow[h,i,j].x)
建模了一张图……,所以和Python配合的几乎完美无缺。
感谢:http://blog.chinaunix.net/uid-13246637-id-4590486.html