Why do you think it is not correct? Also, it seems like this should best we handled by a new question.
Original Message:
Sent: Mon June 22, 2020 01:34 PM
From: Fernando Dias
Subject: Cut Activation using Callbacks
If this is the case, I think it will work then
Another issue that I'm facing is that the callbacks are adding many cuts early in the B&C? I don't think this is necessarily correct.
Any ideas?
Thank you very much for your help
#######################################################################
class MyCutCallback(IncumbentCallback, LazyConstraintCallback):
def __init__(self, env):
LazyConstraintCallback.__init__(self, env)
IncumbentCallback.__init__(self)
self.eps = 1e-6
self.nb_cuts = 0
def add_cut_constraint(self, ct):
self.register_constraint(ct)
def __call__(self):
sol = self.make_solution()
unsats = self.get_cpx_unsatisfied_cts(self.cts, sol, self.eps)
for ct, cut, sense, rhs in unsats:
self.add(cut, sense, rhs)
self.nb_cuts += 1
print('-- add new cut[{0}]: [{1!s}]'.format(self.nb_cuts, ct))
##########################################################################
------------------------------
Fernando Dias
------------------------------
Original Message:
Sent: Mon June 22, 2020 12:19 AM
From: Daniel Junglas
Subject: Cut Activation using Callbacks
What is the problem? As you can read in the documentation here, the lazy constraint callack is only invoked when CPLEX finds an integer solution. That is the hole point of lazy constraints: they are only checked on solutions that are otherwise integer feasible. They give you an additional chance to reject those solutions.
------------------------------
Daniel Junglas
Original Message:
Sent: Sat June 20, 2020 10:51 AM
From: Fernando Dias
Subject: Cut Activation using Callbacks
I got this current class for callbacks using lazy constraints:
#######################################################################
class MyCutCallback(IncumbentCallback, LazyConstraintCallback):
def __init__(self, env):
LazyConstraintCallback.__init__(self, env)
IncumbentCallback.__init__(self)
self.eps = 1e-6
self.nb_cuts = 0
def add_cut_constraint(self, ct):
self.register_constraint(ct)
def __call__(self):
sol = self.make_solution()
unsats = self.get_cpx_unsatisfied_cts(self.cts, sol, self.eps)
for ct, cut, sense, rhs in unsats:
self.add(cut, sense, rhs)
self.nb_cuts += 1
print('-- add new cut[{0}]: [{1!s}]'.format(self.nb_cuts, ct))
##########################################################################
But I need to make this only add cuts after finding an integer solution. How can I make this happen?
I found some material about incumbent callbacks, but how do I get there?
Thank you very much
------------------------------
Fernando Dias
Original Message:
Sent: Fri June 19, 2020 03:35 PM
From: Fernando Dias
Subject: Cut Activation using Callbacks
Thank you very much for your answer.
One more question: The current version check for cut violation at every LP solution, I want to change that so it can check violation and eventually add the cuts only after it finds an integer solution. Any suggestions on how to do that?
Thank you again;
------------------------------
Fernando Dias
Original Message:
Sent: Thu June 18, 2020 08:39 AM
From: Daniel Junglas
Subject: Cut Activation using Callbacks
In order to separate lazy constraints derive from the LazyConstraintCallback class instead of the UserCutClass.
------------------------------
Daniel Junglas
Original Message:
Sent: Thu June 18, 2020 07:02 AM
From: Fernando Dias
Subject: Cut Activation using Callbacks
Hey
I made some adjustments and now the code at least run but the cuts don't work properly. Probably because they're set up as usercuts, but what I need to do is use them as lazy constraints.
Any idea how to change that?
------------------------------
Fernando Dias
Original Message:
Sent: Wed June 17, 2020 06:55 AM
From: Fernando Dias
Subject: Cut Activation using Callbacks
Also, how do I defined those cuts to be lazy constraints instead of user cuts?
------------------------------
Fernando Dias
Original Message:
Sent: Wed June 17, 2020 02:50 AM
From: Fernando Dias
Subject: Cut Activation using Callbacks
Thank you
I removed most of the things I could. It should be easier to run now.
------------------------------
Fernando Dias
Original Message:
Sent: Wed June 17, 2020 02:09 AM
From: Daniel Junglas
Subject: Cut Activation using Callbacks
Can you provide a minimally working code that reproduces the issue? In order to run your code a number of other libraries (like Pyomo) are required.
------------------------------
Daniel Junglas
Original Message:
Sent: Wed June 17, 2020 01:38 AM
From: Fernando Dias
Subject: Cut Activation using Callbacks
I attached the code here, maybe there's another issue.
If anyone could help, it would be very much appreciated.
------------------------------
Fernando Dias
Original Message:
Sent: Wed June 17, 2020 01:13 AM
From: Daniel Junglas
Subject: Cut Activation using Callbacks
This problem is described in the user manual in CPLEX > User's Manual for CPLEX > Advanced programming techniques > User-cut and lazy-constraint pools > Limitations on user-cut pools. In order to avoid this error you have to disable non-linear reductions by setting the linear reduction switch to 0.
------------------------------
Daniel Junglas
Original Message:
Sent: Tue June 16, 2020 02:16 PM
From: Fernando Dias
Subject: Cut Activation using Callbacks
So, if I understood correct, CPLEX check if the current solution is violating the cuts that I've had pre-defined.
And then using the function self.add() add them into the model. However, I got this mistake here:
status CPLEX Error 1121: Can't crush solution form.
Any ideas?
------------------------------
Fernando Dias
Original Message:
Sent: Mon June 08, 2020 08:00 AM
From: Daniel Junglas
Subject: Cut Activation using Callbacks
Ok. If I understood correctly, the function will test the current solution is violating the cuts that I've had set up before, correct?
Correct.
Sorry for asking, but what do you mean by "roll your own"?
I mean you have to implement your own function that finds the cuts that should be added and transforms them from object expressions to index expressions.
------------------------------
Daniel Junglas
Original Message:
Sent: Mon June 08, 2020 07:57 AM
From: Fernando Dias
Subject: Cut Activation using Callbacks
Ok. If I understood correctly, the function will test the current solution is violating the cuts that I've had set up before, correct?
Sorry for asking, but what do you mean by "roll your own"?
Thanks
------------------------------
Fernando Dias
Original Message:
Sent: Mon June 08, 2020 02:04 AM
From: Daniel Junglas
Subject: Cut Activation using Callbacks
The function takes a list of cuts (self.cts) and for each of them returns whether it is violated by at least self.eps. It returns the list of violated cuts. Moreover, it translates the cuts (which are specified using docplex variable objects) into something that can be used to the engine's self.add() function (where variables are specified by index).
If you want to have a different criterion to check whether to add a cut or not then you have to roll your own. In order to get the index of a variable you can use its 'index' property.
------------------------------
Daniel Junglas