0
votes

I'm using Gurobi in Python. I'm iterating over a set of nodes and at each iteration, I'm adding a constraint to solve. After solving, it produces the Gurobi log as follows:

Optimize a model with 6 rows, 36 columns and 41 nonzeros
Variable types: 0 continuous, 36 integer (36 binary)
Coefficient statistics:
  Matrix range     [1e+00, 1e+00]
  Objective range  [2e+01, 9e+01]
  Bounds range     [1e+00, 1e+00]
  RHS range        [2e+00, 2e+00]

MIP start did not produce a new incumbent solution
MIP start violates constraint R5 by 2.000000000

Found heuristic solution: objective 347.281
Presolve removed 2 rows and 21 columns
Presolve time: 0.00s
Presolved: 4 rows, 15 columns, 27 nonzeros
Found heuristic solution: objective 336.2791955
Variable types: 0 continuous, 15 integer (15 binary)

Root relaxation: objective 3.043757e+02, 6 iterations, 0.00 seconds

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

*    0     0               0     304.3757488  304.37575  0.00%     -    0s

Explored 0 nodes (6 simplex iterations) in 0.02 seconds
Thread count was 4 (of 4 available processors)

Solution count 3: 304.376 336.279 339.43 

Optimal solution found (tolerance 1.00e-04)
Best objective 3.043757488224e+02, best bound 3.043757488224e+02, gap 0.0000%

But after a certain iteration, my answer is not what I'm expecting. So I wish to print all my model details (objective function, constraints etc) in the Gurobi log at every iteration.How can I do that?

But model.write() prints the objective function and the constraint that we have coded.

    Minimize
  0 x(0,0) + 75.47184905645283 x(0,1) + 57.55866572463264 x(0,2)
   + 33.97057550292606 x(0,3) + 23.3238075793812 x(0,4)
   + 40.80441152620633 x(0,5) + 75.47184905645283 x(1,0) + 0 x(1,1)
   + 32.7566787083184 x(1,2) + 90.60905032059435 x(1,3)
   + 55.71355310873648 x(1,4) + 40.60788100849391 x(1,5)
   + 57.55866572463264 x(2,0) + 32.7566787083184 x(2,1) + 0 x(2,2)
   + 83.36066218546971 x(2,3) + 46.57252408878007 x(2,4)
   + 41.4004830889689 x(2,5) + 33.97057550292606 x(3,0)
   + 90.60905032059435 x(3,1) + 83.36066218546971 x(3,2) + 0 x(3,3)
   + 37.12142238654117 x(3,4) + 50.00999900019995 x(3,5)
   + 23.3238075793812 x(4,0) + 55.71355310873648 x(4,1)
   + 46.57252408878007 x(4,2) + 37.12142238654117 x(4,3) + 0 x(4,4)
   + 17.69180601295413 x(4,5) + 40.80441152620633 x(5,0)
   + 40.60788100849391 x(5,1) + 41.4004830889689 x(5,2)
   + 50.00999900019995 x(5,3) + 17.69180601295413 x(5,4) + 0 x(5,5)
Subject To
 R0: x(0,1) + x(0,2) + x(0,3) + x(0,4) + x(0,5) >= 2
 R1: x(1,0) + x(1,2) + x(1,3) + x(1,4) + x(1,5) >= 2
 R2: x(1,0) + x(1,3) + x(1,4) + x(2,0) + x(2,3) + x(2,4) + x(5,0) + 
     x(5,3)+ x(5,4) >= 2
 R3: x(3,0) + x(3,1) + x(3,2) + x(3,4) + x(3,5) >= 2
 R4: x(0,1) + x(0,2) + x(0,5) + x(3,1) + x(3,2) + x(3,5) + x(4,1) + 
     x(4,2)+ x(4,5) >= 2
 R5: x(0,1) + x(0,2) + x(3,1) + x(3,2) + x(4,1) + x(4,2) + x(5,1) + 
     x(5,2)>= 2
Bounds
Binaries
 x(0,0) x(0,1) x(0,2) x(0,3) x(0,4) x(0,5) x(1,0) x(1,1) x(1,2) x(1,3)
 x(1,4) x(1,5) x(2,0) x(2,1) x(2,2) x(2,3) x(2,4) x(2,5) x(3,0) x(3,1)
 x(3,2) x(3,3) x(3,4) x(3,5) x(4,0) x(4,1) x(4,2) x(4,3) x(4,4) x(4,5)
 x(5,0) x(5,1) x(5,2) x(5,3) x(5,4) x(5,5)
End

What I need in this is to know what is happening at each iteration. That's because one iteration gives me another false answer and so I want to check whether any redundant constraint is adding into the model when solving.

In other words, does "Gurobi callbacks" allow us to access all information that is available in the model? What will it produce?

1

1 Answers

0
votes

In other words, does "Gurobi callbacks" allow us to access all information that is available in the model? What will it produce?

No, you cannot print constraints generated in a callback function.

Most likely, the issue is one of the following:

  1. You are calling the wrong function inside the callback. There are two kinds of constraints you can add: lazy constraints and user cuts. Lazy constraints are necessary for the structure; a solution must satisfy all lazy constraints. However, you use lazy constraints when they are too numerous to add to the model, and you only want to add those that get violated. User cuts are not necessary, but they can help remove fractional solutions and tighten the LP relaxation of a MIP. In your case, it sounds like you have lazy constraints.

  2. You are not adding all violated lazy constraints. As stated in the documentation: "Your callback should be prepared to cut off solutions that violate any of your lazy constraints, including those that have already been added." You should not track whether you added a lazy constraint already; you must add it every time you see that it is violated. This is due to the parallel processing of the Gurobi solver.