课程三:Callback使用方法
3.1 Callback使用方法
3.11 Callback函数
Callback为用户在求解模型时提供了高级控制功能,如在求解过程中获取信息,终止优化,加入额外约束条件和加入自己开发的算法\
定义callback: def name(model, where): 调用callback: m.optimize(callback函数名)
参数: where:回调函数触发点 what:获取何种信息,what能获取什么取决于where
3.12 cbGet(what):查询一些信息,如目标值,节点数
3.13 cbGetNodeRel(vars):查询变量在当前节点的松弛解
3.14 cbGetSolution(vars):查询可行解变量的取值(where == GRB.Callback.MIPSOL或者GRB.Callback.MULTIOBJ)
3.15 cbCut(lhs, sense, rhs)
lhs:左端项
sense符号
rhs:右端项
(where == GRB.Callback.MIPNODE参数PreCrush=1 (关掉Gurobi预处理对模型约束的转化)。)
3.16 cbLazy(lhs, sense, rhs)
与一般cut区别在于只有在被违反的时候才起作用 Where == GRB.Callback.MIPNODE or GRB.Callback.MIPSOL 使用时必须设定参数LazyConstraints = 1
3.17 cbSetSolution(vars, solution):向当前节点导入一个解
where == GRB.Callback.MIPNODE vars:变量 solution:变量的值
3.18 cbUseSolution():计算导入解的目标值
3.19 案例RINS heuristic
from gurobipy import *
import random
def RINScallback(model, where):
if where == GRB.Callback.MIPNODE:
if model.cbGet(GRB.Callback.MIPNODE_NODCNT) % 100 == 0 and \
model.cbGet(GRB.Callback.MIPNODE_STATUS) == GRB.OPTIMAL:
submodel = model.copy()
suby = submodel.getVars()
yrelaxation = model.cbGetNodeRel(model._y)
for i in range(model._N):
if abs(yrelaxation[i]) < 0.01:
suby[i].ub = 0
elif abs(yrelaxation[i] - 1) < 0.01:
suby[i].lb = 1
submodel.setParam(GRB.Param.TimeLimit, 30)
submodel.optimize()
if submodel.objval > model.cbGet(GRB.Callback.MIPNODE_OBJBST):
for i in range(model._N):
if abs(suby[i].x) < 0.001:
model.cbSetSolution(model._y[i], 0.0)
elif abs(suby[i].x-1)<0.001:
model.cbSetSolution(model._y[i], 1.0)
try:
random.seed(1)
N = 10
Cmatrix = {(i,j):random.randint(0,100) for i in range(N) for j in range(N)}
m = Model('MaximumCut')
y = m.addVars(N, vtype=GRB.BINARY, name='y')
obj = QuadExpr()
for i in range(N):
for j in range(N):
obj += Cmatrix[i,j] * (y[i] + y[j] - 2*y[i]*y[j])
m.setObjective(0.5 * obj, -1)
m.Params.TimeLimit = 600
m._y = y
m._N = N
m.optimize(RINScallback)
print('Obj= ', m.Objval)
for i in range(N):
print(y[i].VarName, ' = ', y[i].x)
except GurobiError:
print('Error reported')
3.2常用线性化方法
3.21 广义约束–Max/Min
z = max(x,y,3) —>
x<=z, y<=z, 3 <=z
x>=z-M(1-u1)
y>=z-M(1-u2)
3>=z-M(1-u3)
u1+u2+u3>=1
u1,u2,u3{0,1}
m.addConstr(z==max_(x, y, 3))
z = min(x,y,3) —>
x>=z, y>=z, 3>=z
x<=z+M(1-u1)
y<=z+M(1-u2)
3<=z+M(1-u3)
u1+u2+u3>=1
u1,u2,u3{0,1}
m.addConstr(z==min_(x, y, 3))
3.22 目标函数存在绝对值
3.23 Maxmin/Minmax
3.24 Maxmax/Minmin
3.25 带fixed cost目标函数
3.26 分式目标函数
3.27 逻辑或
3.28 乘积式