Skip to content

Commit 1650ae1

Browse files
authored
Add support for VectorNonlinearFunction objectives (#68)
1 parent 2d5d045 commit 1650ae1

File tree

4 files changed

+45
-3
lines changed

4 files changed

+45
-3
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.15"
14+
MathOptInterface = "1.19"
1515
julia = "1.6"
1616

1717
[extras]

src/MultiObjectiveAlgorithms.jl

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -88,6 +88,13 @@ function _scalarise(f::MOI.VectorQuadraticFunction, w::Vector{Float64})
8888
return MOI.ScalarQuadraticFunction(quad_terms, affine_terms, constant)
8989
end
9090

91+
function _scalarise(f::MOI.VectorNonlinearFunction, w::Vector{Float64})
92+
scalars = map(zip(w, f.rows)) do (wi, fi)
93+
return MOI.ScalarNonlinearFunction(:*, Any[wi, fi])
94+
end
95+
return MOI.ScalarNonlinearFunction(:+, scalars)
96+
end
97+
9198
abstract type AbstractAlgorithm end
9299

93100
MOI.Utilities.map_indices(::Function, x::AbstractAlgorithm) = x
@@ -493,6 +500,9 @@ function MOI.get(model::Optimizer, attr::MOI.ListOfModelAttributesSet)
493500
end
494501

495502
function MOI.delete(model::Optimizer, x::MOI.VariableIndex)
503+
if model.f isa MOI.VectorNonlinearFunction
504+
throw(MOI.DeleteNotAllowed(x))
505+
end
496506
MOI.delete(model.inner, x)
497507
if model.f !== nothing
498508
model.f = MOI.Utilities.remove_variable(model.f, x)
@@ -582,7 +592,7 @@ function _compute_point(
582592
X = Dict{MOI.VariableIndex,Float64}(
583593
x => MOI.get(model.inner, MOI.VariablePrimal(), x) for x in variables
584594
)
585-
Y = MOI.Utilities.eval_variables(x -> X[x], f)
595+
Y = MOI.Utilities.eval_variables(Base.Fix1(getindex, X), model, f)
586596
return X, Y
587597
end
588598

src/algorithms/EpsilonConstraint.jl

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -106,7 +106,7 @@ function optimize_multiobjective!(
106106
end
107107
ci = MOI.add_constraint(model, f1, SetType(bound))
108108
status = MOI.OPTIMAL
109-
while true
109+
for _ in 1:n_points
110110
if _time_limit_exceeded(model, start_time)
111111
status = MOI.TIME_LIMIT
112112
break

test/algorithms/EpsilonConstraint.jl

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -362,6 +362,38 @@ function test_poor_numerics()
362362
return
363363
end
364364

365+
function test_vectornonlinearfunction()
366+
μ = [0.006898463772627643, -0.02972609131603086]
367+
Q = [0.030446 0.00393731; 0.00393731 0.00713285]
368+
N = 2
369+
model = MOA.Optimizer(Ipopt.Optimizer)
370+
MOI.set(model, MOA.Algorithm(), MOA.EpsilonConstraint())
371+
MOI.set(model, MOA.SolutionLimit(), 10)
372+
MOI.set(model, MOI.Silent(), true)
373+
w = MOI.add_variables(model, N)
374+
MOI.add_constraint.(model, w, MOI.GreaterThan(0.0))
375+
MOI.add_constraint.(model, w, MOI.LessThan(1.0))
376+
MOI.add_constraint(model, sum(1.0 * w[i] for i in 1:N), MOI.EqualTo(1.0))
377+
f = MOI.VectorNonlinearFunction([
378+
μ' * w,
379+
MOI.ScalarNonlinearFunction(
380+
:/,
381+
Any[μ'*w, MOI.ScalarNonlinearFunction(:sqrt, Any[w'*Q*w])],
382+
),
383+
])
384+
MOI.set(model, MOI.ObjectiveSense(), MOI.MAX_SENSE)
385+
MOI.set(model, MOI.ObjectiveFunction{typeof(f)}(), f)
386+
MOI.optimize!(model)
387+
@test MOI.get(model, MOI.ResultCount()) >= 1
388+
for i in 1:MOI.get(model, MOI.ResultCount())
389+
w_sol = MOI.get(model, MOI.VariablePrimal(i), w)
390+
y = MOI.get(model, MOI.ObjectiveValue(i))
391+
@test y ' * w_sol, (μ' * w_sol) / sqrt(w_sol' * Q * w_sol)]
392+
end
393+
@test MOI.get(model, MOI.TerminationStatus()) == MOI.OPTIMAL
394+
return
395+
end
396+
365397
function test_time_limit()
366398
p1 = [77, 94, 71, 63, 96, 82, 85, 75, 72, 91, 99, 63, 84, 87, 79, 94, 90]
367399
p2 = [65, 90, 90, 77, 95, 84, 70, 94, 66, 92, 74, 97, 60, 60, 65, 97, 93]

0 commit comments

Comments
 (0)