Behavior of the lazy constraints added within a callback
回答済みHi all,
I want to learn more about the behavior of the lazy constraints added within a callback using model.cbLazy(). I know from experience that the behavior of lazy constraints added into the model using model.addConstr() and then marked as lazy is completely different from those added in a callback. For example, the former appear in the model when model.write("model.lp") is called, while the latter don't.
I went through the user manual to look for information, but aside from instructions on how to add them, there is no further information about what the solver does with them, nor ways of interacting with them in a similar way as one can with constraints added with model.addConstr().
Specifically, I want to know whether such constraints can be accessed, removed, or updated after they are added to the model. I want to know if calling model.reset() has any effect on those. Also, I want to know if those (all or some) lazy constraints remain in the model every time model.optimize() is called.
To give some context, I would like to solve a complex model A that calls a model B in a callback to separate some lazy cuts for A. In turn, B calls a model C in a different callback to separate some lazy cuts for model B. While not precisely what my model does, assume that A needs separating subtour elimination constraints, and B, which is the model used in the callback, also needs some other subtour elimination constraints to be separated by C in a separate callback. In a way, B's callback is nested within A's callback.
One issue I have is that the solution a=A.cbGetSolution used to parameterize B may require updating (or at least removing) some of the lazy constraints of B generated in previous calls of B.optimize(). I would like to accomplish this without having to reconstruct B from scratch (call B=Model() and add the variables and constraints again). To be honest, I am not even sure those lazy constraints persist in B after B.optimize()finishes, as there is no way to know that. My guess is that some of those lazy cuts remain in B, since I am encountering unexpected behavior in the solutions produced by B.
I tried using B.reset() and a few other tricks to accomplish this, but none of my attempts seem to work. At the very least, I would like to be able to remove all of the lazy cuts added into the model.
I hope the explanation makes sense. Any help would be appreciated.
--JL
-
Hi Jose,
You can read more about two different approaches to implement lazy constraints in the article “How do I implement lazy Constraints in Gurobi?”. As soon as an already feasible solution is violated by a lazy constraint, the solution is discarded, and the lazy constraint is added to the LP relaxation.
Gurobi does not allow you to access the lazy constraints that were added to the model via a callback. If you are using a callback function to generate lazy constraints, you can track and store them as you generate them. However, you cannot remove them from the model afterward. Therefore, if a later step in your procedure requires starting from a model without lazy constraints, you must either reload the original model from a file or keep a copy (using copy(targetenv=None)) of the original model before adding lazy constraints.I saw your response to a similar post, and I understand that reading from a file or keeping a copy is not ideal. However, there is currently no way to remove/update lazy constraints already added to the model via a callback function. You can store them as explained above, but not access and change them via the model object.
Best regards,
Maliheh
0 -
Thank you, Maliheh. Could you please confirm whether the pool of lazy cuts added during the callback is reset every time
model.optimize()is called. I would like to know whether these constraints persist in the lazy pool each time the model is re-optimized.Best,
--Jose
0 -
If the
modelobject remains the same and is not disposed of, yes the lazy constraints persist if you recallmodel.optimize(cb). As an example, if you initially callmodel.optimize(cb)withTimeLimit=20. After the time limit is reached and the problem is not solved to optimality, you can change theTimeLimitparameter and callmodel.optimize(cb)again. You should then see the messageContinuing optimization…in the log.Best regards,
Maliheh
0 -
Hi Maliheh,
I am sorry, I need one more clarification. What do you mean by “If the
modelobject remains the same”? Is there anything that one can do to the model to make the lazy constraints not persist?--Jose
0 -
Sorry for the confusion. I was not sure why you needed to call the
optimize()method again, and was just trying to make sure you meant calling it on the same model object again.0 -
That is what I meant. But, based on your last comment, does it mean that if the object model changes, say by adding a new constraint, or something like that, does the pool get reset? What needs to change in the model for such a reset to occur?
0 -
Hi Maliheh,
Pardon the insistence on this matter. After some experimentation, it seems that calling
model.update()resets the lazy pool. I am not 100% sure if this is true, though. Could you please confirm this?-Jose
0 -
Hi Jose,
Yes, you are right. If you modify the model, for example, by adding a new constraint or variable, or by changing coefficients, the lazy constraints generated in the callback are discarded as they live in the internal solving data structures. So calling
model.reset()or modifying the model should remove the lazy constraints.Best regards,
Maliheh
0
サインインしてコメントを残してください。
コメント
8件のコメント