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

[FileFormats] read double-sided variable bounds separately #2548

Merged
merged 3 commits into from
Oct 7, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 4 additions & 1 deletion src/FileFormats/LP/LP.jl
Original file line number Diff line number Diff line change
Expand Up @@ -916,7 +916,10 @@
return
elseif -Inf < lb < ub < Inf
_delete_default_lower_bound_if_present(model, cache, x)
MOI.add_constraint(model, x, MOI.Interval(lb, ub))
# Do not add MOI.Interval constraints because we want to follow
# JuMP's convention of adding separate lower and upper bounds.
MOI.add_constraint(model, x, MOI.GreaterThan(lb))
MOI.add_constraint(model, x, MOI.LessThan(ub))

Check warning on line 922 in src/FileFormats/LP/LP.jl

View check run for this annotation

Codecov / codecov/patch

src/FileFormats/LP/LP.jl#L921-L922

Added lines #L921 - L922 were not covered by tests
return
elseif lb == -Inf
_delete_default_lower_bound_if_present(model, cache, x)
Expand Down
7 changes: 6 additions & 1 deletion src/FileFormats/MPS/MPS.jl
Original file line number Diff line number Diff line change
Expand Up @@ -1287,7 +1287,12 @@
variable_map[name] = x
MOI.set(model, MOI.VariableName(), x, name)
set = bounds_to_set(data.col_lower[i], data.col_upper[i])
if set !== nothing
if set isa MOI.Interval

Check warning on line 1290 in src/FileFormats/MPS/MPS.jl

View check run for this annotation

Codecov / codecov/patch

src/FileFormats/MPS/MPS.jl#L1290

Added line #L1290 was not covered by tests
# Do not add MOI.Interval constraints because we want to follow JuMP's
# convention of adding separate lower and upper bounds.
MOI.add_constraint(model, x, MOI.GreaterThan(set.lower::Float64))
MOI.add_constraint(model, x, MOI.LessThan(set.upper::Float64))
elseif set !== nothing

Check warning on line 1295 in src/FileFormats/MPS/MPS.jl

View check run for this annotation

Codecov / codecov/patch

src/FileFormats/MPS/MPS.jl#L1293-L1295

Added lines #L1293 - L1295 were not covered by tests
MOI.add_constraint(model, x, set)
end
if data.vtype[i] == VTYPE_INTEGER
Expand Down
19 changes: 15 additions & 4 deletions test/FileFormats/LP/LP.jl
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,8 @@ module TestLP
using Test

import MathOptInterface as MOI
const LP = MOI.FileFormats.LP
import MathOptInterface.FileFormats: LP

const LP_TEST_FILE = "test.lp"

function test_show()
Expand Down Expand Up @@ -464,7 +465,8 @@ function test_read_example_lo1()
@test (MOI.ScalarAffineFunction{Float64}, MOI.LessThan{Float64}) in
constraints
@test (MOI.VariableIndex, MOI.GreaterThan{Float64}) in constraints
@test (MOI.VariableIndex, MOI.Interval{Float64}) in constraints
@test (MOI.VariableIndex, MOI.LessThan{Float64}) in constraints
@test !((MOI.VariableIndex, MOI.Interval{Float64}) in constraints)
io = IOBuffer()
write(io, model)
seekstart(io)
Expand Down Expand Up @@ -525,7 +527,8 @@ function test_read_model1()
@test (MOI.ScalarAffineFunction{Float64}, MOI.LessThan{Float64}) in
constraints
@test (MOI.VariableIndex, MOI.GreaterThan{Float64}) in constraints
@test (MOI.VariableIndex, MOI.Interval{Float64}) in constraints
@test (MOI.VariableIndex, MOI.LessThan{Float64}) in constraints
@test !((MOI.VariableIndex, MOI.Interval{Float64}) in constraints)
@test (MOI.VariableIndex, MOI.Integer) in constraints
@test (MOI.VariableIndex, MOI.ZeroOne) in constraints
@test (MOI.VectorOfVariables, MOI.SOS1{Float64}) in constraints
Expand All @@ -543,9 +546,17 @@ function test_read_model2()
@test (MOI.ScalarAffineFunction{Float64}, MOI.LessThan{Float64}) in
constraints
@test (MOI.VariableIndex, MOI.GreaterThan{Float64}) in constraints
@test (MOI.VariableIndex, MOI.Interval{Float64}) in constraints
@test (MOI.VariableIndex, MOI.LessThan{Float64}) in constraints
@test !((MOI.VariableIndex, MOI.Interval{Float64}) in constraints)
@test (MOI.VariableIndex, MOI.Integer) in constraints
@test (MOI.VariableIndex, MOI.ZeroOne) in constraints
@test MOI.get(model, MOI.VariableName(), MOI.VariableIndex(2)) == "V5"
ci = MOI.ConstraintIndex{MOI.VariableIndex,MOI.LessThan{Float64}}(2)
@test MOI.get(model, MOI.ConstraintSet(), ci) == MOI.LessThan(1.0)
ci = MOI.ConstraintIndex{MOI.VariableIndex,MOI.GreaterThan{Float64}}(2)
@test MOI.get(model, MOI.ConstraintSet(), ci) == MOI.GreaterThan(0.0)
ci = MOI.ConstraintIndex{MOI.VariableIndex,MOI.Interval{Float64}}(2)
@test !MOI.is_valid(model, ci)
@test MOI.get(model, MOI.VariableName(), MOI.VariableIndex(8)) == "V8"
@test model.variables.lower[8] == -Inf
@test model.variables.upper[8] == -3
Expand Down
19 changes: 14 additions & 5 deletions test/FileFormats/MPS/MPS.jl
Original file line number Diff line number Diff line change
Expand Up @@ -170,7 +170,8 @@ function test_stacked_data()
con3: 1.0 * x in Interval(3.0, 7.0)
con4: 2.0 * x in Interval(4.0, 8.0)
y in Integer()
y in Interval(1.0, 4.0)
y >= 1.0
y <= 4.0
z in ZeroOne()
""",
)
Expand All @@ -182,7 +183,8 @@ function test_stacked_data()
["blank_obj", "con1", "con2", "con3", "con4"],
[
("y", MOI.Integer()),
("y", MOI.Interval{Float64}(1.0, 4.0)),
("y", MOI.GreaterThan{Float64}(1.0)),
("y", MOI.LessThan{Float64}(4.0)),
("z", MOI.ZeroOne()),
],
)
Expand All @@ -193,8 +195,13 @@ function test_integer_default_bounds()
model = MPS.Model()
MOI.read_from_file(model, joinpath(@__DIR__, "integer_default_bounds.mps"))
x = only(MOI.get(model, MOI.ListOfVariableIndices()))
ci =
MOI.ConstraintIndex{MOI.VariableIndex,MOI.GreaterThan{Float64}}(x.value)
@test MOI.get(model, MOI.ConstraintSet(), ci) == MOI.GreaterThan(0.0)
ci = MOI.ConstraintIndex{MOI.VariableIndex,MOI.LessThan{Float64}}(x.value)
@test MOI.get(model, MOI.ConstraintSet(), ci) == MOI.LessThan(1.0)
ci = MOI.ConstraintIndex{MOI.VariableIndex,MOI.Interval{Float64}}(x.value)
@test MOI.get(model, MOI.ConstraintSet(), ci) == MOI.Interval(0.0, 1.0)
@test !MOI.is_valid(model, ci)
return
end

Expand Down Expand Up @@ -482,7 +489,8 @@ function test_nonzero_variable_bounds()
x == 1.0
y >= 2.0
z <= 3.0
w in Interval(4.0, 5.0)
w >= 4.0
w <= 5.0
""",
)
io = IOBuffer()
Expand All @@ -499,7 +507,8 @@ function test_nonzero_variable_bounds()
("x", MOI.EqualTo{Float64}(1.0)),
("y", MOI.GreaterThan{Float64}(2.0)),
("z", MOI.LessThan{Float64}(3.0)),
("w", MOI.Interval{Float64}(4.0, 5.0)),
("w", MOI.GreaterThan{Float64}(4.0)),
("w", MOI.LessThan{Float64}(5.0)),
],
)
return
Expand Down
Loading