Skip to content

Commit 1b86584

Browse files
authored
Fix support for VectorOfVariables objectives (#62)
1 parent ad4c9a8 commit 1b86584

File tree

11 files changed

+115
-14
lines changed

11 files changed

+115
-14
lines changed

Project.toml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@ MathOptInterface = "b8f27783-ece8-5eb3-8dc8-9495eed66fee"
1111
Combinatorics = "1"
1212
HiGHS = "1"
1313
Ipopt = "1"
14-
MathOptInterface = "1.12"
14+
MathOptInterface = "1.13"
1515
julia = "1.6"
1616

1717
[extras]

src/MultiObjectiveAlgorithms.jl

Lines changed: 6 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -92,16 +92,6 @@ abstract type AbstractAlgorithm end
9292

9393
MOI.Utilities.map_indices(::Function, x::AbstractAlgorithm) = x
9494

95-
function _instantiate_with_cache(optimizer_factory)
96-
model = MOI.instantiate(optimizer_factory)
97-
if !MOI.supports_incremental_interface(model)
98-
# A cache will already have been added
99-
return model
100-
end
101-
cache = MOI.Utilities.UniversalFallback(MOI.Utilities.Model{Float64}())
102-
return MOI.Utilities.CachingOptimizer(cache, model)
103-
end
104-
10595
mutable struct Optimizer <: MOI.AbstractOptimizer
10696
inner::MOI.AbstractOptimizer
10797
algorithm::Union{Nothing,AbstractAlgorithm}
@@ -112,8 +102,13 @@ mutable struct Optimizer <: MOI.AbstractOptimizer
112102
solve_time::Float64
113103

114104
function Optimizer(optimizer_factory)
105+
inner = MOI.instantiate(
106+
optimizer_factory;
107+
with_bridge_type = Float64,
108+
with_cache_type = Float64,
109+
)
115110
return new(
116-
_instantiate_with_cache(optimizer_factory),
111+
inner,
117112
nothing,
118113
nothing,
119114
SolutionPoint[],

src/algorithms/Chalmet.jl

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,8 @@ function _solve_constrained_model(
2525
rhs::Vector{Float64},
2626
)
2727
f = MOI.Utilities.scalarize(model.f)
28-
MOI.set(model.inner, MOI.ObjectiveFunction{typeof(sum(f))}(), sum(f))
28+
g = sum(1.0 * fi for fi in f)
29+
MOI.set(model.inner, MOI.ObjectiveFunction{typeof(g)}(), g)
2930
constraints = [
3031
MOI.add_constraint(model.inner, f[1], MOI.LessThan(rhs[1] - 1))
3132
MOI.add_constraint(model.inner, f[2], MOI.LessThan(rhs[2] - 1))

src/algorithms/KirlikSayin.jl

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -172,7 +172,7 @@ function optimize_multiobjective!(algorithm::KirlikSayin, model::Optimizer)
172172
zₖ = MOI.get(model.inner, MOI.ObjectiveValue())
173173
# Solving the second stage model: Q_k(ε, zₖ)
174174
# Set objective sum(model.f)
175-
sum_f = sum(scalars)
175+
sum_f = sum(1.0 * s for s in scalars)
176176
MOI.set(model.inner, MOI.ObjectiveFunction{typeof(sum_f)}(), sum_f)
177177
# Constraint to eliminate weak dominance
178178
zₖ_constraint =

test/algorithms/Chalmet.jl

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -190,6 +190,21 @@ function test_infeasible()
190190
return
191191
end
192192

193+
function test_vector_of_variables_objective()
194+
model = MOA.Optimizer(HiGHS.Optimizer)
195+
MOI.set(model, MOA.Algorithm(), MOA.Chalmet())
196+
MOI.set(model, MOI.Silent(), true)
197+
x = MOI.add_variables(model, 2)
198+
MOI.add_constraint.(model, x, MOI.ZeroOne())
199+
f = MOI.VectorOfVariables(x)
200+
MOI.set(model, MOI.ObjectiveSense(), MOI.MIN_SENSE)
201+
MOI.set(model, MOI.ObjectiveFunction{typeof(f)}(), f)
202+
MOI.add_constraint(model, sum(1.0 * xi for xi in x), MOI.GreaterThan(1.0))
203+
MOI.optimize!(model)
204+
MOI.get(model, MOI.TerminationStatus()) == MOI.OPTIMAL
205+
return
206+
end
207+
193208
end
194209

195210
TestChalmet.run_tests()

test/algorithms/Dichotomy.jl

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -392,6 +392,21 @@ function test_quadratic()
392392
return
393393
end
394394

395+
function test_vector_of_variables_objective()
396+
model = MOA.Optimizer(HiGHS.Optimizer)
397+
MOI.set(model, MOA.Algorithm(), MOA.Dichotomy())
398+
MOI.set(model, MOI.Silent(), true)
399+
x = MOI.add_variables(model, 2)
400+
MOI.add_constraint.(model, x, MOI.ZeroOne())
401+
f = MOI.VectorOfVariables(x)
402+
MOI.set(model, MOI.ObjectiveSense(), MOI.MIN_SENSE)
403+
MOI.set(model, MOI.ObjectiveFunction{typeof(f)}(), f)
404+
MOI.add_constraint(model, sum(1.0 * xi for xi in x), MOI.GreaterThan(1.0))
405+
MOI.optimize!(model)
406+
MOI.get(model, MOI.TerminationStatus()) == MOI.OPTIMAL
407+
return
408+
end
409+
395410
end
396411

397412
TestDichotomy.run_tests()

test/algorithms/DominguezRios.jl

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -583,6 +583,21 @@ function test_time_limit()
583583
return
584584
end
585585

586+
function test_vector_of_variables_objective()
587+
model = MOA.Optimizer(HiGHS.Optimizer)
588+
MOI.set(model, MOA.Algorithm(), MOA.DominguezRios())
589+
MOI.set(model, MOI.Silent(), true)
590+
x = MOI.add_variables(model, 2)
591+
MOI.add_constraint.(model, x, MOI.ZeroOne())
592+
f = MOI.VectorOfVariables(x)
593+
MOI.set(model, MOI.ObjectiveSense(), MOI.MIN_SENSE)
594+
MOI.set(model, MOI.ObjectiveFunction{typeof(f)}(), f)
595+
MOI.add_constraint(model, sum(1.0 * xi for xi in x), MOI.GreaterThan(1.0))
596+
MOI.optimize!(model)
597+
MOI.get(model, MOI.TerminationStatus()) == MOI.OPTIMAL
598+
return
599+
end
600+
586601
end
587602

588603
TestDominguezRios.run_tests()

test/algorithms/EpsilonConstraint.jl

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -417,6 +417,21 @@ function test_time_limit_large()
417417
return
418418
end
419419

420+
function test_vector_of_variables_objective()
421+
model = MOA.Optimizer(HiGHS.Optimizer)
422+
MOI.set(model, MOA.Algorithm(), MOA.EpsilonConstraint())
423+
MOI.set(model, MOI.Silent(), true)
424+
x = MOI.add_variables(model, 2)
425+
MOI.add_constraint.(model, x, MOI.ZeroOne())
426+
f = MOI.VectorOfVariables(x)
427+
MOI.set(model, MOI.ObjectiveSense(), MOI.MIN_SENSE)
428+
MOI.set(model, MOI.ObjectiveFunction{typeof(f)}(), f)
429+
MOI.add_constraint(model, sum(1.0 * xi for xi in x), MOI.GreaterThan(1.0))
430+
MOI.optimize!(model)
431+
MOI.get(model, MOI.TerminationStatus()) == MOI.OPTIMAL
432+
return
433+
end
434+
420435
end
421436

422437
TestEpsilonConstraint.run_tests()

test/algorithms/Hierarchical.jl

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -107,6 +107,21 @@ function test_unbounded()
107107
return
108108
end
109109

110+
function test_vector_of_variables_objective()
111+
model = MOA.Optimizer(HiGHS.Optimizer)
112+
MOI.set(model, MOA.Algorithm(), MOA.Hierarchical())
113+
MOI.set(model, MOI.Silent(), true)
114+
x = MOI.add_variables(model, 2)
115+
MOI.add_constraint.(model, x, MOI.ZeroOne())
116+
f = MOI.VectorOfVariables(x)
117+
MOI.set(model, MOI.ObjectiveSense(), MOI.MIN_SENSE)
118+
MOI.set(model, MOI.ObjectiveFunction{typeof(f)}(), f)
119+
MOI.add_constraint(model, sum(1.0 * xi for xi in x), MOI.GreaterThan(1.0))
120+
MOI.optimize!(model)
121+
MOI.get(model, MOI.TerminationStatus()) == MOI.OPTIMAL
122+
return
123+
end
124+
110125
end
111126

112127
TestHierarchical.run_tests()

test/algorithms/KirlikSayin.jl

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -586,6 +586,21 @@ function test_time_limit()
586586
return
587587
end
588588

589+
function test_vector_of_variables_objective()
590+
model = MOA.Optimizer(HiGHS.Optimizer)
591+
MOI.set(model, MOA.Algorithm(), MOA.KirlikSayin())
592+
MOI.set(model, MOI.Silent(), true)
593+
x = MOI.add_variables(model, 2)
594+
MOI.add_constraint.(model, x, MOI.ZeroOne())
595+
f = MOI.VectorOfVariables(x)
596+
MOI.set(model, MOI.ObjectiveSense(), MOI.MIN_SENSE)
597+
MOI.set(model, MOI.ObjectiveFunction{typeof(f)}(), f)
598+
MOI.add_constraint(model, sum(1.0 * xi for xi in x), MOI.GreaterThan(1.0))
599+
MOI.optimize!(model)
600+
MOI.get(model, MOI.TerminationStatus()) == MOI.OPTIMAL
601+
return
602+
end
603+
589604
end
590605

591606
TestKirlikSayin.run_tests()

0 commit comments

Comments
 (0)