Добавление нового ограничения к модели в Python / Gurobi - PullRequest
0 голосов
/ 18 января 2020

Я построил исходную модель, а затем попытался использовать результат этой модели во второй модели, в то время как вторая модель имеет много сходств с исходной моделью, но имеет некоторые дополнительные ограничения. Мой подход состоял в том, чтобы скопировать исходную модель во вторую модель, как показано ниже (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

1 Ответ

0 голосов
/ 22 января 2020

Variable not in model встречается, потому что метод Model.copy() в Gurobi выполняет глубокое копирование (https://www.geeksforgeeks.org/copy-python-deep-copy-shallow-copy/) исходной модели. Таким образом, хотя после вызова Model.copy() обе модели содержат переменные с одинаковыми именами, они хранятся в совершенно разных местах памяти.

Сравнение между мелкой и глубокой копией

Мелкая копия

enter image description here

Глубокая копия

enter image description here

Пример Gurobi

Рассмотрим следующий пример сценария, который создает модель (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 в одной модели изменил его и для другой модели).

Возможные решения

Как также предложено в Почему я получаю «GurobiError: Variable not in model» после использования Model.copy () ? , переменные в копии модели могут быть сопоставлены с переменными в вашем коде путем доступа к ним по их именам с помощью метода getVarByName().

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