diff --git a/src/Test/test_objective.jl b/src/Test/test_objective.jl index fd22b1303d..c8a58f1fb4 100644 --- a/src/Test/test_objective.jl +++ b/src/Test/test_objective.jl @@ -45,6 +45,45 @@ function test_objective_ObjectiveSense_FEASIBILITY_SENSE( @test MOI.get(model, MOI.ObjectiveSense()) == MOI.FEASIBILITY_SENSE end +""" + test_objective_FEASIBILITY_SENSE_clears_objective( + model::MOI.ModelLike, + config::Config, + ) + +Test setting objective sense to FEASIBILITY_SENSE clears previous objective. +""" +function test_objective_FEASIBILITY_SENSE_clears_objective( + model::MOI.ModelLike, + config::Config, +) + @requires _supports(config, MOI.optimize!) + x = MOI.add_variable(model) + MOI.add_constraint(model, MOI.SingleVariable(x), MOI.GreaterThan(1.0)) + MOI.set(model, MOI.ObjectiveSense(), MOI.MIN_SENSE) + f = MOI.ScalarAffineFunction([MOI.ScalarAffineTerm(1.0, x)], 0.0) + MOI.set(model, MOI.ObjectiveFunction{typeof(f)}(), f) + MOI.optimize!(model) + @test MOI.get(model, MOI.ObjectiveValue()) == 1.0 + MOI.set(model, MOI.ObjectiveSense(), MOI.FEASIBILITY_SENSE) + MOI.optimize!(model) + @test MOI.get(model, MOI.ObjectiveValue()) == 0.0 + return +end + +function setup_test( + ::typeof(test_objective_FEASIBILITY_SENSE_clears_objective), + model::MOIU.MockOptimizer, + ::Config, +) + MOIU.set_mock_optimize!( + model, + (mock::MOIU.MockOptimizer) -> + MOIU.mock_optimize!(mock, MOI.OPTIMAL, (MOI.FEASIBLE_POINT, [1])), + ) + return +end + """ test_objective_get_ObjectiveFunction_ScalarAffineFunction( model::MOI.ModelLike, diff --git a/src/Test/test_solve.jl b/src/Test/test_solve.jl index ae846ed52e..0c55283487 100644 --- a/src/Test/test_solve.jl +++ b/src/Test/test_solve.jl @@ -1446,3 +1446,120 @@ function setup_test( ) return end + +function test_solve_SOS2_add_and_delete(model::MOI.ModelLike, config::Config) + @requires _supports(config, MOI.optimize!) + @requires MOI.supports_constraint( + model, + MOI.VectorOfVariables, + MOI.SOS2{Float64}, + ) + function add_SOS2(x, y, xp, yp) + λ = MOI.add_variables(model, length(xp)) + # 0 <= λ <= 1 + MOI.add_constraint.(model, MOI.SingleVariable.(λ), MOI.LessThan(1.0)) + MOI.add_constraint.(model, MOI.SingleVariable.(λ), MOI.GreaterThan(0.0)) + # Σλᵢ == 1 + MOI.add_constraint( + model, + MOI.ScalarAffineFunction(MOI.ScalarAffineTerm.(1.0, λ), 0.0), + MOI.EqualTo(1.0), + ) + # Σλᵢxᵢ - x == 0 + MOI.add_constraint( + model, + MOI.ScalarAffineFunction( + MOI.ScalarAffineTerm.([xp; -1.0], [λ; x]), + 0.0, + ), + MOI.EqualTo(0.0), + ) + # Σλᵢyᵢ - y == 0 + MOI.add_constraint( + model, + MOI.ScalarAffineFunction( + MOI.ScalarAffineTerm.([yp; -1.0], [λ; y]), + 0.0, + ), + MOI.EqualTo(0.0), + ) + # λ ∈ SOS2() + c = MOI.add_constraint( + model, + MOI.VectorOfVariables(λ), + MOI.SOS2{Float64}(collect(1.0:length(xp))), + ) + return λ, c + end + x = MOI.add_variables(model, 2) + y = MOI.add_variables(model, 2) + λ, c1 = add_SOS2(x[1], y[1], [1.0, 2.0, 3.0], [2.0, 2.0, 1.0]) + MOI.add_constraint(model, MOI.SingleVariable(x[1]), MOI.LessThan(2.5)) + η, c2 = add_SOS2(x[2], y[2], [1.0, 2.0, 3.0, 4.0], [0.5, 1.0, 0.2, 2.0]) + MOI.set(model, MOI.ObjectiveSense(), MOI.MIN_SENSE) + f = MOI.ScalarAffineFunction(MOI.ScalarAffineTerm.(1.0, y), 0.0) + MOI.set(model, MOI.ObjectiveFunction{typeof(f)}(), f) + attr = MOI.NumberOfConstraints{MOI.VectorOfVariables,MOI.SOS2{Float64}}() + @test MOI.get(model, attr) == 2 + MOI.optimize!(model) + # x[1] == 2.5 + # y[1] == 1.5 + # x[2] == 3.0 + # y[2] == 0.2 + @test isapprox(MOI.get(model, MOI.VariablePrimal(), x[1]), 2.5, config) + @test isapprox(MOI.get(model, MOI.VariablePrimal(), x[2]), 3.0, config) + @test isapprox(MOI.get(model, MOI.VariablePrimal(), y[1]), 1.5, config) + @test isapprox(MOI.get(model, MOI.VariablePrimal(), y[2]), 0.2, config) + @test isapprox(MOI.get(model, MOI.ObjectiveValue()), 1.7, config) + MOI.delete(model, c1) + MOI.delete(model, c2) + @test MOI.get(model, attr) == 0 + MOI.optimize!(model) + @test isapprox(MOI.get(model, MOI.VariablePrimal(), x[1]), 2.5, config) + @test isapprox(MOI.get(model, MOI.VariablePrimal(), x[2]), 3.0, config) + @test isapprox(MOI.get(model, MOI.VariablePrimal(), y[1]), 1.25, config) + @test isapprox(MOI.get(model, MOI.VariablePrimal(), y[2]), 0.2, config) + @test isapprox(MOI.get(model, MOI.ObjectiveValue()), 1.45, config) + MOI.add_constraint( + model, + MOI.VectorOfVariables(λ), + MOI.SOS2{Float64}([1.0, 2.0, 3.0]), + ) + MOI.add_constraint( + model, + MOI.VectorOfVariables(λ), + MOI.SOS2{Float64}([1.0, 2.0, 3.0, 4.0]), + ) + @test MOI.get(model, attr) == 2 + MOI.optimize!(model) + @test isapprox(MOI.get(model, MOI.VariablePrimal(), x[1]), 2.5, config) + @test isapprox(MOI.get(model, MOI.VariablePrimal(), x[2]), 3.0, config) + @test isapprox(MOI.get(model, MOI.ObjectiveValue()), 1.7, config) + return +end + +function setup_test( + ::typeof(test_solve_SOS2_add_and_delete), + model::MOIU.MockOptimizer, + ::Config, +) + MOIU.set_mock_optimize!( + model, + (mock::MOIU.MockOptimizer) -> MOIU.mock_optimize!( + mock, + MOI.OPTIMAL, + [2.5, 3.0, 1.5, 0.2, 0.0, 0.5, 0.5, 0.0, 0.0, 1.0, 0.0], + ), + (mock::MOIU.MockOptimizer) -> MOIU.mock_optimize!( + mock, + MOI.OPTIMAL, + [2.5, 3.0, 1.25, 0.2, 0.25, 0.0, 0.75, 0.0, 0.0, 1.0, 0.0], + ), + (mock::MOIU.MockOptimizer) -> MOIU.mock_optimize!( + mock, + MOI.OPTIMAL, + [2.5, 3.0, 1.5, 0.2, 0.0, 0.5, 0.5, 0.0, 0.0, 1.0, 0.0], + ), + ) + return +end