0

I built an initial model and then try to use the result of that model in a second model while the second model has many similarities with the initial model, it does have some more constraint. My approach was to copy the initial model to the second model as below(mdl is the initial model which I didn't bring here and mdll is the secondary model):

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

As you can see I copy the initial model as well as the constraints and the variables. To delete a constraint which was present in the initial model but I didn't want it in the second one, I implemented the following:

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

Finally, I tried to add new constraints to the second model as below:

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) 

but I receive the following error. Can anyone please help me with this:

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
dhasson
  • 248
  • 3
  • 10
  • 1
    From the description, this question looks like a duplicate of https://stackoverflow.com/q/37263701/4540852 (or related to it). You could try with the accepted answer there and let us know. – dhasson Jan 20 '20 at 23:03

1 Answers1

0

The Variable not in model is encountered because the method Model.copy() in Gurobi is performing a deep copy (https://www.geeksforgeeks.org/copy-python-deep-copy-shallow-copy/) of the initial model. Thus, while after the call to Model.copy() both models include variables with the same names, they are stored in completely separate memory locations.

Comparison between shallow and deep copy

Shallow Copy

enter image description here

Deep Copy

enter image description here

Gurobi Example

Let's consider the following example script that creates a model (m) and afterwards copies it (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

Using the Python is operator, which evaluates to True if the variables on either side of the operator point to the same object and False otherwise, we can easily confirm that the variable x in the second model is different from the variable x defined in our code (and implicitly from the variable x in the initial model), as it can be seen in the last two lines of the example script.

This behavior has most likely been chosen by the Gurobi developers in order to prevent unpredictable changes that might have occurred if the two models have shared the same variables (ex: changing the variable x in one model, would have altered it also for the other model).

Possible solutions

As also suggested in Why do I get "GurobiError: Variable not in model" after using Model.copy()?, the variables in the model copy can be mapped to variables in your code by accessing them using their names, with the help of the method getVarByName().

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