Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Error when retrieving the conflict status of a feasible MIP model #307

Closed
ValentinKaisermayer opened this issue Apr 10, 2020 · 5 comments · Fixed by #308
Closed

Error when retrieving the conflict status of a feasible MIP model #307

ValentinKaisermayer opened this issue Apr 10, 2020 · 5 comments · Fixed by #308

Comments

@ValentinKaisermayer
Copy link

Consider the following LP example:

using JuMP, Gurobi
m = Model(Gurobi.Optimizer)
@variable(m, 0 <= x <= 2)
@variable(m, 0 <= y <= 30)
@objective(m, Max, 1*x + 2*y)
@constraint(m, 1x + 5y <= 3.0)
optimize!(m)

It is feasible and I get:

julia> termination_status(m)
OPTIMAL::TerminationStatusCode = 1

julia> Gurobi.compute_conflict(backend(m).optimizer.model)
IIS runtime: 0.00 seconds

julia> JuMP.MOI.get(m, Gurobi.ConflictStatus())
INFEASIBLE::TerminationStatusCode = 2

But if I have a MIP problem:

using JuMP
m = Model(Gurobi.Optimizer)
@variable(m, x, Bin)
@variable(m, 0 <= y <= 30)
@objective(m, Max, 1*x + 2*y)
@constraint(m, 1x + 5y <= 3.0)
optimize!(m)

I get something different:

julia> termination_status(m)
OPTIMAL::TerminationStatusCode = 1

julia> Gurobi.compute_conflict(backend(m).optimizer.model)
Found heuristic solution: objective -0.0000000

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

Solution count 1: -0
No other solutions better than 0

Optimal solution found (tolerance 1.00e-04)
Best objective -0.000000000000e+00, best bound -0.000000000000e+00, gap 0.0000%
IIS runtime: 0.00 seconds

julia> JuMP.MOI.get(m, Gurobi.ConflictStatus())
ERROR: OptimizeNotCalled()

This might actually be a problem with Gurobi.jl.

@odow odow transferred this issue from jump-dev/MathOptInterface.jl Apr 10, 2020
@odow
Copy link
Member

odow commented Apr 10, 2020

We could arguably return something other than OptimizeNotCalled here:
https://github.com/JuliaOpt/Gurobi.jl/blob/eeaeda315b8066d707996973880773f3635e5be9/src/MOI_wrapper.jl#L2619

But what do you expect to happen? There is no IIS. The model is feasible.

@ValentinKaisermayer
Copy link
Author

Since the IIS is a set it should be empty if the model is feasible. In my LP example you could actually query the status of each constraint c like:

for t in JuMP.list_of_constraint_types(m)
    for c in JuMP.all_constraints(m, t...)
        if MOI.get.(m, Gurobi.ConstraintConflictStatus(), c)
            println(c)
        end
    end
end

and get back false for every constraint - why not.

@odow
Copy link
Member

odow commented Apr 10, 2020

Gurobi cannot compute the IIS on a feasible model.

julia> Gurobi.computeIIS(backend(m).optimizer.model.inner)
Found heuristic solution: objective -0.0000000

Explored 0 nodes (0 simplex iterations) in 0.00 seconds
Thread count was 1 (of 8 available processors)

Solution count 1: -0 

Optimal solution found (tolerance 1.00e-04)
Best objective -0.000000000000e+00, best bound -0.000000000000e+00, gap 0.0000%
IIS runtime: 0.00 seconds
ERROR: Gurobi.GurobiError(10015, "Cannot compute IIS on a feasible model")

The current behavior comes from the following chain of events

  • The solved model is feasible
  • Calling compute_conflict tries to compute an IIS
  • Computing the IIS fails because the model is feasible
  • But the act of computing the IIS destroys the stored solution
  • So when we ask for an attribute, Gurobi rightly declares that "OptimizeNotCalled" because from it's point of view, the model is reset to the unsolved state.

You could argue that computing the IIS on a feasible model should not delete the cached solution, but that's an upstream issue.

Calling Gurobi.compute_conflict is an advanced operation. You need to check the model is infeasible first.

@ValentinKaisermayer
Copy link
Author

My point is, that the behaviour should be the same - regarding LP and MIP.

@odow
Copy link
Member

odow commented Apr 11, 2020

See #308. We now throw an error in both cases.

that the behaviour should be the same - regarding LP and MIP.

Sure. But the underlying C library does not have the same behavior.

@odow odow closed this as completed in #308 Apr 14, 2020
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Development

Successfully merging a pull request may close this issue.

2 participants