From a5fc81c9442ba1877be24e0a125835b91e8a516d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?G=C3=B6khan=20Kof?= Date: Sun, 14 Dec 2025 10:31:07 +0300 Subject: [PATCH 01/13] Update DR --- src/algorithms/DominguezRios.jl | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/src/algorithms/DominguezRios.jl b/src/algorithms/DominguezRios.jl index e5d8d4c..edb1a4b 100644 --- a/src/algorithms/DominguezRios.jl +++ b/src/algorithms/DominguezRios.jl @@ -190,13 +190,24 @@ function minimize_multiobjective!(algorithm::DominguezRios, model::Optimizer) solutions = SolutionPoint[] k = 0 status = MOI.OPTIMAL + B_prevs = Vector{_DominguezRiosBox}(undef, n) + iter = 0 while any(!isempty(l) for l in L) + iter += 1 if (ret = _check_premature_termination(model)) !== nothing status = ret break end i, k = _select_next_box(L, k) B = L[k][i] + if iter > n + if (B_prevs[k].l ≈ B.l) && (B_prevs[k].u ≈ B.u) + @info "B and B_prev are the same!" + deleteat!(L[k], i) + continue + end + end + B_prevs[k] = B # We're going to scale `w` here by `scale` instead of the usual # `1 / max(...)`. It will show up in a few places bbelow. w = scale ./ max.(1, B.u - yI) From b7c20b386bbf57aaae3931da9d00602df9ee0593 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?G=C3=B6khan=20Kof?= Date: Sun, 14 Dec 2025 10:36:29 +0300 Subject: [PATCH 02/13] Update --- src/algorithms/DominguezRios.jl | 1 - 1 file changed, 1 deletion(-) diff --git a/src/algorithms/DominguezRios.jl b/src/algorithms/DominguezRios.jl index edb1a4b..a1b860a 100644 --- a/src/algorithms/DominguezRios.jl +++ b/src/algorithms/DominguezRios.jl @@ -202,7 +202,6 @@ function minimize_multiobjective!(algorithm::DominguezRios, model::Optimizer) B = L[k][i] if iter > n if (B_prevs[k].l ≈ B.l) && (B_prevs[k].u ≈ B.u) - @info "B and B_prev are the same!" deleteat!(L[k], i) continue end From ef5569919ea984d1451354d0ee5d620ad0cd2f22 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?G=C3=B6khan=20Kof?= Date: Sun, 14 Dec 2025 10:57:05 +0300 Subject: [PATCH 03/13] Update --- src/algorithms/DominguezRios.jl | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/src/algorithms/DominguezRios.jl b/src/algorithms/DominguezRios.jl index a1b860a..465db50 100644 --- a/src/algorithms/DominguezRios.jl +++ b/src/algorithms/DominguezRios.jl @@ -190,7 +190,7 @@ function minimize_multiobjective!(algorithm::DominguezRios, model::Optimizer) solutions = SolutionPoint[] k = 0 status = MOI.OPTIMAL - B_prevs = Vector{_DominguezRiosBox}(undef, n) + B_prevs = Vector{Union{Nothing, _DominguezRiosBox}}(nothing, n) iter = 0 while any(!isempty(l) for l in L) iter += 1 @@ -201,9 +201,11 @@ function minimize_multiobjective!(algorithm::DominguezRios, model::Optimizer) i, k = _select_next_box(L, k) B = L[k][i] if iter > n - if (B_prevs[k].l ≈ B.l) && (B_prevs[k].u ≈ B.u) - deleteat!(L[k], i) - continue + if !isnothing(B_prevs[k]) + if (B_prevs[k].l ≈ B.l) && (B_prevs[k].u ≈ B.u) + deleteat!(L[k], i) + continue + end end end B_prevs[k] = B From d96244829c35fc0599f9da6b5c0584987699e5ae Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?G=C3=B6khan=20Kof?= Date: Sun, 14 Dec 2025 10:59:01 +0300 Subject: [PATCH 04/13] Fix format --- src/algorithms/DominguezRios.jl | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/algorithms/DominguezRios.jl b/src/algorithms/DominguezRios.jl index 465db50..c81dcd1 100644 --- a/src/algorithms/DominguezRios.jl +++ b/src/algorithms/DominguezRios.jl @@ -190,7 +190,7 @@ function minimize_multiobjective!(algorithm::DominguezRios, model::Optimizer) solutions = SolutionPoint[] k = 0 status = MOI.OPTIMAL - B_prevs = Vector{Union{Nothing, _DominguezRiosBox}}(nothing, n) + B_prevs = Vector{Union{Nothing,_DominguezRiosBox}}(nothing, n) iter = 0 while any(!isempty(l) for l in L) iter += 1 From e6e62c8371d24e53d5604ba6de60f4d5deae0ff0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?G=C3=B6khan=20Kof?= Date: Sun, 14 Dec 2025 11:18:52 +0300 Subject: [PATCH 05/13] Add LP test --- test/algorithms/DominguezRios.jl | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/test/algorithms/DominguezRios.jl b/test/algorithms/DominguezRios.jl index e9970d0..609036d 100644 --- a/test/algorithms/DominguezRios.jl +++ b/test/algorithms/DominguezRios.jl @@ -152,6 +152,18 @@ function test_vector_of_variables_objective() return end +function test_lp() + model = Model(() -> MOA.Optimizer(HiGHS.Optimizer)) + set_silent(model) + @variable(model, x1 >= 0) + @variable(model, 0 <= x2 <= 3) + @objective(model, Min, [3x1 + x2, -x1 - 2x2]) + @constraint(model, 3x1 - x2 <= 6) + set_attribute(model, MOA.Algorithm(), MOA.DominguezRios()) + optimize!(model) + @test MOI.get(model, MOI.TerminationStatus()) == MOI.OPTIMAL +end + end # module TestDominguezRios TestDominguezRios.run_tests() From c0a0a56be814749e199d2d989b22738d0551d056 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?G=C3=B6khan=20Kof?= Date: Sun, 14 Dec 2025 11:39:00 +0300 Subject: [PATCH 06/13] Update --- test/algorithms/DominguezRios.jl | 29 +++++++++++++++++++++-------- 1 file changed, 21 insertions(+), 8 deletions(-) diff --git a/test/algorithms/DominguezRios.jl b/test/algorithms/DominguezRios.jl index 609036d..b1f18b2 100644 --- a/test/algorithms/DominguezRios.jl +++ b/test/algorithms/DominguezRios.jl @@ -153,14 +153,27 @@ function test_vector_of_variables_objective() end function test_lp() - model = Model(() -> MOA.Optimizer(HiGHS.Optimizer)) - set_silent(model) - @variable(model, x1 >= 0) - @variable(model, 0 <= x2 <= 3) - @objective(model, Min, [3x1 + x2, -x1 - 2x2]) - @constraint(model, 3x1 - x2 <= 6) - set_attribute(model, MOA.Algorithm(), MOA.DominguezRios()) - optimize!(model) + model = MOI.instantiate(; with_bridge_type = Float64) do + return MOA.Optimizer(HiGHS.Optimizer) + end + MOI.set(model, MOA.Algorithm(), MOA.DominguezRios()) + MOI.set(model, MOI.Silent(), true) + x1 = MOI.add_variable(model) + x2 = MOI.add_variable(model) + MOI.add_constraint(model, x1, MOI.GreaterThan(0.0)) + MOI.add_constraint(model, x2, MOI.Interval(0.0, 3.0)) + f = MOI.VectorAffineFunction( + [ + MOI.VectorAffineTerm(1, MOI.ScalarAffineTerm(3.0, x1)) + MOI.VectorAffineTerm(1, MOI.ScalarAffineTerm(1.0, x1)); + MOI.VectorAffineTerm(2, MOI.ScalarAffineTerm(-1.0, x1)) + MOI.VectorAffineTerm(2, MOI.ScalarAffineTerm(-2.0, x1)) + ], + fill(0.0, 2), + ) + MOI.add_constraint(model, 3x1 - x2, MOI.LessThan(6.0)) + MOI.set(model, MOA.Algorithm(), MOA.DominguezRios()) + MOI.optimize!(model) @test MOI.get(model, MOI.TerminationStatus()) == MOI.OPTIMAL end From e8df858f1bec299c59d46d170dd2dc2413d32300 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?G=C3=B6khan=20Kof?= Date: Sun, 14 Dec 2025 11:44:33 +0300 Subject: [PATCH 07/13] Update --- test/algorithms/DominguezRios.jl | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/algorithms/DominguezRios.jl b/test/algorithms/DominguezRios.jl index b1f18b2..dd2669b 100644 --- a/test/algorithms/DominguezRios.jl +++ b/test/algorithms/DominguezRios.jl @@ -171,7 +171,7 @@ function test_lp() ], fill(0.0, 2), ) - MOI.add_constraint(model, 3x1 - x2, MOI.LessThan(6.0)) + MOI.add_constraint(model, 3.0 * x1 - x2, MOI.LessThan(6.0)) MOI.set(model, MOA.Algorithm(), MOA.DominguezRios()) MOI.optimize!(model) @test MOI.get(model, MOI.TerminationStatus()) == MOI.OPTIMAL From 8fa7e3b7b04bd81277c243b9ac2147a27c59614f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?G=C3=B6khan=20Kof?= Date: Sun, 14 Dec 2025 11:58:54 +0300 Subject: [PATCH 08/13] Update --- test/algorithms/DominguezRios.jl | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/test/algorithms/DominguezRios.jl b/test/algorithms/DominguezRios.jl index dd2669b..0257fa0 100644 --- a/test/algorithms/DominguezRios.jl +++ b/test/algorithms/DominguezRios.jl @@ -165,14 +165,16 @@ function test_lp() f = MOI.VectorAffineFunction( [ MOI.VectorAffineTerm(1, MOI.ScalarAffineTerm(3.0, x1)) - MOI.VectorAffineTerm(1, MOI.ScalarAffineTerm(1.0, x1)); + MOI.VectorAffineTerm(1, MOI.ScalarAffineTerm(1.0, x2)); MOI.VectorAffineTerm(2, MOI.ScalarAffineTerm(-1.0, x1)) - MOI.VectorAffineTerm(2, MOI.ScalarAffineTerm(-2.0, x1)) + MOI.VectorAffineTerm(2, MOI.ScalarAffineTerm(-2.0, x2)) ], fill(0.0, 2), ) - MOI.add_constraint(model, 3.0 * x1 - x2, MOI.LessThan(6.0)) + MOI.add_constraint(model, 3.0 * x1 - 1.0 * x2, MOI.LessThan(6.0)) MOI.set(model, MOA.Algorithm(), MOA.DominguezRios()) + MOI.set(model, MOI.ObjectiveSense(), MOI.MIN_SENSE) + MOI.set(model, MOI.ObjectiveFunction{typeof(f)}(), f) MOI.optimize!(model) @test MOI.get(model, MOI.TerminationStatus()) == MOI.OPTIMAL end From a3641ea9f57e8ed798cf1a785862e6ef4955689f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?G=C3=B6khan=20Kof?= Date: Sun, 14 Dec 2025 12:22:36 +0300 Subject: [PATCH 09/13] Fix format --- test/algorithms/DominguezRios.jl | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/test/algorithms/DominguezRios.jl b/test/algorithms/DominguezRios.jl index 0257fa0..7c5c5be 100644 --- a/test/algorithms/DominguezRios.jl +++ b/test/algorithms/DominguezRios.jl @@ -162,12 +162,14 @@ function test_lp() x2 = MOI.add_variable(model) MOI.add_constraint(model, x1, MOI.GreaterThan(0.0)) MOI.add_constraint(model, x2, MOI.Interval(0.0, 3.0)) + C = Float64[ + 3 1 + -1 -2 + ] f = MOI.VectorAffineFunction( [ - MOI.VectorAffineTerm(1, MOI.ScalarAffineTerm(3.0, x1)) - MOI.VectorAffineTerm(1, MOI.ScalarAffineTerm(1.0, x2)); - MOI.VectorAffineTerm(2, MOI.ScalarAffineTerm(-1.0, x1)) - MOI.VectorAffineTerm(2, MOI.ScalarAffineTerm(-2.0, x2)) + MOI.VectorAffineTerm(i, MOI.ScalarAffineTerm(C[i, j], x[j])) for + i in 1:2 for j in 1:2 ], fill(0.0, 2), ) From 2dadbbde58f9b6a916764184b86e17600f6c3e55 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?G=C3=B6khan=20Kof?= Date: Sun, 14 Dec 2025 12:32:58 +0300 Subject: [PATCH 10/13] Update --- test/algorithms/DominguezRios.jl | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) diff --git a/test/algorithms/DominguezRios.jl b/test/algorithms/DominguezRios.jl index 7c5c5be..967607d 100644 --- a/test/algorithms/DominguezRios.jl +++ b/test/algorithms/DominguezRios.jl @@ -158,10 +158,9 @@ function test_lp() end MOI.set(model, MOA.Algorithm(), MOA.DominguezRios()) MOI.set(model, MOI.Silent(), true) - x1 = MOI.add_variable(model) - x2 = MOI.add_variable(model) - MOI.add_constraint(model, x1, MOI.GreaterThan(0.0)) - MOI.add_constraint(model, x2, MOI.Interval(0.0, 3.0)) + x = MOI.add_variables(model, 2) + MOI.add_constraint(model, x[1], MOI.GreaterThan(0.0)) + MOI.add_constraint(model, x[2], MOI.Interval(0.0, 3.0)) C = Float64[ 3 1 -1 -2 @@ -173,7 +172,7 @@ function test_lp() ], fill(0.0, 2), ) - MOI.add_constraint(model, 3.0 * x1 - 1.0 * x2, MOI.LessThan(6.0)) + MOI.add_constraint(model, 3.0 * x[1] - 1.0 * x[2], MOI.LessThan(6.0)) MOI.set(model, MOA.Algorithm(), MOA.DominguezRios()) MOI.set(model, MOI.ObjectiveSense(), MOI.MIN_SENSE) MOI.set(model, MOI.ObjectiveFunction{typeof(f)}(), f) From 0d4ba598a4dfba00ddc70fa4f111c107df57ffab Mon Sep 17 00:00:00 2001 From: Oscar Dowson Date: Mon, 15 Dec 2025 09:02:08 +1300 Subject: [PATCH 11/13] Simplify objective function and constraints in tests Refactor objective function creation and update constraints. --- test/algorithms/DominguezRios.jl | 15 +++------------ 1 file changed, 3 insertions(+), 12 deletions(-) diff --git a/test/algorithms/DominguezRios.jl b/test/algorithms/DominguezRios.jl index 967607d..d0c9f92 100644 --- a/test/algorithms/DominguezRios.jl +++ b/test/algorithms/DominguezRios.jl @@ -161,23 +161,14 @@ function test_lp() x = MOI.add_variables(model, 2) MOI.add_constraint(model, x[1], MOI.GreaterThan(0.0)) MOI.add_constraint(model, x[2], MOI.Interval(0.0, 3.0)) - C = Float64[ - 3 1 - -1 -2 - ] - f = MOI.VectorAffineFunction( - [ - MOI.VectorAffineTerm(i, MOI.ScalarAffineTerm(C[i, j], x[j])) for - i in 1:2 for j in 1:2 - ], - fill(0.0, 2), - ) MOI.add_constraint(model, 3.0 * x[1] - 1.0 * x[2], MOI.LessThan(6.0)) - MOI.set(model, MOA.Algorithm(), MOA.DominguezRios()) MOI.set(model, MOI.ObjectiveSense(), MOI.MIN_SENSE) + f = MOI.Utilities.vectorize([3.0 1.0; -1.0 -2.0] * x) MOI.set(model, MOI.ObjectiveFunction{typeof(f)}(), f) MOI.optimize!(model) @test MOI.get(model, MOI.TerminationStatus()) == MOI.OPTIMAL + @test MOI.get(model, MOI.ResultCount()) > 1 + return end end # module TestDominguezRios From f3cf90c889d5d1ed3d800a127669ba7d88162bcd Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?G=C3=B6khan=20Kof?= Date: Mon, 15 Dec 2025 11:06:32 +0300 Subject: [PATCH 12/13] Update --- src/algorithms/DominguezRios.jl | 23 ++++++++++++++--------- 1 file changed, 14 insertions(+), 9 deletions(-) diff --git a/src/algorithms/DominguezRios.jl b/src/algorithms/DominguezRios.jl index c81dcd1..59ad5f2 100644 --- a/src/algorithms/DominguezRios.jl +++ b/src/algorithms/DominguezRios.jl @@ -148,6 +148,10 @@ function _update!( return end +_isapprox(::Nothing, ::_DominguezRiosBox) = false + +_isapprox(A::_DominguezRiosBox, B::_DominguezRiosBox) = A.l ≈ B.l && A.u ≈ B.u + function minimize_multiobjective!(algorithm::DominguezRios, model::Optimizer) @assert MOI.get(model.inner, MOI.ObjectiveSense()) == MOI.MIN_SENSE n = MOI.output_dimension(model.f) @@ -190,7 +194,7 @@ function minimize_multiobjective!(algorithm::DominguezRios, model::Optimizer) solutions = SolutionPoint[] k = 0 status = MOI.OPTIMAL - B_prevs = Vector{Union{Nothing,_DominguezRiosBox}}(nothing, n) + B_prev = Vector{Union{Nothing,_DominguezRiosBox}}(nothing, n) iter = 0 while any(!isempty(l) for l in L) iter += 1 @@ -200,15 +204,16 @@ function minimize_multiobjective!(algorithm::DominguezRios, model::Optimizer) end i, k = _select_next_box(L, k) B = L[k][i] - if iter > n - if !isnothing(B_prevs[k]) - if (B_prevs[k].l ≈ B.l) && (B_prevs[k].u ≈ B.u) - deleteat!(L[k], i) - continue - end - end + # We check for the repeated search of similar boxes + # in the same optimization direction. We wait for n + # iterations so that every direction has at least + # one box. If the same box were search before, we + # delete it from the list of boxes. + if _isapprox(B_prev[k], B) + deleteat!(L[k], i) + continue end - B_prevs[k] = B + B_prev[k] = B # We're going to scale `w` here by `scale` instead of the usual # `1 / max(...)`. It will show up in a few places bbelow. w = scale ./ max.(1, B.u - yI) From 2ea7d5f1e2163e719d2449f7f4d8810104391665 Mon Sep 17 00:00:00 2001 From: Oscar Dowson Date: Tue, 16 Dec 2025 08:44:22 +1300 Subject: [PATCH 13/13] Update DominguezRios.jl --- src/algorithms/DominguezRios.jl | 10 +++------- 1 file changed, 3 insertions(+), 7 deletions(-) diff --git a/src/algorithms/DominguezRios.jl b/src/algorithms/DominguezRios.jl index 59ad5f2..64ec5a8 100644 --- a/src/algorithms/DominguezRios.jl +++ b/src/algorithms/DominguezRios.jl @@ -195,20 +195,16 @@ function minimize_multiobjective!(algorithm::DominguezRios, model::Optimizer) k = 0 status = MOI.OPTIMAL B_prev = Vector{Union{Nothing,_DominguezRiosBox}}(nothing, n) - iter = 0 while any(!isempty(l) for l in L) - iter += 1 if (ret = _check_premature_termination(model)) !== nothing status = ret break end i, k = _select_next_box(L, k) B = L[k][i] - # We check for the repeated search of similar boxes - # in the same optimization direction. We wait for n - # iterations so that every direction has at least - # one box. If the same box were search before, we - # delete it from the list of boxes. + # We check for the repeated search of similar boxes in the same + # optimization direction. If the same box was searched before, we delete + # it from the list of boxes. if _isapprox(B_prev[k], B) deleteat!(L[k], i) continue