@@ -188,6 +188,10 @@ function optimize_multiobjective!(algorithm::DominguezRios, model::Optimizer)
188
188
end
189
189
MOI. set (model. inner, MOI. ObjectiveSense (), sense)
190
190
ϵ = 1 / (2 * n * (maximum (yN - yI) - 1 ))
191
+ # If ϵ is small, then the scalar objectives can contain terms that fall
192
+ # below the tolerance level of the solver. To fix this, we rescale the
193
+ # objective so that the coefficients have magnitude `1e+00` or larger.
194
+ scale = max (1.0 , 1 / ϵ)
191
195
push! (L[1 ], _DominguezRiosBox (yI, yN, 0.0 ))
192
196
t_max = MOI. add_variable (model. inner)
193
197
solutions = SolutionPoint[]
@@ -200,20 +204,31 @@ function optimize_multiobjective!(algorithm::DominguezRios, model::Optimizer)
200
204
end
201
205
i, k = _select_next_box (L, k)
202
206
B = L[k][i]
203
- w = 1 ./ max .(1 , B. u - yI)
207
+ # We're goign to scale `w` here by `scale` instead of the usual
208
+ # `1 / max(...)`. It will show up in a few places bbelow.
209
+ w = scale ./ max .(1 , B. u - yI)
204
210
constraints = [
205
211
MOI. Utilities. normalize_and_add_constraint (
206
212
model. inner,
213
+ # `w` is the scaled version here. This epigraph constraint will
214
+ # make `t_max` similarly scaled.
207
215
t_max - (w[i] * (scalars[i] - yI[i])),
208
216
MOI. GreaterThan (0.0 ),
209
217
) for i in 1 : n
210
218
]
219
+ # There's no need to scale anything explicitly here:
220
+ # * t_max is already covered in `constraints`
221
+ # * the `ϵ` term is already covered in `w`
211
222
new_f = t_max + ϵ * sum (w[i] * (scalars[i] - yI[i]) for i in 1 : n)
212
223
MOI. set (model. inner, MOI. ObjectiveFunction {typeof(new_f)} (), new_f)
213
224
MOI. optimize! (model. inner)
214
225
if _is_scalar_status_optimal (model)
215
226
X, Y = _compute_point (model, variables, model. f)
216
227
obj = MOI. get (model. inner, MOI. ObjectiveValue ())
228
+ # We need to undo the scaling of the scalar objective. There's no
229
+ # need to unscale `Y` because we have evaluated this explicitly from
230
+ # the modified `model.f`.
231
+ obj /= scale
217
232
if (obj < 1 ) && all (yI .< B. u)
218
233
push! (solutions, SolutionPoint (X, Y))
219
234
_update! (L, Y, yI, yN)
0 commit comments