Different objective value from current best objective
AnsweredHi,
I want to fetch the current best objective and the upper bound for a solution. This is to estimate the percentage gap between the two values. I want to fetch these values when the model is encountering a time interrupt. My model has two objective functions, which are prioritised (using lexicographic ordering). Both objective functions are to be maximised. I only want to estimate the gap for the first objective (the one with highest priority).
To do this, my understanding is that I need to use a callback function to save the last value of the best objective and the upper bound. To do this I am using the following code snippet found on this community:
def callback(model, where):
if where == gp.GRB.Callback.MIPSOL:
model._bound = model.cbGet(gp.GRB.Callback.MIPSOL_OBJBND)
model._best = model.cbGet(gp.GRB.Callback.MIPSOL_OBJBST)
elif where == gp.GRB.Callback.MULTIOBJ:
model._bounds[model.cbGet(gp.GRB.Callback.MULTIOBJ_OBJCNT) - 1] = model._bound
model._bests[model.cbGet(gp.GRB.Callback.MULTIOBJ_OBJCNT) - 1] = model._best
model._bounds = [None]*2
model._bests = [None]*2
-
Hi Erik,
To clarify the behavior, could you please share a log output and point to when you get which value via the callback and via the ObjVal attribute?
Best regards,
Jaromił0 -
The log output received from my solution is under ____LOG_OUTPUT_WITH_TWO_OBJECTIVE___. I printed the last callback values received, the calculated MIPGap and the model.ObjVal in the bottom of the log output. I do not understand why the first objective receives negative values for incumbent and BestBd (-9 and -8), when the objective itself is strictly positive.
Furthermore, I tried removing the second objective, objective z_2, and optimizing the problem with only one objective, z_1. When doing this I received reasonable values. The log output is under
___LOG_OUTPUT_WITH_ONE_OBJECTIVE___.
____LOG_OUTPUT_WITH_TWO_OBJECTIVE___
Set parameter Username
Academic license - for non-commercial use only - expires 2024-09-27
Set parameter TimeLimit to value 3.5999604201316833e+03
Gurobi Optimizer version 10.0.0 build v10.0.0rc2 (mac64[arm])
CPU model: Apple M1
Thread count: 8 physical cores, 8 logical processors, using up to 8 threads
Optimize a model with 2297 rows, 729 columns and 4875 nonzeros
Model fingerprint: 0xf1504728
Variable types: 392 continuous, 337 integer (337 binary)
Coefficient statistics:
Matrix range [1e+00, 6e+04]
Objective range [1e+00, 1e+00]
Bounds range [1e+00, 1e+00]
RHS range [1e+00, 6e+04]
---------------------------------------------------------------------------
Multi-objectives: starting optimization with 2 objectives ...
---------------------------------------------------------------------------
Multi-objectives: applying initial presolve ...
---------------------------------------------------------------------------
Presolve removed 1236 rows and 44 columns
Presolve time: 0.01s
Presolved: 1061 rows and 685 columns
---------------------------------------------------------------------------
Multi-objectives: optimize objective 1 (z_1) ...
---------------------------------------------------------------------------
Presolve removed 330 rows and 321 columns
Presolve time: 0.01s
Presolved: 731 rows, 364 columns, 3693 nonzeros
Variable types: 72 continuous, 292 integer (292 binary)
Found heuristic solution: objective -14.0000000
Found heuristic solution: objective -11.0000000
Root relaxation: objective -8.000000e+00, 132 iterations, 0.00 seconds (0.00 work units)
Nodes | Current Node | Objective Bounds | Work
Expl Unexpl | Obj Depth IntInf | Incumbent BestBd Gap | It/Node Time
0 0 -8.00000 0 18 -11.00000 -8.00000 27.3% - 0s
H 0 0 -10.0000000 -8.00000 20.0% - 0s
0 0 -8.00000 0 18 -10.00000 -8.00000 20.0% - 0s
H 0 0 -9.0000000 -8.00000 11.1% - 0s
0 0 infeasible 0 -9.00000 -9.00000 0.00% - 0s
Cutting planes:
Learned: 1
Gomory: 2
Implied bound: 3
MIR: 2
Zero half: 2
RLT: 2
Relax-and-lift: 1
Explored 1 nodes (317 simplex iterations) in 0.04 seconds (0.06 work units)
Thread count was 8 (of 8 available processors)
Solution count 4: -9 -10 -11 -14
No other solutions better than -9
Optimal solution found (tolerance 1.00e-04)
Best objective -9.000000000000e+00, best bound -9.000000000000e+00, gap 0.0000%
---------------------------------------------------------------------------
Multi-objectives: optimize objective 2 (z_2) ...
---------------------------------------------------------------------------
Loaded user MIP start with objective 165.92
Presolve removed 330 rows and 320 columns
Presolve time: 0.01s
Presolved: 732 rows, 365 columns, 3857 nonzeros
Variable types: 72 continuous, 293 integer (293 binary)
Root relaxation: objective 3.507653e+02, 182 iterations, 0.00 seconds (0.00 work units)
Nodes | Current Node | Objective Bounds | Work
Expl Unexpl | Obj Depth IntInf | Incumbent BestBd Gap | It/Node Time
0 0 350.76528 0 40 165.92000 350.76528 111% - 0s
0 0 279.13591 0 61 165.92000 279.13591 68.2% - 0s
0 0 181.00000 0 63 165.92000 181.00000 9.09% - 0s
0 0 181.00000 0 51 165.92000 181.00000 9.09% - 0s
0 0 181.00000 0 34 165.92000 181.00000 9.09% - 0s
0 0 181.00000 0 47 165.92000 181.00000 9.09% - 0s
0 0 181.00000 0 49 165.92000 181.00000 9.09% - 0s
0 0 181.00000 0 52 165.92000 181.00000 9.09% - 0s
0 0 181.00000 0 49 165.92000 181.00000 9.09% - 0s
0 0 181.00000 0 48 165.92000 181.00000 9.09% - 0s
0 0 181.00000 0 57 165.92000 181.00000 9.09% - 0s
0 0 181.00000 0 58 165.92000 181.00000 9.09% - 0s
0 0 181.00000 0 59 165.92000 181.00000 9.09% - 0s
0 0 181.00000 0 59 165.92000 181.00000 9.09% - 0s
0 0 181.00000 0 56 165.92000 181.00000 9.09% - 0s
0 0 181.00000 0 52 165.92000 181.00000 9.09% - 0s
0 0 181.00000 0 62 165.92000 181.00000 9.09% - 0s
0 0 181.00000 0 38 165.92000 181.00000 9.09% - 0s
0 2 181.00000 0 38 165.92000 181.00000 9.09% - 0s
Cutting planes:
Learned: 21
Gomory: 1
Cover: 21
Implied bound: 106
Clique: 4
MIR: 23
Inf proof: 8
Zero half: 7
RLT: 21
Relax-and-lift: 6
Explored 2560 nodes (41507 simplex iterations) in 0.50 seconds (0.57 work units)
Thread count was 8 (of 8 available processors)
Solution count 1: 165.92
Optimal solution found (tolerance 1.00e-04)
Best objective 1.659200000000e+02, best bound 1.659200000000e+02, gap 0.0000%
---------------------------------------------------------------------------
Multi-objectives: solved in 0.50 seconds (0.57 work units), solution count 5
User-callback calls 6466, time in user-callback 0.01 sec
Last received upper bound: | -8.0
Last received best bound: | -9.0
Calculated MIP gap: | 0.1111
Objective value from model.ObjVal: | 7.0
___LOG_OUTPUT_WITH_ONE_OBJECTIVE___
Set parameter Username
Academic license - for non-commercial use only - expires 2024-09-27
Set parameter TimeLimit to value 3.5999585959911346e+03
Gurobi Optimizer version 10.0.0 build v10.0.0rc2 (mac64[arm])
CPU model: Apple M1
Thread count: 8 physical cores, 8 logical processors, using up to 8 threads
Optimize a model with 2297 rows, 729 columns and 4875 nonzeros
Model fingerprint: 0x379f446b
Variable types: 392 continuous, 337 integer (337 binary)
Coefficient statistics:
Matrix range [1e+00, 6e+04]
Objective range [1e+00, 1e+00]
Bounds range [1e+00, 1e+00]
RHS range [1e+00, 6e+04]
---------------------------------------------------------------------------
Multi-objectives: starting optimization with 1 objectives ...
---------------------------------------------------------------------------
---------------------------------------------------------------------------
Multi-objectives: optimize objective 1 (z_1) ...
---------------------------------------------------------------------------
Optimize a model with 2297 rows, 729 columns and 4875 nonzeros
Model fingerprint: 0x5bc4a615
Variable types: 392 continuous, 337 integer (337 binary)
Coefficient statistics:
Matrix range [1e+00, 6e+04]
Objective range [1e+00, 1e+00]
Bounds range [1e+00, 1e+00]
RHS range [1e+00, 6e+04]
Presolve removed 1566 rows and 365 columns
Presolve time: 0.02s
Presolved: 731 rows, 364 columns, 3693 nonzeros
Variable types: 72 continuous, 292 integer (292 binary)
Found heuristic solution: objective 2.0000000
Found heuristic solution: objective 5.0000000
Root relaxation: objective 8.000000e+00, 132 iterations, 0.00 seconds (0.00 work units)
Nodes | Current Node | Objective Bounds | Work
Expl Unexpl | Obj Depth IntInf | Incumbent BestBd Gap | It/Node Time
0 0 8.00000 0 18 5.00000 8.00000 60.0% - 0s
H 0 0 6.0000000 8.00000 33.3% - 0s
0 0 8.00000 0 18 6.00000 8.00000 33.3% - 0s
H 0 0 7.0000000 8.00000 14.3% - 0s
0 0 infeasible 0 7.00000 7.00000 0.00% - 0s
Cutting planes:
Learned: 1
Gomory: 2
Implied bound: 3
MIR: 2
Zero half: 2
RLT: 2
Relax-and-lift: 1
Explored 1 nodes (317 simplex iterations) in 0.04 seconds (0.04 work units)
Thread count was 8 (of 8 available processors)
Solution count 4: 7 6 5 2
Optimal solution found (tolerance 1.00e-04)
Best objective 7.000000000000e+00, best bound 7.000000000000e+00, gap 0.0000%
---------------------------------------------------------------------------
Multi-objectives: solved in 0.04 seconds (0.04 work units), solution count 4
User-callback calls 129, time in user-callback 0.00 sec
Last received upper bound: | 8.0
Last received best bound: | 7.0
Calculated MIP gap: | 0.1429
Objective value from model.ObjVal: | 7.00 -
Hi Erik,
Please update to the latest version of Gurobi. In v10.0.0 there was a bug affecting the output of multi-objective problems, please refer to this Knowledge Base article for additional information. Please check whether an update to a newer version solves your issues and feel free to post again if not.
Best regards,
Jaromił0 -
That worked!
But I still have a question. As seen from the log output underneath, the incumbent value and BestBd is 7.00 and 7.00 in the final solution. Why does the last values from the callback function report upper bound as 8.0 and best bound 6.0? Is it a way to make sure that these values match?
____LOG_OUTPUT_WITH_TWO_OBJECTIVES___
Set parameter Username
Academic license - for non-commercial use only - expires 2024-09-27
Set parameter TimeLimit to value 3.5999603188037872e+03
Gurobi Optimizer version 10.0.2 build v10.0.2rc0 (mac64[arm])
CPU model: Apple M1
Thread count: 8 physical cores, 8 logical processors, using up to 8 threads
Optimize a model with 2297 rows, 729 columns and 4875 nonzeros
Model fingerprint: 0xf1504728
Variable types: 392 continuous, 337 integer (337 binary)
Coefficient statistics:
Matrix range [1e+00, 6e+04]
Objective range [1e+00, 1e+00]
Bounds range [1e+00, 1e+00]
RHS range [1e+00, 6e+04]
---------------------------------------------------------------------------
Multi-objectives: starting optimization with 2 objectives ...
---------------------------------------------------------------------------
Multi-objectives: applying initial presolve ...
---------------------------------------------------------------------------
Presolve removed 1236 rows and 44 columns
Presolve time: 0.01s
Presolved: 1061 rows and 685 columns
---------------------------------------------------------------------------
Multi-objectives: optimize objective 1 (z_1) ...
---------------------------------------------------------------------------
Presolve removed 330 rows and 321 columns
Presolve time: 0.01s
Presolved: 731 rows, 364 columns, 3693 nonzeros
Variable types: 72 continuous, 292 integer (292 binary)
Found heuristic solution: objective 2.0000000
Found heuristic solution: objective 5.0000000
Root relaxation: objective 8.000000e+00, 132 iterations, 0.00 seconds (0.00 work units)
Nodes | Current Node | Objective Bounds | Work
Expl Unexpl | Obj Depth IntInf | Incumbent BestBd Gap | It/Node Time
0 0 8.00000 0 18 5.00000 8.00000 60.0% - 0s
H 0 0 6.0000000 8.00000 33.3% - 0s
0 0 8.00000 0 18 6.00000 8.00000 33.3% - 0s
H 0 0 7.0000000 8.00000 14.3% - 0s
0 0 infeasible 0 7.00000 7.00000 0.00% - 0s
Cutting planes:
Learned: 1
Gomory: 2
Implied bound: 3
MIR: 2
Zero half: 2
RLT: 2
Relax-and-lift: 1
Explored 1 nodes (317 simplex iterations) in 0.04 seconds (0.06 work units)
Thread count was 8 (of 8 available processors)
Solution count 4: 7 6 5 2
Optimal solution found (tolerance 1.00e-04)
Best objective 7.000000000000e+00, best bound 7.000000000000e+00, gap 0.0000%
---------------------------------------------------------------------------
Multi-objectives: optimize objective 2 (z_2) ...
---------------------------------------------------------------------------
Loaded user MIP start with objective 71.92
Presolve removed 330 rows and 320 columns
Presolve time: 0.01s
Presolved: 732 rows, 365 columns, 3857 nonzeros
Variable types: 72 continuous, 293 integer (293 binary)
Root relaxation: objective 2.567653e+02, 182 iterations, 0.00 seconds (0.00 work units)
Nodes | Current Node | Objective Bounds | Work
Expl Unexpl | Obj Depth IntInf | Incumbent BestBd Gap | It/Node Time
0 0 256.76528 0 40 71.92000 256.76528 257% - 0s
0 0 185.13591 0 61 71.92000 185.13591 157% - 0s
0 0 87.00000 0 63 71.92000 87.00000 21.0% - 0s
0 0 87.00000 0 51 71.92000 87.00000 21.0% - 0s
0 0 87.00000 0 44 71.92000 87.00000 21.0% - 0s
0 0 87.00000 0 46 71.92000 87.00000 21.0% - 0s
0 0 87.00000 0 46 71.92000 87.00000 21.0% - 0s
0 0 87.00000 0 44 71.92000 87.00000 21.0% - 0s
0 0 87.00000 0 44 71.92000 87.00000 21.0% - 0s
0 0 87.00000 0 54 71.92000 87.00000 21.0% - 0s
0 0 87.00000 0 54 71.92000 87.00000 21.0% - 0s
0 0 87.00000 0 54 71.92000 87.00000 21.0% - 0s
0 0 87.00000 0 40 71.92000 87.00000 21.0% - 0s
0 0 87.00000 0 49 71.92000 87.00000 21.0% - 0s
0 0 87.00000 0 49 71.92000 87.00000 21.0% - 0s
0 0 87.00000 0 50 71.92000 87.00000 21.0% - 0s
0 0 87.00000 0 58 71.92000 87.00000 21.0% - 0s
0 0 87.00000 0 48 71.92000 87.00000 21.0% - 0s
0 0 87.00000 0 54 71.92000 87.00000 21.0% - 0s
0 0 87.00000 0 44 71.92000 87.00000 21.0% - 0s
0 2 87.00000 0 44 71.92000 87.00000 21.0% - 0s
Cutting planes:
Learned: 23
Gomory: 1
Cover: 19
Implied bound: 122
Clique: 2
MIR: 41
Inf proof: 3
Zero half: 4
Mod-K: 1
RLT: 22
Relax-and-lift: 4
Explored 2589 nodes (41141 simplex iterations) in 0.56 seconds (0.64 work units)
Thread count was 8 (of 8 available processors)
Solution count 1: 71.92
Optimal solution found (tolerance 1.00e-04)
Best objective 7.191999999999e+01, best bound 7.191999999999e+01, gap 0.0000%
---------------------------------------------------------------------------
Multi-objectives: solved in 0.56 seconds (0.64 work units), solution count 5
User-callback calls 6611, time in user-callback 0.01 sec
Last received upper bound: | 8.0
Last received best bound: | 6.0
Calculated MIP gap: | 0.3333
Objective value from model.ObjVal: | 7.00 -
Hi Erik,
Why does the last values from the callback function report upper bound as 8.0 and best bound 6.0?
It is possible that the callback was not synced yet and the solution is found so quickly such that the MIPSOL callback just get skipped. Thus, you don't get the chance to access the final objval and bestbd in a MIPSOL callback.
Is it a way to make sure that these values match?
Currently, there is no easy way to get the final optimization values of an intermediate multi-objective solve. However, you can use a MESSAGE callback to access this information
if where == GRB.Callback.MESSAGE: msg = model.cbGet(GRB.Callback.MSG_STRING) # Check if this objective solve has terminated m = re.search('Best objective (?P<ObjVal>[^,]+), best bound (?P<ObjBound>[^,]+), gap (?P<MIPGap>.*)%$', msg) if m: (obj_best, obj_bound, gap) = m.group(1,2,3) obj_best = float(obj_best) obj_bound = float(obj_bound)gap = float(gap)/100 print(obj_best, obj_bound, gap)This should work as a workaround.
We are aware of this missing feature and this is on our future road map.
Best regards,
Jaromił1
Please sign in to leave a comment.
Comments
5 comments