Skip to content

Indicator constraints could not be deleted #538

Closed
@DatName

Description

@DatName

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.


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.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions