Terminating barrier with TimeLimit provides no solution
AnsweredHello to the community,
I am setting the TimeLimit parameter to an LP, with Method = 2,.
The time limit is respected, but I am unable to retrieve any values for my variables.
I would expect that I would be able to get the best solution found so far, which I would also expect to be feasible. Any suggestions? My TimeLimit is generous enough that Barrier has performed a lot of iterations. Crossover is disabled. Any suggestions?
Marilena
-
Hi Marilena,
What version of Gurobi are you using, and what API? I couldn't reproduce this issue on a toy example using Gurobi v13 via gurobipy.
- Riley
0 -
Hi Riley,
Gurobi version is 11.0.2. I am using Julia v1.9.3 and JuMP v1.23.2 with the Gurobi.jl wrapper v1.3.1.
Below you can see the gurobi log for a test case where I am setting a time limit of 4. Without the time limit I require ~4.5 seconds, and barrier performs 39 iterations.From worker 2: Set parameter Method to value 2 From worker 2: Set parameter Crossover to value 0 From worker 2: Set parameter Threads to value 4 From worker 2: Set parameter TimeLimit to value 4 From worker 2: Gurobi Optimizer version 11.0.2 build v11.0.2rc0 (win64 - Windows 11.0 (22631.2)) From worker 2: From worker 2: CPU model: 13th Gen Intel(R) Core(TM) i7-13700, instruction set [SSE2|AVX|AVX2] From worker 2: Thread count: 16 physical cores, 24 logical processors, using up to 4 threads From worker 2: From worker 2: Optimize a model with 165860 rows, 111428 columns and 1578758 nonzeros From worker 2: Model fingerprint: 0xcc35accf From worker 2: Coefficient statistics: From worker 2: Matrix range [1e-02, 2e+00] From worker 2: Objective range [1e-07, 1e+05] From worker 2: Bounds range [0e+00, 0e+00] From worker 2: RHS range [2e-02, 9e+07] From worker 2: Presolve removed 108867 rows and 19020 columns From worker 2: Presolve time: 0.42s From worker 2: Presolved: 56993 rows, 104792 columns, 901516 nonzeros From worker 2: Ordering time: 0.63s From worker 2: From worker 2: Barrier statistics: From worker 2: Free vars : 17 From worker 2: AA' NZ : 2.747e+06 From worker 2: Factor NZ : 8.103e+06 (roughly 130 MB of memory) From worker 2: Factor Ops : 3.129e+09 (less than 1 second per iteration) From worker 2: Threads : 4 From worker 2: From worker 2: Objective Residual From worker 2: Iter Primal Dual Primal Dual Compl Time From worker 2: 0 5.32737208e+14 -1.24563341e+15 1.31e+08 3.43e+04 1.51e+12 1s From worker 2: 1 7.49165932e+14 -8.44879421e+14 8.34e+07 1.29e+04 8.94e+11 1s From worker 2: 2 3.36499225e+14 -5.23529023e+14 4.59e+07 2.75e+03 5.60e+11 2s From worker 2: 3 2.85983435e+13 -3.12890311e+14 3.68e+06 5.44e+02 4.67e+10 2s From worker 2: 4 3.52188846e+12 -1.66050233e+14 4.29e+05 9.31e+01 6.05e+09 2s From worker 2: 5 4.69373660e+11 -5.57970315e+13 4.17e+04 4.39e+00 7.46e+08 2s From worker 2: 6 1.64999608e+11 -1.08195127e+13 4.75e+03 2.75e-01 9.68e+07 2s From worker 2: 7 1.31849861e+11 -2.95783024e+12 9.30e+02 4.54e-02 2.10e+07 2s From worker 2: 8 1.13087028e+11 -9.29143055e+11 1.12e+02 1.18e-02 5.56e+06 2s From worker 2: 9 8.78166077e+10 -6.05439982e+11 2.13e+01 7.44e-03 3.45e+06 2s From worker 2: 10 3.35534048e+10 -1.47482884e+11 5.83e-01 4.52e-03 8.83e+05 2s From worker 2: 11 5.81190978e+09 -7.39792399e+10 6.98e-02 1.43e-02 3.89e+05 2s From worker 2: 12 -2.29971894e+09 -2.96866348e+10 1.86e-02 3.05e-02 1.33e+05 2s From worker 2: 13 -5.56949719e+09 -1.87568621e+10 6.23e-03 1.84e-02 6.42e+04 2s From worker 2: 14 -7.02143946e+09 -1.27167033e+10 2.72e-03 9.99e-03 2.77e+04 2s From worker 2: 15 -7.80972267e+09 -1.04836152e+10 1.08e-03 5.47e-03 1.30e+04 2s From worker 2: 16 -8.21045817e+09 -9.44698746e+09 3.50e-04 3.05e-03 6.02e+03 2s From worker 2: 17 -8.34029044e+09 -8.93301791e+09 1.45e-04 1.84e-03 2.89e+03 3s From worker 2: 18 -8.39471216e+09 -8.67021865e+09 7.22e-05 9.56e-04 1.34e+03 3s From worker 2: 19 -8.42197204e+09 -8.55145007e+09 4.12e-05 4.63e-04 6.31e+02 3s From worker 2: 20 -8.43726002e+09 -8.52484900e+09 2.53e-05 3.51e-04 4.27e+02 3s From worker 2: 21 -8.44933608e+09 -8.49393320e+09 1.32e-05 1.84e-04 2.17e+02 3s From worker 2: 22 -8.45786290e+09 -8.47954115e+09 3.19e-05 1.00e-04 1.06e+02 3s From worker 2: 23 -8.46149221e+09 -8.47081126e+09 1.17e-05 3.73e-05 4.54e+01 3s From worker 2: 24 -8.46345671e+09 -8.46723541e+09 3.78e-06 1.77e-05 1.84e+01 3s From worker 2: 25 -8.46396524e+09 -8.46594444e+09 1.87e-06 9.14e-06 9.64e+00 3s From worker 2: 26 -8.46423484e+09 -8.46522973e+09 9.34e-07 4.56e-06 4.84e+00 3s From worker 2: 27 -8.46433632e+09 -8.46485493e+09 6.05e-07 2.12e-06 2.53e+00 3s From worker 2: 28 -8.46444390e+09 -8.46466629e+09 2.70e-07 1.78e-06 1.08e+00 3s From worker 2: 29 -8.46450311e+09 -8.46459293e+09 1.49e-07 9.35e-07 4.37e-01 3s From worker 2: 30 -8.46453031e+09 -8.46456368e+09 4.85e-08 3.39e-07 1.62e-01 4s From worker 2: 31 -8.46453806e+09 -8.46455371e+09 2.16e-08 1.56e-07 7.62e-02 4s From worker 2: 32 -8.46454208e+09 -8.46454867e+09 1.31e-08 7.10e-08 3.21e-02 4s From worker 2: 33 -8.46454416e+09 -8.46454510e+09 8.73e-09 2.76e-07 4.57e-03 4s From worker 2: From worker 2: Barrier performed 33 iterations in 4.03 seconds (8.82 work units) From worker 2: Time limit reached
In the end I am testing what the model returns with the JuMP calls:
termination_status(model)
primal_status(model)
and I get:From worker 2: TIME_LIMIT From worker 2: NO_SOLUTIONwhile, without the time limit I am getting
From worker 2: OPTIMAL From worker 2: FEASIBLE_POINTMarilena
0 -
Hi Marilena,
Can you try and query the “X” attribute? Something like this:
MOI.get(model, Gurobi.ModelAttribute("X"))You can also try setting the ResultFile parameter in order to write the solution to file:
set_optimizer_attribute(model, "ResultFile", "solution.sol")- Riley
0 -
Indeed, I can retrieve the values I need with
MOI.get(grb, Gurobi.VariableAttribute("X"), index(my_x))
Therefore, if I attempt to explain what is happening is that the solution is there from Gurobi, but the way the JuMP API calls are set, do not retrieve the values in the case of early termination.Let me also note that I should set my model as a “direct_model” instead of "model", which I hope will not significanty affect my process.
gurobi_env = Gurobi.Env() Solver = optimizer_with_attributes(() -> Gurobi.Optimizer(gurobi_env), "TimeLimit" => time_limit) #model = Model(Solver) model= direct_model(Solver)Many thanks Riley, once again you have been very helpful!
0 -
Hi Marilena,
You're welcome! A github issue on the appropriate repository (Jump.jl or MathOptInterface.jl ? - you would know better than me) might be helpful to see if it can be addressed by the developers.
- Riley
0 -
Hi again, and Happy New Year!
I have a follow-up question on this issue.
Communication with Julia developers indicated that as long as a feasible solution is available at the time of early termination, it can be returned (the discussion is in https://discourse.julialang.org/t/retrieve-current-solution-when-termination-status-is-time-limit/134464/7).This implies that the solution I obtain from an early iterate of Barrier is infeasible, which is not what I expected based on my understanding of how Barrier works (iterating within the feasible region). To verify the infeasibility, I fixed all variables to the "early" solution and reran; indeed, this fixed model is infeasible, with violations of the order of 1e-3 on equality constraints (lhs value obtained from fixed variables is greater than rhs value).
Is this behavior expected? And if yes, could you direct me to relevant documentation where this is explained?
Marilena
0 -
Hi Marilena,
Happy New Year to you too!
The behavior is expected, and the following webinar recording will help explain what are actually solving when our barrier algorithm runs:
Performance Tuning for Gurobi's Barrier AlgorithmThe barrier iterations are interior, with respect to bounds (in both primal and dual space), but not with respect to constraints. This is why in the barrier logging you will see violations for primal feasibility and dual feasibility logged (as well as complementarity), but not bound violations. Granted, our own diagrams for how the barrier algorithm works contribute to this misunderstanding - the image of a path that snakes its way through the interior of a feasible region is used everywhere, and although there are interior point methods which maintain primal feasibility like this, they are less efficient (but simpler to explain).
- Riley
0 -
Many thanks Riley for the very useful info.
Best,
Marilena
0
Please sign in to leave a comment.
Comments
8 comments