@@ -15,31 +15,20 @@ function _halfspaces(IPS::Vector{Vector{Float64}})
15
15
return [(- H_i. a, - H_i. β) for H_i in H]
16
16
end
17
17
18
- function _distance (w̄, b̄, OPS, model)
19
- n = MOI. output_dimension (model. f)
20
- optimizer = typeof (model. inner. optimizer)
21
- δ_optimizer = optimizer ()
22
- MOI. set (δ_optimizer, MOI. Silent (), true )
23
- x = MOI. add_variables (δ_optimizer, n)
24
- for (w, b) in OPS
25
- MOI. add_constraint (
26
- δ_optimizer,
27
- MOI. ScalarAffineFunction (MOI. ScalarAffineTerm .(w, x), 0.0 ),
28
- MOI. GreaterThan (b),
29
- )
30
- end
18
+ function _distance (w̄, b̄, δ_OPS_optimizer)
19
+ y = MOI. get (δ_OPS_optimizer, MOI. ListOfVariableIndices ())
31
20
MOI. set (
32
- δ_optimizer ,
21
+ δ_OPS_optimizer ,
33
22
MOI. ObjectiveFunction {MOI.ScalarAffineFunction{Float64}} (),
34
- MOI. ScalarAffineFunction (MOI. ScalarAffineTerm .(w̄, x ), 0.0 ),
23
+ MOI. ScalarAffineFunction (MOI. ScalarAffineTerm .(w̄, y ), 0.0 ),
35
24
)
36
- MOI. set (δ_optimizer , MOI. ObjectiveSense (), MOI. MIN_SENSE)
37
- MOI. optimize! (δ_optimizer )
38
- return b̄ - MOI. get (δ_optimizer , MOI. ObjectiveValue ())
25
+ MOI. set (δ_OPS_optimizer , MOI. ObjectiveSense (), MOI. MIN_SENSE)
26
+ MOI. optimize! (δ_OPS_optimizer )
27
+ return b̄ - MOI. get (δ_OPS_optimizer , MOI. ObjectiveValue ())
39
28
end
40
29
41
- function _select_next_halfspace (H, OPS, model )
42
- distances = [_distance (w, b, OPS, model ) for (w, b) in H]
30
+ function _select_next_halfspace (H, δ_OPS_optimizer )
31
+ distances = [_distance (w, b, δ_OPS_optimizer ) for (w, b) in H]
43
32
index = argmax (distances)
44
33
w, b = H[index]
45
34
return distances[index], w, b
@@ -56,7 +45,10 @@ function MOA.minimize_multiobjective!(
56
45
n = MOI. output_dimension (model. f)
57
46
scalars = MOI. Utilities. scalarize (model. f)
58
47
status = MOI. OPTIMAL
59
- OPS = Tuple{Vector{Float64},Float64}[]
48
+ optimizer = typeof (model. inner. optimizer)
49
+ δ_OPS_optimizer = optimizer ()
50
+ MOI. set (δ_OPS_optimizer, MOI. Silent (), true )
51
+ y = MOI. add_variables (δ_OPS_optimizer, n)
60
52
anchors = Dict {Vector{Float64},Dict{MOI.VariableIndex,Float64}} ()
61
53
yI, yUB = zeros (n), zeros (n)
62
54
for (i, f_i) in enumerate (scalars)
@@ -81,8 +73,16 @@ function MOA.minimize_multiobjective!(
81
73
yUB[i] = Y
82
74
MOI. set (model. inner, MOI. ObjectiveSense (), MOI. MIN_SENSE)
83
75
e_i = Float64 .(1 : n .== i)
84
- push! (OPS, (e_i, yI[i])) # e_i' * y >= yI_i
85
- push! (OPS, (- e_i, - yUB[i])) # -e_i' * y >= -yUB_i ⟹ e_i' * y <= yUB_i
76
+ MOI. add_constraint (
77
+ δ_OPS_optimizer,
78
+ MOI. ScalarAffineFunction (MOI. ScalarAffineTerm .(e_i, y), 0.0 ),
79
+ MOI. GreaterThan (yI[i]),
80
+ )
81
+ MOI. add_constraint (
82
+ δ_OPS_optimizer,
83
+ MOI. ScalarAffineFunction (MOI. ScalarAffineTerm .(e_i, y), 0.0 ),
84
+ MOI. LessThan (yUB[i]),
85
+ )
86
86
end
87
87
IPS = [yUB, keys (anchors)... ]
88
88
merge! (solutions, anchors)
@@ -106,7 +106,7 @@ function MOA.minimize_multiobjective!(
106
106
break
107
107
end
108
108
count += 1
109
- δ, w, b = _select_next_halfspace (H, OPS, model )
109
+ δ, w, b = _select_next_halfspace (H, δ_OPS_optimizer )
110
110
if δ - 1e-3 <= algorithm. precision # added some convergence tolerance
111
111
break
112
112
end
@@ -121,7 +121,11 @@ function MOA.minimize_multiobjective!(
121
121
β̄ = MOI. get (model. inner, MOI. ObjectiveValue ())
122
122
X, Y = MOA. _compute_point (model, variables, model. f)
123
123
solutions[Y] = X
124
- push! (OPS, (w, β̄))
124
+ MOI. add_constraint (
125
+ δ_OPS_optimizer,
126
+ MOI. ScalarAffineFunction (MOI. ScalarAffineTerm .(w, y), 0.0 ),
127
+ MOI. GreaterThan (β̄),
128
+ )
125
129
IPS = push! (IPS, Y)
126
130
H = _halfspaces (IPS)
127
131
end
0 commit comments