Search code examples
pythonlazy-evaluationmathematical-optimizationlinear-programminggurobi

Adding lazy constraint in python-Gurobi interface


I am trying to add some lazy constraints to the first stage of a stochastic programming problem. For example, the optimal solution shows me that locations 16 and 20 are chosen together which I don't want to so I want to add a lazy constraint as follows:

   First Stage
       x1 + x2 + ... + x40 = 5
       z_i,l <= x_i   i=1,..,40  and l=1,2
   Second Stage
       ....
   def mycallback(model,where):
       if where == GRB.Callback.MIPSOL:
          sol = model.cbGetSolution([model._vars[s] for s in range(1,40)])
          if sol[16] + sol[20] == 2:
             Exp = LinExpr([(1,model._vars[16]),(1,model._vars[20])])
             model.cbLazy(Exp <= 1)

  model._vars = x
  model.optimize(mycallback)

But after running this function, locations 16 and 20 are still in the optimal solution. Could you please let me know how should I attack this issue?


Solution

  • In your code, the test

    if sol[16] + sol[20] == 2:
    

    is comparing the sum of two floating point numbers with an integer using equality. Even if you declare decision variables to be integer, the solution values are floating point numbers. The floating point numbers don't even need to have integer values. Gurobi has a parameter IntFeasTol, which determines how far a value can be from 0 or 1 and still be considered binary. The default is 1e-5, so 0.999991 would be considered an integer. Your check should something like

    if sol[16] + sol[20] > 1.5: