Skip to content

Commit 6e8bee8

Browse files
authored
Add two-stage solve for EpsilonConstraint (#172)
1 parent da4c7cf commit 6e8bee8

File tree

1 file changed

+25
-16
lines changed

1 file changed

+25
-16
lines changed

src/algorithms/EpsilonConstraint.jl

Lines changed: 25 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -105,35 +105,44 @@ function minimize_multiobjective!(
105105
solutions = SolutionPoint[only(solution_1), only(solution_2)]
106106
f1, f2 = MOI.Utilities.eachscalar(f)
107107
MOI.set(inner, MOI.ObjectiveFunction{typeof(f2)}(), f2)
108-
# Add epsilon constraint
108+
# Add epsilon constraints
109+
u_1 = right
110+
c_1 = MOI.constant(f1, Float64)
111+
ci_1 =
112+
MOI.Utilities.normalize_and_add_constraint(inner, f1, MOI.LessThan(u_1))
113+
u_2 = max(solution_1[1].y[2], solution_2[1].y[2])
114+
c_2 = MOI.constant(f2, Float64)
115+
ci_2 =
116+
MOI.Utilities.normalize_and_add_constraint(inner, f2, MOI.LessThan(u_2))
109117
variables = MOI.get(inner, MOI.ListOfVariableIndices())
110-
bound = right - ε
111-
constant = MOI.constant(f1, Float64)
112-
ci = MOI.Utilities.normalize_and_add_constraint(
113-
model,
114-
f1,
115-
MOI.LessThan{Float64}(bound);
116-
allow_modify_function = true,
117-
)
118-
bound -= constant
119118
status = MOI.OPTIMAL
120119
for _ in 3:n_points
121120
if (ret = _check_premature_termination(model)) !== nothing
122121
status = ret
123122
break
124123
end
125-
MOI.set(model, MOI.ConstraintSet(), ci, MOI.LessThan{Float64}(bound))
124+
# First-stage solve: minimize f₂: f₁ <= u₁ - ε
125+
MOI.set(inner, MOI.ObjectiveFunction{typeof(f2)}(), f2)
126+
MOI.set(inner, MOI.ConstraintSet(), ci_1, MOI.LessThan(u_1 - c_1 - ε))
127+
MOI.set(inner, MOI.ConstraintSet(), ci_2, MOI.LessThan(u_2 - c_2))
128+
optimize_inner!(model)
129+
if !_is_scalar_status_optimal(model)
130+
break
131+
end
132+
# Second-stage solve: minimize f₁: f₂ <= f₂^*
133+
f_2_opt = MOI.get(inner, MOI.ObjectiveValue())::Float64
134+
MOI.set(inner, MOI.ObjectiveFunction{typeof(f1)}(), f1)
135+
MOI.set(inner, MOI.ConstraintSet(), ci_2, MOI.LessThan(f_2_opt - c_2))
126136
optimize_inner!(model)
127137
if !_is_scalar_status_optimal(model)
128138
break
129139
end
130140
X, Y = _compute_point(model, variables, f)
131141
_log_subproblem_solve(model, Y)
132-
if isempty(solutions) || !(Y solutions[end].y)
133-
push!(solutions, SolutionPoint(X, Y))
134-
end
135-
bound = min(Y[1] - constant - ε, bound - ε)
142+
push!(solutions, SolutionPoint(X, Y))
143+
u_1 = Y[1]
136144
end
137-
MOI.delete(model, ci)
145+
MOI.delete(inner, ci_1)
146+
MOI.delete(inner, ci_2)
138147
return status, solutions
139148
end

0 commit comments

Comments
 (0)