@@ -15,31 +15,6 @@ 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 _compute_anchors (model:: MOA.Optimizer )
19
- anchors = Dict {Vector{Float64},Dict{MOI.VariableIndex,Float64}} ()
20
- n = MOI. output_dimension (model. f)
21
- scalars = MOI. Utilities. scalarize (model. f)
22
- variables = MOI. get (model. inner, MOI. ListOfVariableIndices ())
23
- yI, yUB = zeros (n), zeros (n)
24
- for (i, f_i) in enumerate (scalars)
25
- MOI. set (model. inner, MOI. ObjectiveFunction {typeof(f_i)} (), f_i)
26
- MOI. optimize! (model. inner)
27
- # status check
28
- X, Y = MOA. _compute_point (model, variables, model. f)
29
- model. ideal_point[i] = Y[i]
30
- yI[i] = Y[i]
31
- anchors[Y] = X
32
- MOI. set (model. inner, MOI. ObjectiveSense (), MOI. MAX_SENSE)
33
- MOI. optimize! (model. inner)
34
- # status check
35
- _, Y = MOA. _compute_point (model, variables, f_i)
36
- yUB[i] = Y
37
- MOI. set (model. inner, MOI. ObjectiveSense (), MOI. MIN_SENSE)
38
- end
39
-
40
- return yI, yUB, anchors
41
- end
42
-
43
18
function _distance (w̄, b̄, OPS, model)
44
19
n = MOI. output_dimension (model. f)
45
20
optimizer = typeof (model. inner. optimizer)
65
40
66
41
function _select_next_halfspace (H, OPS, model)
67
42
distances = [_distance (w, b, OPS, model) for (w, b) in H]
68
- @info " Distances: $(Dict (zip (H, distances))) "
69
43
index = argmax (distances)
70
44
w, b = H[index]
71
45
return distances[index], w, b
@@ -75,24 +49,45 @@ function MOA.minimize_multiobjective!(
75
49
algorithm:: MOA.Sandwiching ,
76
50
model:: MOA.Optimizer ,
77
51
)
78
- @assert MOI. get (model. inner, MOI. ObjectiveSense ()) == MOI. MIN_SENSE
79
- ε = algorithm. precision
52
+ @assert MOI. get (model. inner, MOI. ObjectiveSense ()) == MOI. MIN_SENSE
80
53
start_time = time ()
81
54
solutions = Dict {Vector{Float64},Dict{MOI.VariableIndex,Float64}} ()
82
55
variables = MOI. get (model. inner, MOI. ListOfVariableIndices ())
83
56
n = MOI. output_dimension (model. f)
84
57
scalars = MOI. Utilities. scalarize (model. f)
85
- yI, yUB, anchors = _compute_anchors (model)
86
- merge! (solutions, anchors)
87
- @info " yI: $(yI) "
88
- @info " yUB: $(yUB) "
89
- IPS = [yUB, keys (anchors)... ]
58
+ status = MOI. OPTIMAL
90
59
OPS = Tuple{Vector{Float64},Float64}[]
91
- for i in 1 : n
60
+ anchors = Dict {Vector{Float64},Dict{MOI.VariableIndex,Float64}} ()
61
+ yI, yUB = zeros (n), zeros (n)
62
+ for (i, f_i) in enumerate (scalars)
63
+ MOI. set (model. inner, MOI. ObjectiveFunction {typeof(f_i)} (), f_i)
64
+ MOI. optimize! (model. inner)
65
+ status = MOI. get (model. inner, MOI. TerminationStatus ())
66
+ if ! MOA. _is_scalar_status_optimal (model)
67
+ return status, nothing
68
+ end
69
+ X, Y = MOA. _compute_point (model, variables, model. f)
70
+ model. ideal_point[i] = Y[i]
71
+ yI[i] = Y[i]
72
+ anchors[Y] = X
73
+ MOI. set (model. inner, MOI. ObjectiveSense (), MOI. MAX_SENSE)
74
+ MOI. optimize! (model. inner)
75
+ status = MOI. get (model. inner, MOI. TerminationStatus ())
76
+ if ! MOA. _is_scalar_status_optimal (model)
77
+ MOA. _warn_on_nonfinite_anti_ideal (algorithm, MOI. MIN_SENSE, i)
78
+ return status, nothing
79
+ end
80
+ _, Y = MOA. _compute_point (model, variables, f_i)
81
+ yUB[i] = Y
82
+ MOI. set (model. inner, MOI. ObjectiveSense (), MOI. MIN_SENSE)
92
83
e_i = Float64 .(1 : n .== i)
93
84
push! (OPS, (e_i, yI[i])) # e_i' * y >= yI_i
94
85
push! (OPS, (- e_i, - yUB[i])) # -e_i' * y >= -yUB_i ⟹ e_i' * y <= yUB_i
95
86
end
87
+ @info " yI: $(yI) "
88
+ @info " yUB: $(yUB) "
89
+ IPS = [yUB, keys (anchors)... ]
90
+ merge! (solutions, anchors)
96
91
@info " IPS: $(IPS) "
97
92
@info " OPS: $(OPS) "
98
93
u = MOI. add_variables (model. inner, n)
@@ -110,19 +105,28 @@ function MOA.minimize_multiobjective!(
110
105
H = _halfspaces (IPS)
111
106
count = 0
112
107
while ! isempty (H)
108
+ if MOA. _time_limit_exceeded (model, start_time)
109
+ status = MOI. TIME_LIMIT
110
+ break
111
+ end
113
112
count += 1
114
113
@info " -- Iteration #$(count) --"
115
114
@info " HalfSpaces: $(H) "
116
115
δ, w, b = _select_next_halfspace (H, OPS, model)
117
116
@info " Selected halfspace: w: $(w) , b: $(b) "
118
117
@info " δ: $(δ) "
119
- if δ - 1e-3 <= ε # added some convergence tolerance
118
+ if δ - 1e-3 <= algorithm . precision # added some convergence tolerance
120
119
break
121
120
end
122
121
# would not terminate when precision is set to 0
123
122
new_f = sum (w[i] * (scalars[i] + u[i]) for i in 1 : n) # w' * (f(x) + u)
124
123
MOI. set (model. inner, MOI. ObjectiveFunction {typeof(new_f)} (), new_f)
125
124
MOI. optimize! (model. inner)
125
+ status = MOI. get (model. inner, MOI. TerminationStatus ())
126
+ if ! MOA. _is_scalar_status_optimal (model)
127
+ MOA. _warn_on_nonfinite_anti_ideal (algorithm, MOI. MIN_SENSE, i)
128
+ return status, nothing
129
+ end
126
130
β̄ = MOI. get (model. inner, MOI. ObjectiveValue ())
127
131
@info " β̄: $(β̄) "
128
132
X, Y = MOA. _compute_point (model, variables, model. f)
@@ -134,9 +138,6 @@ function MOA.minimize_multiobjective!(
134
138
@info " IPS: $(IPS) "
135
139
@info " OPS: $(OPS) "
136
140
H = _halfspaces (IPS)
137
- if count == 10
138
- break
139
- end
140
141
end
141
142
MOI. delete .(model. inner, f_constraints)
142
143
MOI. delete .(model. inner, u_constraints)
0 commit comments