From ee2feee60550d9ad44d9d7f1c62ab5842500c3ae Mon Sep 17 00:00:00 2001 From: odow Date: Fri, 8 Aug 2025 08:49:30 +1200 Subject: [PATCH 1/5] Fix floating point comparison in TambyVanderpooten --- src/algorithms/TambyVanderpooten.jl | 8 ++++---- test/problems.jl | 27 +++++++++++++++++++++++++++ 2 files changed, 31 insertions(+), 4 deletions(-) diff --git a/src/algorithms/TambyVanderpooten.jl b/src/algorithms/TambyVanderpooten.jl index fb3273a..9378880 100644 --- a/src/algorithms/TambyVanderpooten.jl +++ b/src/algorithms/TambyVanderpooten.jl @@ -187,12 +187,12 @@ function minimize_multiobjective!( bounds_to_remove = Vector{Float64}[] for u_i in keys(U_N) for k in 1:n - if u_i[k] == yI[k] + if isapprox(u_i[k], yI[k]; atol = 1e-6) push!(bounds_to_remove, u_i) else for (u_j, y_j) in V[k] if all(_project(u_i, k) .<= _project(u_j, k)) && - (y_j[k] == u_i[k]) + isapprox(y_j[k], u_i[k]; atol = 1e-6) push!(bounds_to_remove, u_i) end end @@ -205,6 +205,6 @@ function minimize_multiobjective!( end end end - solutions = [SolutionPoint(X, Y) for (Y, X) in solutions] - return status, solutions + solutions_vec = [SolutionPoint(X, Y) for (Y, X) in solutions] + return status, filter_nondominated(MOI.MIN_SENSE, solutions_vec) end diff --git a/test/problems.jl b/test/problems.jl index 146cbd1..e8924fb 100644 --- a/test/problems.jl +++ b/test/problems.jl @@ -472,4 +472,31 @@ function test_issue_122(model) return end +function test_issue_133() + #!format: off + p = Float64[ + 33 90 96 75 1 69 100 50 63 61 59 95 58 10 77 30 86 89 82 51 38 33 73 54 91 89 95 82 48 67 + 55 36 80 58 20 96 75 57 24 68 37 58 8 85 27 25 71 53 47 72 57 64 1 8 12 68 3 80 20 90 + 22 40 50 73 44 65 12 26 13 77 14 68 71 35 54 98 45 95 98 19 18 38 14 51 37 48 35 97 95 36 + ] + w = Float64[ + 22, 13, 10, 25, 4, 15, 17, 15, 15, 28, 14, 13, 2, 23, 6, 22, 18, 6, 23, + 21, 7, 7, 14, 4, 3, 27, 10, 5, 9, 10 + ] + #!format: on + model = MOA.Optimizer(HiGHS.Optimizer) + MOI.set(model, MOA.Algorithm(), MOA.TambyVanderpooten()) + MOI.set(model, MOI.Silent(), true) + x = MOI.add_variables(model, length(w)) + MOI.add_constraint.(model, x, MOI.ZeroOne()) + MOI.set(model, MOI.ObjectiveSense(), MOI.MAX_SENSE) + f = MOI.Utilities.vectorize(p * x) + MOI.set(model, MOI.ObjectiveFunction{typeof(f)}(), f) + MOI.add_constraint(model, w' * x, MOI.LessThan(204.0)) + MOI.optimize!(model) + @test MOI.get(model, MOI.TerminationStatus()) == MOI.OPTIMAL + @test MOI.get(model, MOI.ResultCount()) == 95 + return +end + end # module Problems From 012cf80ef44cefcd561f6ec84cff8ccc53f0f5b9 Mon Sep 17 00:00:00 2001 From: odow Date: Fri, 8 Aug 2025 09:42:50 +1200 Subject: [PATCH 2/5] Update --- test/problems.jl | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/test/problems.jl b/test/problems.jl index e8924fb..192afe0 100644 --- a/test/problems.jl +++ b/test/problems.jl @@ -472,7 +472,7 @@ function test_issue_122(model) return end -function test_issue_133() +function test_issue_133(model) #!format: off p = Float64[ 33 90 96 75 1 69 100 50 63 61 59 95 58 10 77 30 86 89 82 51 38 33 73 54 91 89 95 82 48 67 @@ -484,9 +484,6 @@ function test_issue_133() 21, 7, 7, 14, 4, 3, 27, 10, 5, 9, 10 ] #!format: on - model = MOA.Optimizer(HiGHS.Optimizer) - MOI.set(model, MOA.Algorithm(), MOA.TambyVanderpooten()) - MOI.set(model, MOI.Silent(), true) x = MOI.add_variables(model, length(w)) MOI.add_constraint.(model, x, MOI.ZeroOne()) MOI.set(model, MOI.ObjectiveSense(), MOI.MAX_SENSE) From 1fcaa22d4321556883f1297598480df2e79ba070 Mon Sep 17 00:00:00 2001 From: odow Date: Fri, 8 Aug 2025 10:12:12 +1200 Subject: [PATCH 3/5] Update --- src/algorithms/KirlikSayin.jl | 4 +++- src/algorithms/TambyVanderpooten.jl | 7 ++++--- 2 files changed, 7 insertions(+), 4 deletions(-) diff --git a/src/algorithms/KirlikSayin.jl b/src/algorithms/KirlikSayin.jl index add1ac4..ec58322 100644 --- a/src/algorithms/KirlikSayin.jl +++ b/src/algorithms/KirlikSayin.jl @@ -169,7 +169,9 @@ function minimize_multiobjective!(algorithm::KirlikSayin, model::Optimizer) end X, Y = _compute_point(model, variables, model.f) Y_proj = _project(Y, k) - if !(Y in YN) + # We want `if !(Y in YN)` but this tests exact equality. We want + # an approximate comparison. + if all(!isapprox(Y; atol = 1e-6), YN) push!(solutions, SolutionPoint(X, Y)) push!(YN, Y) L = _update_list(L, Y_proj) diff --git a/src/algorithms/TambyVanderpooten.jl b/src/algorithms/TambyVanderpooten.jl index 9378880..85ac16f 100644 --- a/src/algorithms/TambyVanderpooten.jl +++ b/src/algorithms/TambyVanderpooten.jl @@ -180,7 +180,9 @@ function minimize_multiobjective!( MOI.delete.(model, ε_constraints) MOI.delete(model, y_k_constraint) push!(V[k], (u, Y)) - if Y ∉ U_N[u][k] + # We want `if !(Y in U_N[u][k])` but this tests exact equality. We want + # an approximate comparison. + if all(!isapprox(Y; atol = 1e-6), U_N[u][k]) _update_search_region(U_N, Y, yN) solutions[Y] = X end @@ -205,6 +207,5 @@ function minimize_multiobjective!( end end end - solutions_vec = [SolutionPoint(X, Y) for (Y, X) in solutions] - return status, filter_nondominated(MOI.MIN_SENSE, solutions_vec) + return status, [SolutionPoint(X, Y) for (Y, X) in solutions] end From 478565608beb74412a48fb2f06386b7e8100d2ca Mon Sep 17 00:00:00 2001 From: odow Date: Fri, 8 Aug 2025 10:40:48 +1200 Subject: [PATCH 4/5] Update --- src/algorithms/KirlikSayin.jl | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/algorithms/KirlikSayin.jl b/src/algorithms/KirlikSayin.jl index ec58322..2f0d6ed 100644 --- a/src/algorithms/KirlikSayin.jl +++ b/src/algorithms/KirlikSayin.jl @@ -171,7 +171,8 @@ function minimize_multiobjective!(algorithm::KirlikSayin, model::Optimizer) Y_proj = _project(Y, k) # We want `if !(Y in YN)` but this tests exact equality. We want # an approximate comparison. - if all(!isapprox(Y; atol = 1e-6), YN) + # if all(!isapprox(Y; atol = 1e-6), YN) + if !(Y in YN) push!(solutions, SolutionPoint(X, Y)) push!(YN, Y) L = _update_list(L, Y_proj) From 8c08a771cad94924f171e7f6b8305b4d436f6c35 Mon Sep 17 00:00:00 2001 From: odow Date: Fri, 8 Aug 2025 10:58:06 +1200 Subject: [PATCH 5/5] Update --- src/algorithms/KirlikSayin.jl | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/src/algorithms/KirlikSayin.jl b/src/algorithms/KirlikSayin.jl index 2f0d6ed..d60d09e 100644 --- a/src/algorithms/KirlikSayin.jl +++ b/src/algorithms/KirlikSayin.jl @@ -169,9 +169,6 @@ function minimize_multiobjective!(algorithm::KirlikSayin, model::Optimizer) end X, Y = _compute_point(model, variables, model.f) Y_proj = _project(Y, k) - # We want `if !(Y in YN)` but this tests exact equality. We want - # an approximate comparison. - # if all(!isapprox(Y; atol = 1e-6), YN) if !(Y in YN) push!(solutions, SolutionPoint(X, Y)) push!(YN, Y) @@ -181,5 +178,5 @@ function minimize_multiobjective!(algorithm::KirlikSayin, model::Optimizer) MOI.delete.(model, ε_constraints) MOI.delete(model, zₖ_constraint) end - return status, solutions + return status, filter_nondominated(MOI.MIN_SENSE, solutions) end