From 7ae2e244058b0a04a473258161d245d68de696d2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Beno=C3=AEt=20Legat?= Date: Thu, 30 May 2019 18:50:32 +0200 Subject: [PATCH] Remove variables instead of substracting it --- src/Bridges/slackbridge.jl | 6 ++---- src/Test/UnitTests/basic_constraint_tests.jl | 19 ++++++++++++++++++- src/Utilities/functions.jl | 9 +++++---- test/Bridges/slackbridge.jl | 5 +++-- 4 files changed, 28 insertions(+), 11 deletions(-) diff --git a/src/Bridges/slackbridge.jl b/src/Bridges/slackbridge.jl index d0989001e5..dab1112694 100644 --- a/src/Bridges/slackbridge.jl +++ b/src/Bridges/slackbridge.jl @@ -93,8 +93,7 @@ end function MOI.get(model::MOI.ModelLike, attr::MOI.ConstraintFunction, b::ScalarSlackBridge{T}) where T - return MOIU.operate(+, T, MOI.get(model, attr, b.equality), - MOI.SingleVariable(b.slack)) + return MOIU.removevariable(MOI.get(model, attr, b.equality), b.slack) end function MOI.get(model::MOI.ModelLike, attr::MOI.ConstraintSet, b::ScalarSlackBridge) @@ -192,8 +191,7 @@ end function MOI.get(model::MOI.ModelLike, attr::MOI.ConstraintFunction, b::VectorSlackBridge{T}) where T - return MOIU.operate(+, T, MOI.get(model, attr, b.equality), - MOI.VectorOfVariables(b.slacks)) + return MOIU.removevariable(MOI.get(model, attr, b.equality), b.slacks) end function MOI.get(model::MOI.ModelLike, attr::MOI.ConstraintSet, b::VectorSlackBridge) diff --git a/src/Test/UnitTests/basic_constraint_tests.jl b/src/Test/UnitTests/basic_constraint_tests.jl index 10ef380c2f..6eb21ad003 100644 --- a/src/Test/UnitTests/basic_constraint_tests.jl +++ b/src/Test/UnitTests/basic_constraint_tests.jl @@ -135,6 +135,21 @@ function basic_constraint_tests(model::MOI.ModelLike, config::TestConfig; end end +variables(func::MOI.SingleVariable) = func.variable +variables(func::MOI.VectorOfVariables) = func.variables +variables(func::MOI.ScalarAffineFunction) = Set(term.variable_index for term in func.terms) +variables(func::MOI.VectorAffineFunction) = Set(term.scalar_term.variable_index for term in func.terms) +function variables(func::MOI.ScalarQuadraticFunction) + return Set(term.variable_index for term in func.affine_terms) ∪ + Set(term.variable_index_1 for term in func.quadratic_terms) + Set(term.variable_index_2 for term in func.quadratic_terms) +end +function variables(func::MOI.VectorQuadraticFunction) + return Set(term.scalar_term.variable_index for term in func.affine_terms) ∪ + Set(term.scalar_term.variable_index_1 for term in func.quadratic_terms) + Set(term.scalar_term.variable_index_2 for term in func.quadratic_terms) +end + """ basic_constraint_test_helper(model::MOI.ModelLike, config::TestConfig, func::Function, set::MOI.AbstractSet, N::Int; delete::Bool = true, @@ -188,7 +203,9 @@ function basic_constraint_test_helper(model::MOI.ModelLike, config::TestConfig, if get_constraint_function @testset "ConstraintFunction" begin - @test MOI.get(model, MOI.ConstraintFunction(), c) ≈ constraint_function + func = MOI.get(model, MOI.ConstraintFunction(), c) + @test func ≈ constraint_function + @test variables(func) == variables(constraint_function) end end if get_constraint_set diff --git a/src/Utilities/functions.jl b/src/Utilities/functions.jl index b879c0730f..084434d83d 100644 --- a/src/Utilities/functions.jl +++ b/src/Utilities/functions.jl @@ -449,12 +449,13 @@ function test_models_equal(model1::MOI.ModelLike, model2::MOI.ModelLike, variabl end +_hasvar(v::VI, vi::Vector{VI}) = v in vi _hasvar(v::VI, vi::VI) = v == vi -_hasvar(t::MOI.ScalarAffineTerm, vi::VI) = t.variable_index == vi -_hasvar(t::MOI.ScalarQuadraticTerm, vi::VI) = t.variable_index_1 == vi || t.variable_index_2 == vi -_hasvar(t::Union{MOI.VectorAffineTerm, MOI.VectorQuadraticTerm}, vi::VI) = _hasvar(t.scalar_term, vi) +_hasvar(t::MOI.ScalarAffineTerm, vi) = _hasvar(t.variable_index, vi) +_hasvar(t::MOI.ScalarQuadraticTerm, vi) = _hasvar(t.variable_index_1, vi) || _hasvar(t.variable_index_2, vi) +_hasvar(t::Union{MOI.VectorAffineTerm, MOI.VectorQuadraticTerm}, vi) = _hasvar(t.scalar_term, vi) # Removes terms or variables in `vis_or_terms` that contains the variable of index `vi` -function _rmvar(vis_or_terms::Vector, vi::VI) +function _rmvar(vis_or_terms::Vector, vi) return vis_or_terms[.!_hasvar.(vis_or_terms, Ref(vi))] end diff --git a/test/Bridges/slackbridge.jl b/test/Bridges/slackbridge.jl index 2f4ea0c136..b0ad714f1c 100644 --- a/test/Bridges/slackbridge.jl +++ b/test/Bridges/slackbridge.jl @@ -16,6 +16,7 @@ config = MOIT.TestConfig() @testset "Scalar slack" begin MOI.empty!(mock) bridged_mock = MOIB.ScalarSlack{Float64}(mock) + x = MOI.add_variable(bridged_mock) y = MOI.add_variable(bridged_mock) f = MOI.ScalarAffineFunction(MOI.ScalarAffineTerm{Float64}.([1.0, 2.0], [x, y]), 0.0) @@ -37,8 +38,7 @@ config = MOIT.TestConfig() F in [MOI.ScalarAffineFunction{Float64}, MOI.ScalarQuadraticFunction{Float64}], S in [MOI.GreaterThan{Float64}, - MOI.LessThan{Float64}] - ]) + MOI.LessThan{Float64}]]) # There are extra variables due to the bridge MOIU.set_mock_optimize!(mock, @@ -88,6 +88,7 @@ end @testset "Vector slack" begin MOI.empty!(mock) bridged_mock = MOIB.VectorSlack{Float64}(mock) + x = MOI.add_variable(bridged_mock) y = MOI.add_variable(bridged_mock) f = MOI.VectorAffineFunction(MOI.VectorAffineTerm.(1, MOI.ScalarAffineTerm.([1.0, 2.0], [x, y])), [0.0])