callback of MIPSOL

471 views
Skip to first unread message

Orion T

unread,
Aug 10, 2018, 1:56:10 AM8/10/18
to Gurobi Optimization
Dear Gurobi team, 

I have a question regarding the MIPSOL callback codes. I am currently implementing a separation oracle for solving a combinatorial optimization (MIP) using gurobipy. My callback function (separation oracle) is called when a new incumbent solution is found (i.e. where == GRB.callback.MIPSOL).

First I want to confirm that `a new incumbent is found' means that the solver has found a better feasible solution. If this is the case, why Is the separation oracle being called several times when a new incumbent is found, instead of just once. Here I've attached an output display. The oracle outputs 'found a new incumbent...' each time it is called. There seems to be no improvement in the incumbent (stays at 1090 the whole time) but the callback function is called multiple times.

output.png

It seems unlikely to me that the solver has found multiple feasible solutions of the same value because I've experienced the same situation at different phase of solving process and from different datasets. So is it that the callback function will be called multiple times even when the incumbent is only updated once? I'd appreciate your explanation very much.


Thanks,

Ziye


Daniel Espinoza

unread,
Aug 13, 2018, 7:41:05 AM8/13/18
to Gurobi Optimization
Hi Ziye,

While Gurobi is multi-threaded, user callbacks are called in sequential mode, during synchronization of the different threads. So, it might well happen that the same feasible solution is found on different threads, and then (during synchronization) the callback are called to check on them. This is to keep the programming burden for users as low as possible.
Now, for single-threads, I would be surprised if the same happens.

Best,
Daniel

Orion T

unread,
Aug 13, 2018, 12:12:14 PM8/13/18
to gur...@googlegroups.com
Hi Daniel,

Thanks for your help. I set the Threads parameter to be 1 and here is the solver log I got. It does not seem to have much effect as we would expect though.

'''
Academic license - for non-commercial use only
Changed value of parameter LazyConstraints to 1
   Prev: 0  Min: 0  Max: 1  Default: 0
Changed value of parameter LogFile to ../result/log_gurobi.txt
   Prev: gurobi.log  Default: 
Changed value of parameter TimeLimit to 300.0
   Prev: 1e+100  Min: 0.0  Max: 1e+100  Default: 1e+100
Parameter MIPGap unchanged
   Value: 0.0001  Min: 0.0  Max: 1e+100  Default: 0.0001
Changed value of parameter Threads to 1
   Prev: 0  Min: 0  Max: 1024  Default: 0
Master defined. Continuing optimization...
Iteration 1:
 Solving master...
Optimize a model with 268 rows, 211 columns and 838 nonzeros
Variable types: 1 continuous, 210 integer (210 binary)
Coefficient statistics:
  Matrix range     [1e+00, 8e+01]
  Objective range  [1e+00, 1e+00]
  Bounds range     [1e+00, 1e+00]
  RHS range        [1e+00, 1e+00]
Found a new incumbent...
Found violated cutset... Adding them in...
Presolve removed 66 rows and 46 columns
Presolve time: 0.01s
Presolved: 202 rows, 165 columns, 706 nonzeros
Variable types: 1 continuous, 164 integer (164 binary)
Found a new incumbent...
Found violated cutset... Adding them in...
Found a new incumbent...
Found heuristic solution: objective 506.0000000
Found a new incumbent...
Found violated cutset... Adding them in...

Root relaxation: objective 1.006174e+02, 83 iterations, 0.00 seconds

    Nodes    |    Current Node    |     Objective Bounds      |     Work
 Expl Unexpl |  Obj  Depth IntInf | Incumbent    BestBd   Gap | It/Node Time

     0     0  100.61736    0   30  506.00000  100.61736  80.1%     -    0s
Found a new incumbent...
Found violated cutset... Adding them in...
Found a new incumbent...
Found violated cutset... Adding them in...
Found a new incumbent...
Found violated cutset... Adding them in...
     0     0  111.49822    0   36  506.00000  111.49822  78.0%     -    0s
Found a new incumbent...
Found violated cutset... Adding them in...
Found a new incumbent...
Found violated cutset... Adding them in...
Found a new incumbent...
H    0     0                     366.0000000  111.49822  69.5%     -    0s
     0     0  113.67164    0   32  366.00000  113.67164  68.9%     -    0s
Found a new incumbent...
Found violated cutset... Adding them in...
     0     0  114.01504    0   32  366.00000  114.01504  68.8%     -    0s
Found a new incumbent...
Found violated cutset... Adding them in...
Found a new incumbent...
Found violated cutset... Adding them in...
Found a new incumbent...
H    0     0                     340.0000000  114.01504  66.5%     -    0s
     0     0  117.44444    0   35  340.00000  117.44444  65.5%     -    0s
Found a new incumbent...
Found violated cutset... Adding them in...
     0     0  117.81308    0   44  340.00000  117.81308  65.3%     -    0s
     0     0  117.81308    0   44  340.00000  117.81308  65.3%     -    0s
Found a new incumbent...
Found violated cutset... Adding them in...
Found a new incumbent...
Found violated cutset... Adding them in...
Found a new incumbent...
Found violated cutset... Adding them in...
'''

--

---
You received this message because you are subscribed to a topic in the Google Groups "Gurobi Optimization" group.
To unsubscribe from this topic, visit https://groups.google.com/d/topic/gurobi/a4JlGuY5Vik/unsubscribe.
To unsubscribe from this group and all its topics, send an email to gurobi+unsubscribe@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.

Daniel Espinoza

unread,
Aug 13, 2018, 5:51:36 PM8/13/18
to Gurobi Optimization
Hi Orion,

Interesting... are you positive that you are seeing the same solution and/or adding the same cut?
Is the cut maybe too ugly?


Orion T

unread,
Aug 18, 2018, 12:59:41 PM8/18/18
to Gurobi Optimization
Hi Daniel, sorry I am getting late to this. In the callback function, I only generate one set of cuts and add all of them in. So if the callback is called once at each new incumbent, the print() function should only be called once instead of multiple times. Am I understanding this correctly?

Ziye

Daniel Espinoza

unread,
Aug 20, 2018, 7:38:53 PM8/20/18
to Gurobi Optimization
Hi Ziye,

As I said, it might happen that you are testing different solutions, and each one request the user to test against its lazycallback... so, are you sure the solutions are the same?
Reply all
Reply to author
Forward
0 new messages