3
$\begingroup$

I am running a MIP using DOCPLEX that generates several feasible integer solutions during the Branch and Bound search.

The node log updates every now and then based on the parameter setting.

However, is there a way to report each solution with the elapsed time till that point(i.e. find out the elapsed time everytime a new better bound is found)? I want to generate a report/plot to track how the best integer solution changes over time.

$\endgroup$
4
$\begingroup$

In Making optimization simple (Python) I gave 2 options:

The models:

from docplex.mp.model import Model
from docplex.mp.progress import *

mdl = Model(name='buses')
nbbus40 = mdl.integer_var(name='nbBus40')
nbbus30 = mdl.integer_var(name='nbBus30')
mdl.add_constraint(nbbus40*40 + nbbus30*30 >= 300, 'kids')
mdl.minimize(nbbus40*500 + nbbus30*400)

class pl(ProgressListener):
  
    def __init__(self):
        ProgressListener.__init__(self, ProgressClock.Gap)
    
    def notify_progress(self, pdata):
        gap = pdata.mip_gap
        ms_time = 1000* pdata.time
        print('-- new gap: {0:.1%}, time: {1:.0f} ms'.format(gap, ms_time))
        

# connect a listener to the model
mdl.add_progress_listener(pl())

mdl.solve(log_output=False,)

mdl.export("c:\\temp\\buses.lp")

for v in mdl.iter_integer_vars():
    print(v," = ",v.solution_value)

and the second one:

from docplex.mp.model import Model
from docplex.mp.progress import *

mdl = Model(name='buses')
nbbus40 = mdl.integer_var(name='nbBus40')
nbbus30 = mdl.integer_var(name='nbBus30')
mdl.add_constraint(nbbus40*40 + nbbus30*30 >= 300, 'kids')
mdl.minimize(nbbus40*500 + nbbus30*400)

mdl.parameters.mip.limits.solutions=1

while (1==1):
    sol=mdl.solve(log_output=False)
    for v in mdl.iter_integer_vars():
       print(v," = ",v.solution_value)

    print("objective = ",sol.get_objective_value())
    print("best bound = ",mdl.solve_details.best_bound)
    print("mip gap = ",mdl.solve_details.mip_relative_gap)  
       
    print("status : ",mdl.solve_details.status)   
    if ("optimal solution" in str(mdl.solve_details.status)):
        break
$\endgroup$
3
$\begingroup$

One solution is to add an Incumbent callback (not sure whether DOCPLEX support this yet, but certainly Java/C++), and log the solution + time stamp within the the callback.

Another solution which, if my memory service me well, is the following:

  1. Set the MIP integer solution limit to 1 (IntSolLim parameter in Cplex <=12.6).
  2. Invoke solve(). Cplex will return as soon as it finds a solution
  3. Log the solution and its timestamp.
  4. Re-invoke solve(). Cplex will continue its search from the previous solution. Repeat until no more solutions can be found, in which case the Cplex status will be 'optimal'. Obviously you would program this in a simple loop.
$\endgroup$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.