Skip to content

Commit

Permalink
[FileFormats.MPS] fix issue #2479
Browse files Browse the repository at this point in the history
  • Loading branch information
odow committed Apr 18, 2024
1 parent eff2982 commit c6d8dad
Show file tree
Hide file tree
Showing 5 changed files with 92 additions and 0 deletions.
17 changes: 17 additions & 0 deletions src/FileFormats/MPS/MPS.jl
Original file line number Diff line number Diff line change
Expand Up @@ -1024,6 +1024,7 @@ mutable struct TempMPSModel
obj_constant::Float64
col_lower::Vector{Float64}
col_upper::Vector{Float64}
col_bounds_default::Vector{Bool}
row_lower::Vector{Float64}
row_upper::Vector{Float64}
sense::Vector{Sense}
Expand All @@ -1050,6 +1051,7 @@ function TempMPSModel()
0.0, # obj_constant
Float64[], # col_lower
Float64[], # col_upper
Bool[], # col_bounds_default
Float64[], # row_lower
Float64[], # row_upper
Sense[], # sense
Expand Down Expand Up @@ -1465,6 +1467,7 @@ function _add_new_column(data, column_name)
push!(data.c, 0.0)
push!(data.col_lower, 0.0)
push!(data.col_upper, Inf)
push!(data.col_bounds_default, true)
push!(data.vtype, VTYPE_CONTINUOUS)
return
end
Expand Down Expand Up @@ -1641,6 +1644,13 @@ function _parse_single_bound(data, column_name::String, bound_type::String)
if col === nothing
error("Column name $(column_name) not found.")
end
if data.col_bounds_default[col] && data.vtype[col] == VTYPE_INTEGER
# This column was part of an INTORG...INTEND block, so it gets a default
# bound of [0, 1]. However, since it now has a bound, it reverts to a
# default of [0, inf).
data.col_upper[col] = Inf
end
data.col_bounds_default[col] = false
if bound_type == "PL"
data.col_upper[col] = Inf
elseif bound_type == "MI"
Expand All @@ -1667,6 +1677,13 @@ function _parse_single_bound(
if col === nothing
error("Column name $(column_name) not found.")
end
if data.col_bounds_default[col] && data.vtype[col] == VTYPE_INTEGER
# This column was part of an INTORG...INTEND block, so it gets a default
# bound of [0, 1]. However, since it now has a bound, it reverts to a
# default of [0, inf).
data.col_upper[col] = Inf
end
data.col_bounds_default[col] = false
if bound_type == "FX"
data.col_lower[col] = value
data.col_upper[col] = value
Expand Down
39 changes: 39 additions & 0 deletions test/FileFormats/MPS/MPS.jl
Original file line number Diff line number Diff line change
Expand Up @@ -200,6 +200,45 @@ function test_integer_default_bounds()
return
end

function test_integer_default_bounds_LI()
model = MPS.Model()
filename = joinpath(@__DIR__, "integer_default_bounds_LI.mps")
MOI.read_from_file(model, filename)
x = only(MOI.get(model, MOI.ListOfVariableIndices()))
c_types = MOI.get(model, MOI.ListOfConstraintTypesPresent())
@test length(c_types) == 2
@test (MOI.VariableIndex, MOI.Integer) in c_types
F, S = MOI.VariableIndex, MOI.GreaterThan{Float64}
@test (F, S) in c_types
ci = MOI.ConstraintIndex{F,S}(x.value)
@test MOI.get(model, MOI.ConstraintSet(), ci) == MOI.GreaterThan(1.0)
return
end

function test_integer_default_bounds_MI()
model = MPS.Model()
filename = joinpath(@__DIR__, "integer_default_bounds_MI.mps")
MOI.read_from_file(model, filename)
@test MOI.get(model, MOI.ListOfConstraintTypesPresent()) ==
[(MOI.VariableIndex, MOI.Integer)]
return
end

function test_integer_default_bounds_PL()
model = MPS.Model()
filename = joinpath(@__DIR__, "integer_default_bounds_PL.mps")
MOI.read_from_file(model, filename)
x = only(MOI.get(model, MOI.ListOfVariableIndices()))
c_types = MOI.get(model, MOI.ListOfConstraintTypesPresent())
@test length(c_types) == 2
@test (MOI.VariableIndex, MOI.Integer) in c_types
F, S = MOI.VariableIndex, MOI.GreaterThan{Float64}
@test (F, S) in c_types
ci = MOI.ConstraintIndex{F,S}(x.value)
@test MOI.get(model, MOI.ConstraintSet(), ci) == MOI.GreaterThan(0.0)
return
end

function test_free_integer()
model = MPS.Model()
MOI.read_from_file(model, joinpath(@__DIR__, "free_integer.mps"))
Expand Down
12 changes: 12 additions & 0 deletions test/FileFormats/MPS/integer_default_bounds_LI.mps
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
NAME
OBJSENSE MIN
ROWS
N obj
COLUMNS
MARKER 'MARKER' 'INTORG'
x obj 1
MARKER 'MARKER' 'INTEND'
RHS
BOUNDS
LI BND1 x 1
ENDATA
12 changes: 12 additions & 0 deletions test/FileFormats/MPS/integer_default_bounds_MI.mps
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
NAME
OBJSENSE MIN
ROWS
N obj
COLUMNS
MARKER 'MARKER' 'INTORG'
x obj 1
MARKER 'MARKER' 'INTEND'
RHS
BOUNDS
MI BND1 x
ENDATA
12 changes: 12 additions & 0 deletions test/FileFormats/MPS/integer_default_bounds_PL.mps
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
NAME
OBJSENSE MIN
ROWS
N obj
COLUMNS
MARKER 'MARKER' 'INTORG'
x obj 1
MARKER 'MARKER' 'INTEND'
RHS
BOUNDS
PL BND1 x
ENDATA

0 comments on commit c6d8dad

Please sign in to comment.