I am using docplex (CPLEX Python API) to solve a mixed integer programming model.
Let us say that I have a minimization problem, and I have a lower bound for the objective function of that problem. I could simply add a constraint stating that the objective function needs to be bigger than that lower bound. However, someone raised the point that doing this may blind some search bounds in the solver, suggesting that I should create a callback that when it is called, compares the solution with that lower bound, stopping the search if the solution is equal to the lower bound.
After doing some research, I tried to use a ProgressListener, somehow similar to what is described here (https://dataplatform.cloud.ibm.com/exchange/public/entry/view/6e2bffa5869dacbae6500c7037ecd36f) but simpler. I'm leaving it below (I deleted the variables, objective function, and constraints, since they are not of interest here).
'''DECLARE MODEL'''
from docplex.mp.model import Model
mdl = Model()
#Declare variables, objective function, and constraints
from docplex.mp.progress import ProgressListener
from docplex.mp.progress import ProgressClock
lbound = 10
class pl(ProgressListener):
def __init__(self):
ProgressListener.__init__(self, ProgressClock.Gap)
def notify_progress(self, pdata):
if pdata.has_incumbent:
self.incumbent_value = pdata.current_objective
if self.incumbent_value == lbound:
self.abort()
mdl.add_progress_listener(pl())
sol = mdl.solve()
Based on this, I have two main questions:
Is there a more efficient way to do this?
When I add the ProgressListener, the solver has a different behavior. What I mean by this is that when I solve the model, I get a solution with the same solution value, regardless if I am using the ProgressListener or not. However, the value of the variables can be quite different. I understand this only happens in cases in which there are symmetrical solutions, otherwise the exact same solution would always be obtained. Nevertheless, is this normal to happen? Also, it is important to note that this happens regardless of what is done inside the ProgressListener. For instance, I have tried to run my model without any constraint that specifies a lower bound, and I obtain a certain solution. When I add a ProgressListener, even if that ProgressListener only prints some information, the solution is different (not in terms of solution value but in terms of the value of the variables)
You can use progress listener https://github.com/AlexFleischerParis/zoodocplex/blob/master/zooprogresslistener.py
but you can also get all solutions one by one https://github.com/AlexFleischerParis/zoodocplex/blob/master/zoogetsolutiononebyone.py