Skip to content

Commit dabce8d

Browse files
authored
Fix scaling issue in DominguezRios (#104)
1 parent 297b9f5 commit dabce8d

File tree

1 file changed

+16
-1
lines changed

1 file changed

+16
-1
lines changed

src/algorithms/DominguezRios.jl

Lines changed: 16 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -188,6 +188,10 @@ function optimize_multiobjective!(algorithm::DominguezRios, model::Optimizer)
188188
end
189189
MOI.set(model.inner, MOI.ObjectiveSense(), sense)
190190
ϵ = 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 / ϵ)
191195
push!(L[1], _DominguezRiosBox(yI, yN, 0.0))
192196
t_max = MOI.add_variable(model.inner)
193197
solutions = SolutionPoint[]
@@ -200,20 +204,31 @@ function optimize_multiobjective!(algorithm::DominguezRios, model::Optimizer)
200204
end
201205
i, k = _select_next_box(L, k)
202206
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)
204210
constraints = [
205211
MOI.Utilities.normalize_and_add_constraint(
206212
model.inner,
213+
# `w` is the scaled version here. This epigraph constraint will
214+
# make `t_max` similarly scaled.
207215
t_max - (w[i] * (scalars[i] - yI[i])),
208216
MOI.GreaterThan(0.0),
209217
) for i in 1:n
210218
]
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`
211222
new_f = t_max + ϵ * sum(w[i] * (scalars[i] - yI[i]) for i in 1:n)
212223
MOI.set(model.inner, MOI.ObjectiveFunction{typeof(new_f)}(), new_f)
213224
MOI.optimize!(model.inner)
214225
if _is_scalar_status_optimal(model)
215226
X, Y = _compute_point(model, variables, model.f)
216227
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
217232
if (obj < 1) && all(yI .< B.u)
218233
push!(solutions, SolutionPoint(X, Y))
219234
_update!(L, Y, yI, yN)

0 commit comments

Comments
 (0)