diff --git a/src/algorithms/KirlikSayin.jl b/src/algorithms/KirlikSayin.jl index 0fb3e4b..369d0a8 100644 --- a/src/algorithms/KirlikSayin.jl +++ b/src/algorithms/KirlikSayin.jl @@ -146,6 +146,8 @@ function minimize_multiobjective!(algorithm::KirlikSayin, model::Optimizer) end optimize_inner!(model) if !_is_scalar_status_optimal(model) + # If this fails, it likely means that the solver experienced a + # numerical error with this box. Just skip it. _remove_rectangle(L, _Rectangle(_project(yI, k), uᵢ)) MOI.delete.(model, ε_constraints) continue @@ -163,6 +165,8 @@ function minimize_multiobjective!(algorithm::KirlikSayin, model::Optimizer) ) optimize_inner!(model) if !_is_scalar_status_optimal(model) + # If this fails, it likely means that the solver experienced a + # numerical error with this box. Just skip it. MOI.delete.(model, ε_constraints) MOI.delete(model, zₖ_constraint) _remove_rectangle(L, _Rectangle(_project(yI, k), uᵢ)) diff --git a/test/algorithms/Dichotomy.jl b/test/algorithms/Dichotomy.jl index 6e0a1b7..2fa8d07 100644 --- a/test/algorithms/Dichotomy.jl +++ b/test/algorithms/Dichotomy.jl @@ -440,6 +440,24 @@ function test_solve_failures() return end +function test_scalar_time_limit() + model = MOA.Optimizer(HiGHS.Optimizer) + MOI.set(model, MOA.Algorithm(), MOA.Dichotomy()) + MOI.set(model, MOI.Silent(), true) + MOI.set(model, MOI.TimeLimitSec(), 0.0) + MOI.Utilities.loadfromstring!( + model, + """ + variables: x + minobjective: [2 * x] + x >= 0.0 + """, + ) + MOI.optimize!(model) + @test MOI.get(model, MOI.TerminationStatus()) == MOI.TIME_LIMIT + return +end + end # module TestDichotomy TestDichotomy.run_tests() diff --git a/test/algorithms/KirlikSayin.jl b/test/algorithms/KirlikSayin.jl index 29242e7..1d7f521 100644 --- a/test/algorithms/KirlikSayin.jl +++ b/test/algorithms/KirlikSayin.jl @@ -11,6 +11,7 @@ import HiGHS import MultiObjectiveAlgorithms as MOA import MultiObjectiveAlgorithms: MOI +include(joinpath(dirname(@__DIR__), "mock_optimizer.jl")) include(joinpath(dirname(@__DIR__), "problems.jl")) include(joinpath(dirname(@__DIR__), "vOptLib.jl")) @@ -146,6 +147,36 @@ function test_vector_of_variables_objective() return end +function test_solve_failures() + m, n = 2, 10 + p1 = [5.0 1 10 8 3 5 3 3 7 2; 10 6 1 6 8 3 2 10 6 1] + p2 = [4.0 6 4 3 1 6 8 2 9 7; 8 8 8 2 4 8 8 1 10 1] + w = [5.0 9 3 5 10 5 7 10 7 8; 4 8 8 6 10 8 10 7 5 1] + b = [34.0, 33.0] + for fail_after in 0:5 + model = MOA.Optimizer(mock_optimizer(fail_after)) + MOI.set(model, MOA.Algorithm(), MOA.KirlikSayin()) + x_ = MOI.add_variables(model, m * n) + x = reshape(x_, m, n) + MOI.add_constraint.(model, x, MOI.Interval(0.0, 1.0)) + f = MOI.Utilities.operate(vcat, Float64, sum(p1 .* x), sum(p2 .* x)) + MOI.set(model, MOI.ObjectiveSense(), MOI.MAX_SENSE) + MOI.set(model, MOI.ObjectiveFunction{typeof(f)}(), f) + for i in 1:m + f_i = sum(w[i, j] * x[i, j] for j in 1:n) + MOI.add_constraint(model, f_i, MOI.LessThan(b[i])) + end + for j in 1:n + MOI.add_constraint(model, sum(1.0 .* x[:, j]), MOI.EqualTo(1.0)) + end + MOI.optimize!(model) + @test MOI.get(model, MOI.TerminationStatus()) == + (fail_after <= 3 ? MOI.NUMERICAL_ERROR : MOI.OPTIMAL) + @test MOI.get(model, MOI.ResultCount()) == 0 + end + return +end + end # TestKirlikSayin TestKirlikSayin.run_tests()