Skip to content

Commit 7b0d975

Browse files
authored
Rename NISE as Dichotomy (#40)
1 parent b03c3ff commit 7b0d975

File tree

3 files changed

+115
-24
lines changed

3 files changed

+115
-24
lines changed

README.md

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,7 @@ using JuMP
2727
import HiGHS
2828
import MultiObjectiveAlgorithms as MOA
2929
model = JuMP.Model(() -> MOA.Optimizer(HiGHS.Optimizer))
30-
set_optimizer_attribute(model, MOA.Algorithm(), MOA.NISE())
30+
set_optimizer_attribute(model, MOA.Algorithm(), MOA.Dichotomy())
3131
set_optimizer_attribute(model, MOA.SolutionLimit(), 4)
3232
```
3333

@@ -44,11 +44,11 @@ Set the algorithm using the `MOA.Algorithm()` attribute.
4444
The value must be one of the algorithms supported by MOA:
4545

4646
* `MOA.EpsilonConstraint()`
47+
* `MOA.Dichotomy()`
4748
* `MOA.DominguezRios()`
4849
* `MOA.Hierarchical()`
4950
* `MOA.KirlikSayin()`
5051
* `MOA.Lexicographic()` [default]
51-
* `MOA.NISE()`
5252

5353
Consult their docstrings for details.
5454

src/algorithms/NISE.jl renamed to src/algorithms/Dichotomy.jl

Lines changed: 33 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,24 @@
33
# v.2.0. If a copy of the MPL was not distributed with this file, You can
44
# obtain one at http://mozilla.org/MPL/2.0/.
55

6+
"""
7+
Dichotomy()
8+
9+
A solver that implements the algorithm of:
10+
11+
Y. P. Aneja, K. P. K. Nair, (1979) Bicriteria Transportation Problem. Management
12+
Science 25(1), 73-78.
13+
14+
## Supported optimizer attributes
15+
16+
* `MOA.SolutionLimit()`
17+
"""
18+
mutable struct Dichotomy <: AbstractAlgorithm
19+
solution_limit::Union{Nothing,Int}
20+
21+
Dichotomy() = new(nothing)
22+
end
23+
624
"""
725
NISE()
826
@@ -12,32 +30,36 @@ Cohon, J. L., Church, R. L., & Sheer, D. P. (1979). Generating multiobjective
1230
trade‐offs: An algorithm for bicriterion problems. Water Resources Research,
1331
15(5), 1001-1010.
1432
33+
!!! note
34+
This algorithm is identical to `Dichotomy()`, and it may be removed in a
35+
future release.
36+
1537
## Supported optimizer attributes
1638
1739
* `MOA.SolutionLimit()`
1840
"""
19-
mutable struct NISE <: AbstractAlgorithm
20-
solution_limit::Union{Nothing,Int}
21-
22-
NISE() = new(nothing)
23-
end
41+
NISE() = Dichotomy()
2442

25-
MOI.supports(::NISE, ::SolutionLimit) = true
43+
MOI.supports(::Dichotomy, ::SolutionLimit) = true
2644

27-
function MOI.set(alg::NISE, ::SolutionLimit, value)
45+
function MOI.set(alg::Dichotomy, ::SolutionLimit, value)
2846
alg.solution_limit = value
2947
return
3048
end
3149

32-
function MOI.get(alg::NISE, attr::SolutionLimit)
50+
function MOI.get(alg::Dichotomy, attr::SolutionLimit)
3351
return something(alg.solution_limit, default(alg, attr))
3452
end
3553

36-
function _solve_weighted_sum(model::Optimizer, alg::NISE, weight::Float64)
54+
function _solve_weighted_sum(model::Optimizer, alg::Dichotomy, weight::Float64)
3755
return _solve_weighted_sum(model, alg, [weight, 1 - weight])
3856
end
3957

40-
function _solve_weighted_sum(model::Optimizer, ::NISE, weights::Vector{Float64})
58+
function _solve_weighted_sum(
59+
model::Optimizer,
60+
::Dichotomy,
61+
weights::Vector{Float64},
62+
)
4163
f = _scalarise(model.f, weights)
4264
MOI.set(model.inner, MOI.ObjectiveFunction{typeof(f)}(), f)
4365
MOI.optimize!(model.inner)
@@ -51,7 +73,7 @@ function _solve_weighted_sum(model::Optimizer, ::NISE, weights::Vector{Float64})
5173
return status, SolutionPoint(X, Y)
5274
end
5375

54-
function optimize_multiobjective!(algorithm::NISE, model::Optimizer)
76+
function optimize_multiobjective!(algorithm::Dichotomy, model::Optimizer)
5577
if MOI.output_dimension(model.f) > 2
5678
error("Only scalar or bi-objective problems supported.")
5779
end

test/algorithms/NISE.jl renamed to test/algorithms/Dichotomy.jl

Lines changed: 80 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33
# v.2.0. If a copy of the MPL was not distributed with this file, You can
44
# obtain one at http://mozilla.org/MPL/2.0/.
55

6-
module TestNISE
6+
module TestDichotomy
77

88
using Test
99

@@ -23,9 +23,11 @@ function run_tests()
2323
return
2424
end
2525

26-
function test_NISE_SolutionLimit()
26+
function test_Dichotomy_SolutionLimit()
2727
model = MOA.Optimizer(HiGHS.Optimizer)
28-
MOI.set(model, MOA.Algorithm(), MOA.NISE())
28+
MOI.set(model, MOA.Algorithm(), MOA.Dichotomy())
29+
@test MOI.supports(MOA.Dichotomy(), MOA.SolutionLimit())
30+
@test MOI.supports(model, MOA.SolutionLimit())
2931
@test MOI.get(model, MOA.SolutionLimit()) ==
3032
MOA.default(MOA.SolutionLimit())
3133
MOI.set(model, MOA.SolutionLimit(), 1)
@@ -36,7 +38,7 @@ end
3638
function test_moi_bolp_1()
3739
f = MOI.OptimizerWithAttributes(
3840
() -> MOA.Optimizer(HiGHS.Optimizer),
39-
MOA.Algorithm() => MOA.NISE(),
41+
MOA.Algorithm() => MOA.Dichotomy(),
4042
)
4143
model = MOI.instantiate(f)
4244
MOI.set(model, MOI.Silent(), true)
@@ -72,7 +74,7 @@ end
7274
function test_moi_bolp_1_maximize()
7375
f = MOI.OptimizerWithAttributes(
7476
() -> MOA.Optimizer(HiGHS.Optimizer),
75-
MOA.Algorithm() => MOA.NISE(),
77+
MOA.Algorithm() => MOA.Dichotomy(),
7678
)
7779
model = MOI.instantiate(f)
7880
MOI.set(model, MOI.Silent(), true)
@@ -108,7 +110,7 @@ end
108110
function test_moi_bolp_1_reversed()
109111
f = MOI.OptimizerWithAttributes(
110112
() -> MOA.Optimizer(HiGHS.Optimizer),
111-
MOA.Algorithm() => MOA.NISE(),
113+
MOA.Algorithm() => MOA.Dichotomy(),
112114
)
113115
model = MOI.instantiate(f)
114116
MOI.set(model, MOI.Silent(), true)
@@ -144,7 +146,7 @@ end
144146
function test_moi_bolp_1_scalar()
145147
f = MOI.OptimizerWithAttributes(
146148
() -> MOA.Optimizer(HiGHS.Optimizer),
147-
MOA.Algorithm() => MOA.NISE(),
149+
MOA.Algorithm() => MOA.Dichotomy(),
148150
)
149151
model = MOI.instantiate(f)
150152
MOI.set(model, MOI.Silent(), true)
@@ -198,7 +200,7 @@ function test_biobjective_knapsack()
198200
w = [80, 87, 68, 72, 66, 77, 99, 85, 70, 93, 98, 72, 100, 89, 67, 86, 91]
199201
f = MOI.OptimizerWithAttributes(
200202
() -> MOA.Optimizer(HiGHS.Optimizer),
201-
MOA.Algorithm() => MOA.NISE(),
203+
MOA.Algorithm() => MOA.Dichotomy(),
202204
)
203205
model = MOI.instantiate(f)
204206
MOI.set(model, MOI.Silent(), true)
@@ -234,7 +236,7 @@ end
234236

235237
function test_infeasible()
236238
model = MOA.Optimizer(HiGHS.Optimizer)
237-
MOI.set(model, MOA.Algorithm(), MOA.NISE())
239+
MOI.set(model, MOA.Algorithm(), MOA.Dichotomy())
238240
MOI.set(model, MOI.Silent(), true)
239241
x = MOI.add_variables(model, 2)
240242
MOI.add_constraint.(model, x, MOI.GreaterThan(0.0))
@@ -250,7 +252,7 @@ end
250252

251253
function test_unbounded()
252254
model = MOA.Optimizer(HiGHS.Optimizer)
253-
MOI.set(model, MOA.Algorithm(), MOA.NISE())
255+
MOI.set(model, MOA.Algorithm(), MOA.Dichotomy())
254256
MOI.set(model, MOI.Silent(), true)
255257
x = MOI.add_variables(model, 2)
256258
MOI.add_constraint.(model, x, MOI.GreaterThan(0.0))
@@ -264,6 +266,73 @@ function test_unbounded()
264266
return
265267
end
266268

269+
function test_bicriteria_transportation_nise()
270+
m, n = 3, 4
271+
c = Float64[1 2 7 7; 1 9 3 4; 8 9 4 6]
272+
d = Float64[4 4 3 4; 5 8 9 10; 6 2 5 1]
273+
a = Float64[11, 3, 14, 16]
274+
b = Float64[8, 19, 17]
275+
model = MOA.Optimizer(HiGHS.Optimizer)
276+
MOI.set(model, MOA.Algorithm(), MOA.Dichotomy())
277+
MOI.set(model, MOI.Silent(), true)
278+
x = [MOI.add_variable(model) for i in 1:m, j in 1:n]
279+
MOI.add_constraint.(model, x, MOI.GreaterThan(0.0))
280+
for j in 1:n
281+
terms = [MOI.ScalarAffineTerm(1.0, x[i, j]) for i in 1:m]
282+
MOI.add_constraint(
283+
model,
284+
MOI.ScalarAffineFunction(terms, 0.0),
285+
MOI.EqualTo(a[j]),
286+
)
287+
end
288+
for i in 1:m
289+
terms = [MOI.ScalarAffineTerm(1.0, x[i, j]) for j in 1:n]
290+
MOI.add_constraint(
291+
model,
292+
MOI.ScalarAffineFunction(terms, 0.0),
293+
MOI.EqualTo(b[i]),
294+
)
295+
end
296+
f = MOI.Utilities.vectorize([
297+
sum(c[i, j] * x[i, j] for i in 1:m, j in 1:n),
298+
sum(d[i, j] * x[i, j] for i in 1:m, j in 1:n),
299+
])
300+
MOI.set(model, MOI.ObjectiveFunction{typeof(f)}(), f)
301+
MOI.set(model, MOI.ObjectiveSense(), MOI.MIN_SENSE)
302+
MOI.optimize!(model)
303+
N = MOI.get(model, MOI.ResultCount())
304+
y_sol = hcat(MOI.get.(model, MOI.ObjectiveValue.(1:N))...)
305+
Y_N = Float64[143 156 176 186 208; 265 200 175 171 167]
306+
@test isapprox(y_sol, Y_N; atol = 1e-6)
307+
return
308+
end
309+
310+
function test_deprecated()
311+
nise = MOA.NISE()
312+
dichotomy = MOA.Dichotomy()
313+
@test nise isa typeof(dichotomy)
314+
@test nise.solution_limit === dichotomy.solution_limit
315+
return
316+
end
317+
318+
function test_three_objective()
319+
model = MOA.Optimizer(HiGHS.Optimizer)
320+
MOI.set(model, MOA.Algorithm(), MOA.Dichotomy())
321+
MOI.set(model, MOI.Silent(), true)
322+
MOI.Utilities.loadfromstring!(
323+
model,
324+
"""
325+
variables: x
326+
maxobjective: [1.0 * x, -1.0 * x, 2.0 * x + 2.0]
327+
""",
328+
)
329+
@test_throws(
330+
ErrorException("Only scalar or bi-objective problems supported."),
331+
MOI.optimize!(model),
332+
)
333+
return
334+
end
335+
267336
end
268337

269-
TestNISE.run_tests()
338+
TestDichotomy.run_tests()

0 commit comments

Comments
 (0)