Closed DatName closed 9 months ago
Hi.
I found this issue with deleting and adding indicator constraints. Consider:
using JuMP using Gurobi mdl = JuMP.Model() set_optimizer(mdl, Gurobi.Optimizer) b1 = @variable(mdl, binary = true) x1 = @variable(mdl, lower_bound = -1.0, upper_bound = 1.0) x2 = @variable(mdl, lower_bound = -1.0, upper_bound = 1.0) c1 = @constraint(mdl, b1 => {x1 + x2 == 0.1}) c2 = @constraint(mdl, !b1 => {x1 + x2 == -0.1}) @objective(mdl, Max, x1 - x2) optimize!(mdl)
This works as expected. Note that output of Gurobi shows that there are 2 general contrains in the problem:
Set parameter Username Gurobi Optimizer version 10.0.0 build v10.0.0rc2 (linux64) CPU model: 12th Gen Intel(R) Core(TM) i9-12900H, instruction set [SSE2|AVX|AVX2] Thread count: 20 physical cores, 20 logical processors, using up to 20 threads Optimize a model with 0 rows, 3 columns and 0 nonzeros Model fingerprint: 0xa8016401 Model has 2 general constraints Variable types: 2 continuous, 1 integer (1 binary) Coefficient statistics: Matrix range [0e+00, 0e+00] Objective range [1e+00, 1e+00] Bounds range [1e+00, 1e+00] RHS range [0e+00, 0e+00] GenCon rhs range [1e-01, 1e-01] GenCon coe range [1e+00, 1e+00] Presolve added 1 rows and 0 columns Presolve time: 0.00s Presolved: 1 rows, 3 columns, 3 nonzeros Variable types: 2 continuous, 1 integer (1 binary) Found heuristic solution: objective 1.9000000 Root relaxation: objective 2.000000e+00, 1 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 2.00000 0 1 1.90000 2.00000 5.26% - 0s Explored 1 nodes (1 simplex iterations) in 0.00 seconds (0.00 work units) Thread count was 20 (of 20 available processors) Solution count 1: 1.9 Optimal solution found (tolerance 1.00e-04) Best objective 1.900000000000e+00, best bound 1.900000000000e+00, gap 0.0000% User-callback calls 373, time in user-callback 0.00 sec
Now, lets delete and add back the same constraints:
JuMP.delete(mdl, c1) JuMP.delete(mdl, c2) c1 = @constraint(mdl, b1 => {x1 + x2 == 0.1}) c2 = @constraint(mdl, !b1 => {x1 + x2 == -0.1}) @objective(mdl, Max, x1 - x2) optimize!(mdl)
now, Gurobi sees 3 general constraints:
Optimize a model with 0 rows, 3 columns and 0 nonzeros Model fingerprint: 0xe65febfe Model has 3 general constraints ...
If we repeat that last section of julia code, number of general constraints reported by Gurobi will constantly increase:
... Model has 4 general constraints ... ... Model has 5 general constraints ...
and so on. Though number of constraints reported by JuMP.all_constraints(mdl, include_variable_in_set_constraints=true) stays the same.
JuMP.all_constraints(mdl, include_variable_in_set_constraints=true)
If we delete/add different constraints, there will be conflicts, though only after second delete
using JuMP using Gurobi mdl = JuMP.Model() set_optimizer(mdl, Gurobi.Optimizer) b1 = @variable(mdl, binary = true) x1 = @variable(mdl, lower_bound = -1.0, upper_bound = 1.0) x2 = @variable(mdl, lower_bound = -1.0, upper_bound = 1.0) c1 = @constraint(mdl, b1 => {x1 + x2 == 0.1}) c2 = @constraint(mdl, !b1 => {x1 + x2 == -0.1}) @objective(mdl, Max, x1 - x2) optimize!(mdl) @assert JuMP.termination_status(mdl) == MOI.OPTIMAL JuMP.delete(mdl, c1) JuMP.delete(mdl, c2) c1 = @constraint(mdl, b1 => {x1 + x2 == 0.2}) # ! changing right hand side c2 = @constraint(mdl, !b1 => {x1 + x2 == -0.2}) # ! changing right hand side @objective(mdl, Max, x1 - x2) optimize!(mdl) @assert JuMP.termination_status(mdl) == MOI.OPTIMAL JuMP.delete(mdl, c1) JuMP.delete(mdl, c2) c1 = @constraint(mdl, b1 => {x1 + x2 == 0.1}) c2 = @constraint(mdl, !b1 => {x1 + x2 == -0.1}) @objective(mdl, Max, x1 - x2) optimize!(mdl) @assert JuMP.termination_status(mdl) == MOI.OPTIMAL # ! throws
currently, the last model is infeasible.
I assume this is because of #516
https://github.com/jump-dev/Gurobi.jl/blob/68311c5f945f82d4cb5f073e31b1503cb6a7f92b/src/MOI_wrapper/MOI_indicator_constraint.jl#L194-L211
Hi.
I found this issue with deleting and adding indicator constraints. Consider:
This works as expected. Note that output of Gurobi shows that there are 2 general contrains in the problem:
Now, lets delete and add back the same constraints:
now, Gurobi sees 3 general constraints:
If we repeat that last section of julia code, number of general constraints reported by Gurobi will constantly increase:
and so on. Though number of constraints reported by
JuMP.all_constraints(mdl, include_variable_in_set_constraints=true)
stays the same.If we delete/add different constraints, there will be conflicts, though only after second delete
currently, the last model is infeasible.