From a2c3c5d850e27a787542d3c561ec11f3492f39fa Mon Sep 17 00:00:00 2001 From: Guillaume Marques Date: Fri, 29 Jan 2021 13:30:40 +0100 Subject: [PATCH 1/4] tests cases with infinite bounds --- src/Test/UnitTests/constraints.jl | 99 +++++++++++++++++++++++++++++++ test/Test/unit.jl | 2 + 2 files changed, 101 insertions(+) diff --git a/src/Test/UnitTests/constraints.jl b/src/Test/UnitTests/constraints.jl index 17e06a0e7e..6cb3da7956 100644 --- a/src/Test/UnitTests/constraints.jl +++ b/src/Test/UnitTests/constraints.jl @@ -514,3 +514,102 @@ function solve_zero_one_with_bounds_3(model::MOI.ModelLike, config::TestConfig) end end unittests["solve_zero_one_with_bounds_3"] = solve_zero_one_with_bounds_3 + +function solve_constrs_with_inf_bounds(model::MOI.ModelLike, config::TestConfig) + MOI.empty!(model) + x = MOI.add_variable(model) + y = MOI.add_variable(model) + objective_function = MOI.ScalarAffineFunction( + [MOI.ScalarAffineTerm(1.0, x), MOI.ScalarAffineTerm(-1.0, y)], + 0.0 + ) + MOI.set( + model, + MOI.ObjectiveFunction{typeof(objective_function)}(), + objective_function, + ) + MOI.set(model, MOI.ObjectiveSense(), MOI.MAX_SENSE) + + c1 = MOI.add_constraint( + model, + MOI.SingleVariable(x), + MOI.LessThan{Float64}(1.0) + ) + c2 = MOI.add_constraint( + model, + MOI.SingleVariable(x), + MOI.GreaterThan{Float64}(-Inf) + ) + c3 = MOI.add_constraint( + model, + MOI.SingleVariable(y), + MOI.LessThan{Float64}(Inf) + ) + c4 = MOI.add_constraint( + model, + MOI.SingleVariable(y), + MOI.GreaterThan{Float64}(-1.0) + ) + + @test MOI.is_valid(model, c2) + @test MOI.is_valid(model, c3) + + return test_model_solution( + model, + config; + objective_value = 2.0, + variable_primal = [(x, 1.0), (y, -1.0)], + ) +end +unittests["solve_constrs_with_inf_bounds"] = solve_constrs_with_inf_bounds + +function solve_one_sided_intervals(model::MOI.ModelLike, config::TestConfig) + MOI.empty!(model) + MOIU.loadfromstring!( + model, + """ + variables: x, y, z + maxobjective: x + -1y + z + c1: x in Interval(-Inf, 1.0) + c2: y in Interval(-1.0, Inf) + c3: z in Interval(-Inf, Inf) + c4: 1z <= 1.0 +""", + ) + + x = MOI.get(model, MOI.VariableIndex, "x") + y = MOI.get(model, MOI.VariableIndex, "y") + z = MOI.get(model, MOI.VariableIndex, "z") + + c1 = MOI.get( + model, + MOI.ConstraintIndex{MOI.SingleVariable, MOI.Interval{Float64}}, + "c1" + ) + c2 = MOI.get( + model, + MOI.ConstraintIndex{MOI.SingleVariable, MOI.Interval{Float64}}, + "c2" + ) + c3 = MOI.get( + model, + MOI.ConstraintIndex{MOI.SingleVariable, MOI.Interval{Float64}}, + "c3" + ) + + @test MOI.get(model, MOI.ConstraintIndex, "c1") == c1 + @test MOI.get(model, MOI.ConstraintIndex, "c2") == c2 + @test MOI.get(model, MOI.ConstraintIndex, "c3") == c3 + + @test MOI.is_valid(model, c1) + @test MOI.is_valid(model, c2) + @test MOI.is_valid(model, c3) + + return test_model_solution( + model, + config; + objective_value = 3.0, + variable_primal = [(x, 1.0), (y, -1.0), (z, 1.0)], + ) +end +unittests["solve_one_sided_intervals"] = solve_one_sided_intervals \ No newline at end of file diff --git a/test/Test/unit.jl b/test/Test/unit.jl index 8cfe461be3..caa58fbf19 100644 --- a/test/Test/unit.jl +++ b/test/Test/unit.jl @@ -45,6 +45,8 @@ end "solve_zero_one_with_bounds_1", "solve_zero_one_with_bounds_2", "solve_zero_one_with_bounds_3", + "solve_constrs_with_inf_bounds", + "solve_one_sided_intervals", "solve_unbounded_model", "solve_single_variable_dual_min", "solve_single_variable_dual_max", From 83d951013e4cd134abe2da9caea659ffb5b1f2e1 Mon Sep 17 00:00:00 2001 From: Guillaume Marques Date: Fri, 29 Jan 2021 21:34:29 +0100 Subject: [PATCH 2/4] add test for the test --- test/Test/unit.jl | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) diff --git a/test/Test/unit.jl b/test/Test/unit.jl index caa58fbf19..abe5e501a6 100644 --- a/test/Test/unit.jl +++ b/test/Test/unit.jl @@ -348,6 +348,23 @@ end MOIT.solve_zero_one_with_bounds_3(mock, config) end + @testset "solve_constrs_inf_bounds" begin + MOIU.set_mock_optimize!(mock, + (mock::MOIU.MockOptimizer) -> begin + MOIU.mock_optimize!( + mock, MOI.OPTIMAL, (MOI.FEASIBLE_POINT, [1.0, -1.0]) + ) + end, + (mock::MOIU.MockOptimizer) -> begin + MOIU.mock_optimize!( + mock, MOI.OPTIMAL, (MOI.FEASIBLE_POINT, [1.0, -1.0, 1.0]) + ) + end + ) + MOIT.solve_constrs_with_inf_bounds(mock, config) + MOIT.solve_one_sided_intervals(mock, config) + end + @testset "solve_unbounded_model" begin MOIU.set_mock_optimize!(mock, (mock::MOIU.MockOptimizer) -> begin From d67d58be456bbc82d060f9c3c2d2ad73c69dee2e Mon Sep 17 00:00:00 2001 From: Guillaume Marques Date: Mon, 22 Mar 2021 16:27:39 +0100 Subject: [PATCH 3/4] remove tests for LessThan(Inf) and GreaterThan(Inf) --- src/Test/UnitTests/constraints.jl | 48 ------------------------------- test/Test/unit.jl | 4 +-- 2 files changed, 1 insertion(+), 51 deletions(-) diff --git a/src/Test/UnitTests/constraints.jl b/src/Test/UnitTests/constraints.jl index 6cb3da7956..4c9f6efc23 100644 --- a/src/Test/UnitTests/constraints.jl +++ b/src/Test/UnitTests/constraints.jl @@ -515,54 +515,6 @@ function solve_zero_one_with_bounds_3(model::MOI.ModelLike, config::TestConfig) end unittests["solve_zero_one_with_bounds_3"] = solve_zero_one_with_bounds_3 -function solve_constrs_with_inf_bounds(model::MOI.ModelLike, config::TestConfig) - MOI.empty!(model) - x = MOI.add_variable(model) - y = MOI.add_variable(model) - objective_function = MOI.ScalarAffineFunction( - [MOI.ScalarAffineTerm(1.0, x), MOI.ScalarAffineTerm(-1.0, y)], - 0.0 - ) - MOI.set( - model, - MOI.ObjectiveFunction{typeof(objective_function)}(), - objective_function, - ) - MOI.set(model, MOI.ObjectiveSense(), MOI.MAX_SENSE) - - c1 = MOI.add_constraint( - model, - MOI.SingleVariable(x), - MOI.LessThan{Float64}(1.0) - ) - c2 = MOI.add_constraint( - model, - MOI.SingleVariable(x), - MOI.GreaterThan{Float64}(-Inf) - ) - c3 = MOI.add_constraint( - model, - MOI.SingleVariable(y), - MOI.LessThan{Float64}(Inf) - ) - c4 = MOI.add_constraint( - model, - MOI.SingleVariable(y), - MOI.GreaterThan{Float64}(-1.0) - ) - - @test MOI.is_valid(model, c2) - @test MOI.is_valid(model, c3) - - return test_model_solution( - model, - config; - objective_value = 2.0, - variable_primal = [(x, 1.0), (y, -1.0)], - ) -end -unittests["solve_constrs_with_inf_bounds"] = solve_constrs_with_inf_bounds - function solve_one_sided_intervals(model::MOI.ModelLike, config::TestConfig) MOI.empty!(model) MOIU.loadfromstring!( diff --git a/test/Test/unit.jl b/test/Test/unit.jl index abe5e501a6..e73bf0dd13 100644 --- a/test/Test/unit.jl +++ b/test/Test/unit.jl @@ -45,7 +45,6 @@ end "solve_zero_one_with_bounds_1", "solve_zero_one_with_bounds_2", "solve_zero_one_with_bounds_3", - "solve_constrs_with_inf_bounds", "solve_one_sided_intervals", "solve_unbounded_model", "solve_single_variable_dual_min", @@ -348,7 +347,7 @@ end MOIT.solve_zero_one_with_bounds_3(mock, config) end - @testset "solve_constrs_inf_bounds" begin + @testset "solve_one_sided_intervals" begin MOIU.set_mock_optimize!(mock, (mock::MOIU.MockOptimizer) -> begin MOIU.mock_optimize!( @@ -361,7 +360,6 @@ end ) end ) - MOIT.solve_constrs_with_inf_bounds(mock, config) MOIT.solve_one_sided_intervals(mock, config) end From cc1814d8d02d6708a307e4e12abcf81f379d2373 Mon Sep 17 00:00:00 2001 From: Guillaume Marques Date: Mon, 22 Mar 2021 20:38:33 +0100 Subject: [PATCH 4/4] wip --- src/Bridges/Constraint/interval.jl | 32 ++++++++++++++++++++-- src/sets.jl | 10 +++++++ test/Bridges/Constraint/interval.jl | 41 +++++++++++++++++++++++++++++ 3 files changed, 81 insertions(+), 2 deletions(-) diff --git a/src/Bridges/Constraint/interval.jl b/src/Bridges/Constraint/interval.jl index 29e99313f4..d6a7a82c0c 100644 --- a/src/Bridges/Constraint/interval.jl +++ b/src/Bridges/Constraint/interval.jl @@ -1,5 +1,5 @@ -_lower_set(set::MOI.Interval) = MOI.GreaterThan(set.lower) -_upper_set(set::MOI.Interval) = MOI.LessThan(set.upper) +_lower_set(set::MOI.Interval) = isinf(set.lower) ? MOI.ExtendedGreaterThan(set.lower) : MOI.GreaterThan(set.lower) +_upper_set(set::MOI.Interval) = isinf(set.upper) ? MOI.ExtendedLessThan(set.upper) : MOI.LessThan(set.upper) _lower_set(set::MOI.EqualTo) = MOI.GreaterThan(set.value) _upper_set(set::MOI.EqualTo) = MOI.LessThan(set.value) _lower_set(set::MOI.Zeros) = MOI.Nonnegatives(set.dimension) @@ -267,3 +267,31 @@ function MOI.get( ) where {T,F} return MOI.Zeros(MOI.get(model, attr, bridge.lower).dimension) end + + +# guimarqu : new bridge (to improve) +""" + UnextendBridge + +Bridge for ExtendedGreatherThan to GreaterThan ... +""" +struct UnextendBridge{ + T, + F<:MOI.AbstractFunction, + ES<:MOI.AbstractSet, + S<:MOI.AbstractSet +} <: AbstractBridge + non_extended::Union{Nothing, CI{F,S}} +end + +function bridge_constraint( + ::Type{UnextendBridge{T,F,ES,S}}, + model::MOI.ModelLike, + f::F, + set::S, +) where {T,F,ES,S} + if isinf(set.value) + return UnextendBridge{T,F,ES,S}(nothing) + end + return UnextendBridge{T,F,ES,S}(MOI.GreaterThan(3)) +end diff --git a/src/sets.jl b/src/sets.jl index 2b8772d500..ba935365c7 100644 --- a/src/sets.jl +++ b/src/sets.jl @@ -162,6 +162,11 @@ struct GreaterThan{T<:Real} <: AbstractScalarSet lower::T end +# guimarqu +struct ExtendedGreaterThan{T<:Real} <: AbstractScalarSet + lower::T +end + """ LessThan{T <: Real}(upper::T) @@ -171,6 +176,11 @@ struct LessThan{T<:Real} <: AbstractScalarSet upper::T end +# guimarqu +struct ExtendedLessThan{T<:Real} <: AbstractScalarSet + lower::T +end + """ EqualTo{T <: Number}(value::T) diff --git a/test/Bridges/Constraint/interval.jl b/test/Bridges/Constraint/interval.jl index 2635522e9a..d444efe91e 100644 --- a/test/Bridges/Constraint/interval.jl +++ b/test/Bridges/Constraint/interval.jl @@ -12,6 +12,7 @@ mock = MOIU.MockOptimizer(MOIU.UniversalFallback(MOIU.Model{Float64}())) config = MOIT.TestConfig() config_with_basis = MOIT.TestConfig(basis = true) + @testset "Split" begin T = Float64 bridged_mock = MOIB.Constraint.SplitInterval{T}(mock) @@ -32,6 +33,46 @@ config_with_basis = MOIT.TestConfig(basis = true) ) end +@testset "my test" begin + bridged_mock = MOIB.Constraint.SplitInterval{Float64}(mock) + + MOIU.set_mock_optimize!( + mock, + (mock::MOIU.MockOptimizer) -> MOIU.mock_optimize!( + mock, + [1.0, -1.0, 1.0], + ), + ) + + # variables: x, y, z + # maxobjective: x + -1y + z + # c1: x in Interval(-Inf, 1.0) + # c2: y in Interval(-1.0, Inf) + # c3: z in Interval(-Inf, Inf) + # c4: 1z <= 1.0 + MOIT.solve_one_sided_intervals(bridged_mock, config_with_basis) + + println("====== ****** ======") + for (i, b) in bridged_mock.map.single_variable_constraints + @show MOI.get(bridged_mock.model, MOI.ConstraintSet(), b.lower) + @show MOI.get(bridged_mock.model, MOI.ConstraintSet(), b.upper) + end + + println("====== ****** ======") + + @show MOI.get( + bridged_mock, + MOI.ListOfConstraintIndices{ + MOI.SingleVariable, + MOI.Interval{Float64}, + }(), + ) + + + +end +exit() + @testset "Interval" begin bridged_mock = MOIB.Constraint.SplitInterval{Float64}(mock) MOIU.set_mock_optimize!(