@@ -15,31 +15,20 @@ function _halfspaces(IPS::Vector{Vector{Float64}})
1515 return [(- H_i. a, - H_i. β) for H_i in H]
1616end
1717
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 ())
3120 MOI. set (
32- δ_optimizer ,
21+ δ_OPS_optimizer ,
3322 MOI. ObjectiveFunction {MOI.ScalarAffineFunction{Float64}} (),
34- MOI. ScalarAffineFunction (MOI. ScalarAffineTerm .(w̄, x ), 0.0 ),
23+ MOI. ScalarAffineFunction (MOI. ScalarAffineTerm .(w̄, y ), 0.0 ),
3524 )
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 ())
3928end
4029
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]
4332 index = argmax (distances)
4433 w, b = H[index]
4534 return distances[index], w, b
@@ -56,7 +45,10 @@ function MOA.minimize_multiobjective!(
5645 n = MOI. output_dimension (model. f)
5746 scalars = MOI. Utilities. scalarize (model. f)
5847 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)
6052 anchors = Dict {Vector{Float64},Dict{MOI.VariableIndex,Float64}} ()
6153 yI, yUB = zeros (n), zeros (n)
6254 for (i, f_i) in enumerate (scalars)
@@ -81,8 +73,16 @@ function MOA.minimize_multiobjective!(
8173 yUB[i] = Y
8274 MOI. set (model. inner, MOI. ObjectiveSense (), MOI. MIN_SENSE)
8375 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+ )
8686 end
8787 IPS = [yUB, keys (anchors)... ]
8888 merge! (solutions, anchors)
@@ -106,7 +106,7 @@ function MOA.minimize_multiobjective!(
106106 break
107107 end
108108 count += 1
109- δ, w, b = _select_next_halfspace (H, OPS, model )
109+ δ, w, b = _select_next_halfspace (H, δ_OPS_optimizer )
110110 if δ - 1e-3 <= algorithm. precision # added some convergence tolerance
111111 break
112112 end
@@ -121,7 +121,11 @@ function MOA.minimize_multiobjective!(
121121 β̄ = MOI. get (model. inner, MOI. ObjectiveValue ())
122122 X, Y = MOA. _compute_point (model, variables, model. f)
123123 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+ )
125129 IPS = push! (IPS, Y)
126130 H = _halfspaces (IPS)
127131 end
0 commit comments