【问题标题】:Adding new constraint to a model in Python/Gurobi在 Python/Gurobi 中向模型添加新约束
【发布时间】:2020-05-05 01:21:55
【问题描述】:

我建立了一个初始模型,然后尝试在第二个模型中使用该模型的结果,而第二个模型与初始模型有很多相似之处,它确实有更多的约束。我的方法是将初始模型复制到第二个模型如下(mdl 是我没有带到这里的初始模型,mdll 是辅助模型):

mdll=Model('Boarding_test2')
Best_X_values= mdl.getAttr('x', X)
mdll.update()
mdll=mdl.copy()
mdll.getVars() 
mdll.getConstrs()

如您所见,我复制了初始模型以及约束和变量。 要删除初始模型中存在但我不希望在第二个模型中出现的约束,我实现了以下内容:

Del_cons=mdll.getConstrByName('Stefen')
Del_cons.__dict__
mdll.remove(Del_cons)
mdll.update()

最后,我尝试为第二个模型添加新的约束,如下所示:

mdll.addConstrs((Y[k,p])==1 for k in K for p in P if k==p and p!=p_sim)   
mdll.addConstrs(quicksum(Y[k,p] for k in K if k==k_sim )==1  for p in P if p==p_sim)  
mdll.addConstrs(quicksum(Y[k,p] for p in P if p==p_sim)==1  for k in K if k==k_sim) 

但我收到以下错误。谁能帮我解决这个问题:

GurobiError                               Traceback (most recent call last)

  1 #mdll.remove(mdll.getConstrByName('Stefen'))
----> 2 mdll.addConstrs((Y[k,p])==1 for k in K for p in P if k==p and p!=p_sim)
  3 mdll.update()
  4 mdll.addConstrs(quicksum(Y[k,p] for k in K if k==k_sim )==1  for p in P if p==p_sim)
  5 mdll.update()

model.pxi in gurobipy.Model.addConstrs()

model.pxi in gurobipy.Model.addConstr()

model.pxi in gurobipy.Model.__addConstr()

GurobiError: Variable not in model

【问题讨论】:

标签: python gurobi


【解决方案1】:

遇到 Variable not in model 是因为 Gurobi 中的方法 Model.copy() 正在执行初始模型的深度复制 (https://www.geeksforgeeks.org/copy-python-deep-copy-shallow-copy/)。因此,虽然在调用Model.copy() 之后,两个模型都包含具有相同名称的变量,但它们存储在完全独立的内存位置。

浅拷贝和深拷贝的比较

浅拷贝

深拷贝

古罗比示例

让我们考虑以下示例脚本,该脚本创建一个模型 (m),然后复制它 (m2):

from gurobipy import *

# Create a new model
m = gp.Model("mip1")

# Create variables
x = m.addVar(vtype=GRB.BINARY, name="x")
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 constraints:
m.addConstr(x + 2 * y + 3 * z <= 4, "c0")
m.addConstr(x + y >= 1, "c1")

# Optimize model
m.optimize()

# Copy the model
m2 = m.copy()

#Check if variable "x" from the initial model is different from variable "x" in the copied model
print(x is m2.getVarByName("x")) #will print False => variable "x" from our code is different than the variable "x" in the copied model
print(m.getVarByName("x") is m2.getVarByName("x")) # will print False => variable "x" in the initial model is different than the variable "x" in the copied model

使用 Python 的 is 运算符,如果运算符两侧的变量指向同一个对象,则计算结果为 True,否则计算为 False,我们可以很容易地确认变量 x 在第二个模型不同于我们代码中定义的变量x(隐含地不同于初始模型中的变量x),从示例脚本的最后两行可以看出。

Gurobi 开发人员很可能选择了这种行为,以防止在两个模型共享相同变量时可能发生的不可预测的变化(例如:在一个模型中更改变量 x,会改变它也适用于其他型号)。

可能的解决方案

正如Why do I get "GurobiError: Variable not in model" after using Model.copy()? 中所建议的那样,模型副本中的变量可以通过使用它们的名称访问代码中的变量来映射到代码中的变量,方法是getVarByName()

xInModelCopy = m2.getVarByName("x") # declare a variable for "x" in the copied model

【讨论】:

    猜你喜欢
    • 2015-12-08
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2022-06-15
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多