Skip to content

Commit ad4c9a8

Browse files
authored
[breaking] Add LexicographicAllPermutations and change default (#59)
1 parent b4413a1 commit ad4c9a8

File tree

4 files changed

+47
-25
lines changed

4 files changed

+47
-25
lines changed

README.md

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -47,9 +47,9 @@ Set the algorithm using the `MOA.Algorithm()` attribute.
4747
The value must be one of the algorithms supported by MOA:
4848

4949
* `MOA.Chalmet()`
50-
* `MOA.EpsilonConstraint()`
5150
* `MOA.Dichotomy()`
5251
* `MOA.DominguezRios()`
52+
* `MOA.EpsilonConstraint()`
5353
* `MOA.Hierarchical()`
5454
* `MOA.KirlikSayin()`
5555
* `MOA.Lexicographic()` [default]
@@ -65,6 +65,7 @@ docstring for details on which attributes it supports, and how it uses them in
6565
the solution process.
6666

6767
* `MOA.EpsilonConstraintStep()`
68+
* `MOA.LexicographicAllPermutations()`
6869
* `MOA.ObjectiveAbsoluteTolerance(index::Int)`
6970
* `MOA.ObjectivePriority(index::Int)`
7071
* `MOA.ObjectiveRelativeTolerance(index::Int)`

src/MultiObjectiveAlgorithms.jl

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -334,6 +334,19 @@ struct EpsilonConstraintStep <: AbstractAlgorithmAttribute end
334334

335335
default(::EpsilonConstraintStep) = 1.0
336336

337+
"""
338+
LexicographicAllPermutations <: AbstractAlgorithmAttribute -> Bool
339+
340+
Controls whether to return the lexicographic solution for all permutations of
341+
the scalar objectives (when `true`), or only the solution corresponding to the
342+
lexicographic solution of the original objective function (when `false`).
343+
344+
Defaults to true`.
345+
"""
346+
struct LexicographicAllPermutations <: AbstractAlgorithmAttribute end
347+
348+
default(::LexicographicAllPermutations) = true
349+
337350
### RawOptimizerAttribute
338351

339352
function MOI.supports(model::Optimizer, attr::MOI.RawOptimizerAttribute)

src/algorithms/Lexicographic.jl

Lines changed: 20 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -4,16 +4,18 @@
44
# obtain one at http://mozilla.org/MPL/2.0/.
55

66
"""
7-
Lexicographic(; all_permutations::Bool = false)
7+
Lexicographic()
88
99
`Lexicographic()` implements a lexigographic algorithm that returns a single
1010
point on the frontier, corresponding to solving each objective in order.
1111
12-
`Lexicographic(all_permutations = true)` repeats the lexicographic algorithm for
13-
all permutations of the scalar objectives, returning at most `n!` objectives.
14-
1512
## Supported optimizer attributes
1613
14+
* `MOA.LexicographicAllPermutations()`: Controls whether to return the
15+
lexicographic solution for all permutations of the scalar objectives (when
16+
`true`), or only the solution corresponding to the lexicographic solution of
17+
the original objective function (when `false`).
18+
1719
* `MOA.ObjectiveRelativeTolerance(index)`: after solving objective `index`, a
1820
constraint is added such that the relative degradation in the objective value
1921
of objective `index` is less than this tolerance.
@@ -22,8 +24,8 @@ mutable struct Lexicographic <: AbstractAlgorithm
2224
rtol::Vector{Float64}
2325
all_permutations::Bool
2426

25-
function Lexicographic(; all_permutations::Bool = false)
26-
return new(Float64[], all_permutations)
27+
function Lexicographic()
28+
return new(Float64[], default(LexicographicAllPermutations()))
2729
end
2830
end
2931

@@ -41,9 +43,20 @@ function MOI.set(alg::Lexicographic, attr::ObjectiveRelativeTolerance, value)
4143
return
4244
end
4345

46+
MOI.supports(::Lexicographic, ::LexicographicAllPermutations) = true
47+
48+
function MOI.get(alg::Lexicographic, ::LexicographicAllPermutations)
49+
return alg.all_permutations
50+
end
51+
52+
function MOI.set(alg::Lexicographic, ::LexicographicAllPermutations, val::Bool)
53+
alg.all_permutations = val
54+
return
55+
end
56+
4457
function optimize_multiobjective!(algorithm::Lexicographic, model::Optimizer)
4558
sequence = 1:MOI.output_dimension(model.f)
46-
if !algorithm.all_permutations
59+
if !MOI.get(algorithm, LexicographicAllPermutations())
4760
return _solve_in_sequence(algorithm, model, sequence)
4861
end
4962
solutions = SolutionPoint[]

test/algorithms/Lexicographic.jl

Lines changed: 12 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,8 @@ function test_knapsack()
2727
P = Float64[1 0 0 0; 0 1 0 0; 0 0 0 1; 0 0 1 0]
2828
model = MOA.Optimizer(HiGHS.Optimizer)
2929
MOI.set(model, MOA.Algorithm(), MOA.Lexicographic())
30+
@test MOI.supports(model, MOA.LexicographicAllPermutations())
31+
MOI.set(model, MOA.LexicographicAllPermutations(), false)
3032
MOI.set(model, MOA.ObjectiveRelativeTolerance(1), 0.1)
3133
MOI.set(model, MOI.Silent(), true)
3234
x = MOI.add_variables(model, 4)
@@ -42,14 +44,10 @@ function test_knapsack()
4244
return
4345
end
4446

45-
function test_knapsack_all_permutations()
47+
function test_knapsack_default()
4648
P = Float64[1 0 0 0; 0 1 0 0; 0 0 0 1]
4749
model = MOA.Optimizer(HiGHS.Optimizer)
48-
MOI.set(
49-
model,
50-
MOA.Algorithm(),
51-
MOA.Lexicographic(; all_permutations = true),
52-
)
50+
MOI.set(model, MOA.Algorithm(), MOA.Lexicographic())
5351
MOI.set(model, MOI.Silent(), true)
5452
x = MOI.add_variables(model, 4)
5553
MOI.add_constraint.(model, x, MOI.GreaterThan(0.0))
@@ -77,6 +75,7 @@ function test_knapsack_min()
7775
P = Float64[1 0 0 0; 0 1 0 0; 0 0 0 1; 0 0 1 0]
7876
model = MOA.Optimizer(HiGHS.Optimizer)
7977
MOI.set(model, MOA.Algorithm(), MOA.Lexicographic())
78+
MOI.set(model, MOA.LexicographicAllPermutations(), false)
8079
MOI.set(model, MOA.ObjectiveRelativeTolerance(1), 0.1)
8180
MOI.set(model, MOI.Silent(), true)
8281
x = MOI.add_variables(model, 4)
@@ -92,9 +91,11 @@ function test_knapsack_min()
9291
return
9392
end
9493

95-
function test_knapsack_default()
94+
function test_knapsack_one_solution()
9695
P = Float64[1 0 0 0; 0 1 0 0; 0 0 0 1; 0 0 1 0]
9796
model = MOA.Optimizer(HiGHS.Optimizer)
97+
MOI.set(model, MOA.Algorithm(), MOA.Lexicographic())
98+
MOI.set(model, MOA.LexicographicAllPermutations(), false)
9899
MOI.set(model, MOI.Silent(), true)
99100
x = MOI.add_variables(model, 4)
100101
MOI.add_constraint.(model, x, MOI.GreaterThan(0.0))
@@ -114,11 +115,8 @@ end
114115
function test_infeasible()
115116
for flag in (true, false)
116117
model = MOA.Optimizer(HiGHS.Optimizer)
117-
MOI.set(
118-
model,
119-
MOA.Algorithm(),
120-
MOA.Lexicographic(; all_permutations = flag),
121-
)
118+
MOI.set(model, MOA.Algorithm(), MOA.Lexicographic())
119+
MOI.set(model, MOA.LexicographicAllPermutations(), flag)
122120
MOI.set(model, MOI.Silent(), true)
123121
x = MOI.add_variables(model, 2)
124122
MOI.add_constraint.(model, x, MOI.GreaterThan(0.0))
@@ -136,11 +134,8 @@ end
136134
function test_unbounded()
137135
for flag in (true, false)
138136
model = MOA.Optimizer(HiGHS.Optimizer)
139-
MOI.set(
140-
model,
141-
MOA.Algorithm(),
142-
MOA.Lexicographic(; all_permutations = flag),
143-
)
137+
MOI.set(model, MOA.Algorithm(), MOA.Lexicographic())
138+
MOI.set(model, MOA.LexicographicAllPermutations(), flag)
144139
MOI.set(model, MOI.Silent(), true)
145140
x = MOI.add_variables(model, 2)
146141
MOI.add_constraint.(model, x, MOI.GreaterThan(0.0))

0 commit comments

Comments
 (0)