赞
踩
gurobi 对 python 支持的不错,我已经编写了几个规划求解的例子。每次重新编程时,之前例子里的一些知识点又忘记了,觉得很有必要总结一下。
例如,下面的 python 代码调用 gurobi 求解一个简单的混合整数规划问题:
max
x
+
y
+
2
z
s
.
t
.
x
+
2
y
+
3
z
≤
4
x
+
y
≥
1
x
,
y
,
z
∈
{
0
,
1
}
# This example formulates and solves the following simple MIP model:
# maximize
# x + y + 2 z
# subject to
# x + 2 y + 3 z <= 4
# x + y >= 1
# x, y, z binary
from gurobipy import *
try:
# Create a new model
m = Model("mip1")
# Create variables
x = m.addVar(vtype=GRB.BINARY, name="x") # default bounds for continuous type is [0, infinite]
y = m.addVar(vtype=GRB.BINARY, name="y")
z = m.addVar(vtype=GRB.BINARY, name="z")
# 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('%s %g' % (v.varName, v.x))
print('Obj: %g' % m.objVal)
except GurobiError as e:
print('Error code ' + str(e.errno) + ": " + str(e))
except AttributeError:
print('Encountered an attribute error')
几点总结:
gurobi 的申请方式参看:http://www.gurobi.cn/NewsView1.Asp?id=4
model = read('test.mps')
X = [m.addVar(vtype = GRB.CONTINUOUS) for t in range(3)]
X = m.addVars(3, vtype = GRB.CONTINUOUS)
上面两个命令是等价的
final_cash = LinExpr(X[0]+X[1]) # 直接 X[0]+X[1] 也可以
# Set objective
m.setObjective(final_cash, GRB.MAXIMIZE)
若目标函数的表达式比较简单,也可以直接放到 setObjective 里。
m.update()
I = [LinExpr() for i in range(3)]
setObjective() 中的表达式 LinExpr 一定要在出现 setObjective() 之前定义好,若之后变动,可能会计算出错
目标函数中不能有包含求解变量的 min 或 max 表达式(此时可以让 min 或 max 表达式等于一个辅助变量,添加到约束条件中)
变量 var 或者线性表达式 LinExpr 可以用 python 的 sum()相加
m.addConstr(x + y <=10)
# x5 = max(x1, x3, x4, 2.0)
m.addGenConstrMax(x5, [x1, x3, x4], 2.0, "maxconstr")
# alternative form
m.addGenConstrMax(x5, [x1, x3, x4, 2.0], name="maxconstr")
# overloaded forms
m.addConstr(x5 == max_([x1, x3, x4, 2.0]), name="maxconstr")
m.addConstr(x5 == max_(x1, x3, x4, 2.0), name="maxconstr")
不过我发现,当遇到数组变量时, max_ 或 min_ 可能会出错,所以一般还是用 addGenConstrMax()、addGenConstrMin() 来处理 min 或 max 表达式
m.addConstr(A@x >= b)
m.addConstr(c@A@x + c@b >= d)
c=m.getConstrs()[0] #将第一个约束条件取出并传递给变量 c
c.RHS = 10 # 更新这个约束条件的常数项
model.remove(models.getConstrs()[0])
model.remove(model.getConstrs()[1:3]) # 移除第 2 与第 3 个约束条件
当删除一个约束条件,又增加一个新的约束条件时,这个新的约束条件的索引自动排到后面
用 getA() 得到线性约束条件的系数矩阵
A = model.getA()
m.Params.timeLimit = 100.0 # 等价于 m.setParam('timeLimit', 100)
m.Params.InfUnbdInfo = 1 # Determines whether simplex (and crossover) will compute additional information when a model is determined to be infeasible or unbounded
m.Params.LogToConsole = 0
m.params.Method = 1 # 使用对偶单纯形法
m.params.Method = 0 # 使用原始单纯形法(迭代慢,但占内存小)
m.params.Method = 2 # 使用内点法(gurobi称作barrier法)
对于 gurobi 的一个线性规划模型 m
m.getAttr(GRB.Attr.Pi)
m.getAttr(GRB.Attr.RHS)
若约束条件有多个,上面的两个命令得出的都是列表值
gurobi 的 模型可以通过访问 Status 参数查看是否可行,无界,迭代超过限制的信息,官方的说明文档如下:
例如,下面通过访问模型模型不可行时,计算 IIS:
if m.Status == 3: # model is infeasible
print("Model is infeasible")
m.computeIIS()
m.write("model.ilp")
转载于个人公众号:Python 数据科学与数学建模
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。