我目前正在研究一种MILP配方,我想通过分支切割法使用Gurobi来解决。我的模型是经典的带时间窗的取件和传递问题(PDPTW)的变体,为此定义了几类有效不等式。分支定界求解器运行时,如果满足当前节点中的某些条件,我想添加这些不等式(即我想添加割口)。我的问题如下:
我的变量被定义为字典,这使得在制定约束条件时易于使用它们,因为我可以轻松地使用它们的原始索引。下面提供了如何定义变量的示例]
tauOD = {}
# Start- End-Service time of trucks
for i in range(0,Nt):
tauOD[i,0]=model.addVar(lb=0.0, ub=truckODTime[i][0],
vtype=GRB.CONTINUOUS,name='tauOD[%s,%s]'%(i,0))
tauOD[i,1]=model.addVar(lb=0.0, ub=truckODTime[i][1],
vtype=GRB.CONTINUOUS,name='tauOD[%s,%s]'%(i,1))
一旦根据变量,约束和成本函数定义了模型,在经典的分支定界问题中,我只需使用model.optimize()即可开始该过程。在这种情况下,我使用命令model.optimize(my_callback),其中my_callback是我定义的添加剪切的回调函数。我的问题是,由于某些原因,回调函数不喜欢定义为字典的模型变量。我发现的唯一解决方法如下:
model._vars = model.getVars() #---> added this call right before the optimization starts
model.optimize(mycallback)
然后在回调中,我现在可以使用变量的顺序而不是索引来检索变量:
def mycallback(model,where):
if where == GRB.Callback.MIPNODE:
status = model.cbGet(GRB.Callback.MIPNODE_STATUS)
# If current node was solved to optimality, add cuts to strenghten
# linear relaxation
if status == GRB.OPTIMAL:
this_Sol = model.cbGetNodeRel(model._vars) # Get variables of current solution
# Adding a cut
model.cbCut(lhs=this_Sol[123]+this_Sol[125],sense=GRB.LESS_EQUAL,rhs=1) #---> Dummy cut just
# for illustration
# purposes
上述切割只是一个虚拟的例子,显示我可以使用在解决方案中排序的顺序变量而不是它们的索引来添加切割。例如,我希望能够在回调中写一个约束为[]
x [0,3,0] + x [0,5,0] <= 1
但是我唯一能做的就是写
this_Sol [123] + this_Sol [125] <= 1(假设x [0,3,0]是我的解矢量的第124个变量,而x [0,5,0]是我的解矢量的第126个) 。尽管知道变量的顺序是可行的,但是由于它取决于我在建立模型时如何创建变量,所以这比我在定义变量时要使用索引要困难得多(而且容易出错)我模型的原始约束(请参见下面的示例):
################### ### CONSTRAINTS ### ################### # For each truck, one active connection from origin depot for i in range(0,Nt): thisLHS = LinExpr() for j in range(0,sigma): thisLHS += x[0,j+1,i] thisLHS += x[0,2*sigma+1,i] model.addConstr(lhs=thisLHS, sense=GRB.EQUAL, rhs=1, name='C1_'+str(i))
你们有没有遇到过类似的问题?我的一个朋友告诉我,由于某些原因,Gurobi不喜欢在回调函数中定义为字典的变量,但是我不知道该如何规避。任何帮助将不胜感激。谢谢!
亚历山德罗
我目前正在研究一种MILP配方,我想通过分支切割法使用Gurobi来解决。我的模型是经典的带时间窗(PDPTW)的取件和发货问题的变形...
您应按变量的副本进行复制。
感谢@seimetz的回答,但我不确定我是否理解该过程。为什么我需要在循环中使用model._I等而不是简单的索引(例如,对于范围(0,5)中的i)?让我更加清楚。我想在一个PDPTW的变体问题中添加有效的不等式。这样的不等式之一集中在一对传递节点i + n,j + n上。让我们还假设涉及N_t辆卡车。在分支定界树的每个节点中,我要检查以下数量