Copy constraints and variables from base model to extended model
AnsweredHi there,
I am formulating a base model and want to do seperate instances of extended models that take constraints and variables from the base model into the extended models.
Here the formulation of the base model:

and the formulation of one of the extended models (here MixedSequencing):


and calling the extended model with:

When I try to run the model, the following error pops up regarding line 68:

I assume, after considering the documentation, the pasting of constraints and variables from the base model does not work with the addConstr() function. If this is the case, is there another function or way to copy base constraints ct_1a, ct_1b and base variable x into the extended model, possibly easier than described here:
?
Kind regards, Tim
-
Hi Tim,
In the MixedSequencing function you are creating a model, then passing it to your BaseModel function, which adds variables and constraints to this model (not a copy), and then you are iterating through the constraints and adding them again, creating duplicates on the model. You are then doing something similar with variables.
There is no copying occurring here, and I'd recommend reading up on Passing by Reference in Python to understand what is going on when you pass objects to functions.
That aside, this misunderstanding is not what is the core of your problem. One issue is that the MixedSequencing code does not know what "x" is, since it was defined in a different place. You can see that your editor is highlighting this for you by underlining the "x" in the screenshots. There maybe more issues but it is hard to tell using screenshots.
If you would like to paste code here (not screenshots), then I can demonstrate how to fix this.
Cheers,
Riley0 -
Dear Riley,
thank you very much for your quick and detailled answer. I'll take a look into the "passing by reference in python" link you provided later today but thank you for that already in advance.
Since I could not upload the python (and a mathematical problem definition in a pdf file in case my code is totally messy) file, please find a .zip package under this link: https://drive.google.com/file/d/1bFoqyIREwHwenZAKUk351bYMKK8BDpJA/view?usp=sharing
Let me know, if this works!
Kind regards,
Tim0 -
Hi Tim,
Please see changes I've made below to the relevant sections of code. I've made comments where changes have been made. Let me know if you need any clarification?
def BaseModel(M, T, demand, model):
"""
M: constant, number of models
T: constant, number of production cycles
demand: list, demand for copies of model m.
model: object, gurobi optimization model
"""
# Define decision variables for the given model
x = model.addVars(M, T, vtype = gp.GRB.BINARY, name = "x")
# Add constraints (1a) and (1b)
ct_1a = model.addConstrs(gp.quicksum(x[m, t] for m in range(0, M)) == 1 for t in range(0, T))
ct_1b = model.addConstrs(gp.quicksum(x[m, t] for t in range(0, T)) == demand[m] for m in range(0, M))
# Write the optimization model in txt file
model.write('BaseModel.lp')
# fix: no need to return model, you have made changes to the original model being passed in
return x
def MixedSequencing(T, C, demand, processTimes, length):
# Create the optimization model
model = gp.Model("Mixed Sequencing")
# Set parameters
model.setParam('OutputFlag', True)
M, K = len(demand), len(processTimes[0]) # number of models, number of stations
# Define decision variables
# fix: missing vtype keyword parameter. Without it addVars assumes gp.GRB.CONTINUOUS is another index
# and hence w and s would have 3-element indices.
w = model.addVars(K, T, vtype=gp.GRB.CONTINUOUS, lb = 0, name = "work_overload")
s = model.addVars(K, T, vtype=gp.GRB.CONTINUOUS, lb = 0, name = "start_position_of_worker")
# fix: returning x and assigning so that we can use it in constraints.
# Another option is to set
# model._x = x
# in BaseModel function then in this function use
# x = model._x
# after calling BaseModel so that you have a reference to x.
x = BaseModel(M, T, demand, model)
# Add constraints (2c) - (2f)
# fix: cannot use processTimes[m, k] with nested lists. You could convert processTimes to numpy array and use this indexing though.
# fix: cannot have t+1 index and t in range(T)
ct_2c = model.addConstrs(s[k, t+1] >= s[k, t] + gp.quicksum(processTimes[m][k] * x[m, t] - w[k, t] - C
for m in range(M)) for k in range(K) for t in range(T-1))
ct_2d = model.addConstrs(length[k] >= s[k, t] + gp.quicksum(processTimes[m][k] * x[m, t] - w[k, t]
for m in range(M)) for k in range(K) for t in range(T))
# Set objective
obj = model.setObjective(gp.quicksum(w[k, t] for k in range(0, K) for t in range(0, T)), sense = gp.GRB.MINIMIZE)
# Optimize the model
model.optimize()
# Write the optimization model in txt file
model.write('MixedModel.lp')
Output(model)
Note that you may benefit a lot from prototyping your models interactively either with Jupyter notebooks, or equivalently pypercent format offered by editors such as VS Code.- Riley
0 -
Hi Riley,
Thanks you very much for the code suggestion and the hints to things that don't work! I'm still trying to fix those so just one quick direct follow-up question: with your suggestion I can easly take the x variables from the BaseModel into the extended MixedSequencing, that's already awesome! How can I access the 2 constraints ct_1a and ct_1b as well?
Kind regards, Tim
0 -
Hi Tim,
You can either usereturn x, ct_1a, ct_1band then
x, ct_1a, ct_1b = BaseModel(M, T, demand, model)
or you can use the other approach where you store them on the model object, i.e.
model._ct_1a = ct_1a
- Riley0
Please sign in to leave a comment.
Comments
5 comments