@@ -90,6 +90,7 @@ function optimize_multiobjective!(algorithm::KirlikSayin, model::Optimizer)
90
90
model. ideal_point .*= - 1
91
91
return status, solutions
92
92
end
93
+ @assert sense == MOI. MIN_SENSE
93
94
solutions = SolutionPoint[]
94
95
# Problem with p objectives.
95
96
# Set k = 1, meaning the nondominated points will get projected
@@ -99,68 +100,62 @@ function optimize_multiobjective!(algorithm::KirlikSayin, model::Optimizer)
99
100
variables = MOI. get (model. inner, MOI. ListOfVariableIndices ())
100
101
n = MOI. output_dimension (model. f)
101
102
yI, yN = zeros (n), zeros (n)
102
- δ = sense == MOI. MIN_SENSE ? - 1 : 1
103
+ # This tolerance is really important!
104
+ δ = 1.0
103
105
scalars = MOI. Utilities. scalarize (model. f)
104
106
# Ideal and Nadir point estimation
105
107
for (i, f_i) in enumerate (scalars)
108
+ # Ideal point
106
109
MOI. set (model. inner, MOI. ObjectiveFunction {typeof(f_i)} (), f_i)
107
- MOI. set (model. inner, MOI. ObjectiveSense (), sense)
108
110
MOI. optimize! (model. inner)
109
111
status = MOI. get (model. inner, MOI. TerminationStatus ())
110
112
if ! _is_scalar_status_optimal (status)
111
113
return status, nothing
112
114
end
113
115
_, Y = _compute_point (model, variables, f_i)
114
- yI[i] = Y + 1
115
- model. ideal_point[i] = Y
116
- MOI. set (
117
- model. inner,
118
- MOI. ObjectiveSense (),
119
- sense == MOI. MIN_SENSE ? MOI. MAX_SENSE : MOI. MIN_SENSE,
120
- )
116
+ model. ideal_point[i] = yI[i] = Y
117
+ # Nadir point
118
+ MOI. set (model. inner, MOI. ObjectiveSense (), MOI. MAX_SENSE)
121
119
MOI. optimize! (model. inner)
122
120
status = MOI. get (model. inner, MOI. TerminationStatus ())
123
121
if ! _is_scalar_status_optimal (status)
124
- _warn_on_nonfinite_anti_ideal (algorithm, sense, i)
122
+ # Repair ObjectiveSense before exiting
123
+ MOI. set (model. inner, MOI. ObjectiveSense (), MOI. MIN_SENSE)
124
+ _warn_on_nonfinite_anti_ideal (algorithm, MOI. MIN_SENSE, i)
125
125
return status, nothing
126
126
end
127
127
_, Y = _compute_point (model, variables, f_i)
128
- yN[i] = Y
128
+ yN[i] = Y + δ
129
+ MOI. set (model. inner, MOI. ObjectiveSense (), MOI. MIN_SENSE)
129
130
end
130
- # Reset the sense after modifying it.
131
- MOI. set (model. inner, MOI. ObjectiveSense (), sense)
132
131
L = [_Rectangle (_project (yI, k), _project (yN, k))]
133
- SetType = ifelse (
134
- sense == MOI. MIN_SENSE,
135
- MOI. LessThan{Float64},
136
- MOI. GreaterThan{Float64},
137
- )
138
132
status = MOI. OPTIMAL
139
133
while ! isempty (L)
140
134
if _time_limit_exceeded (model, start_time)
141
- status = MOI. TIME_LIMIT
142
- break
135
+ return MOI. TIME_LIMIT, solutions
143
136
end
144
- Rᵢ = L[ argmax ([_volume (Rᵢ, _project (yI, k)) for Rᵢ in L])]
145
- lᵢ, uᵢ = Rᵢ . l, Rᵢ . u
137
+ max_volume_index = argmax ([_volume (Rᵢ, _project (yI, k)) for Rᵢ in L])
138
+ uᵢ = L[max_volume_index] . u
146
139
# Solving the first stage model: P_k(ε)
147
- # Set ε := uᵢ
148
- ε = insert! ( copy (uᵢ), k, 0.0 )
149
- ε_constraints = Any[]
140
+ # minimize: f_1(x)
141
+ # s.t.: f_i(x) <= u_i - δ
142
+ @assert k == 1
150
143
MOI. set (
151
144
model. inner,
152
145
MOI. ObjectiveFunction {typeof(scalars[k])} (),
153
146
scalars[k],
154
147
)
148
+ ε_constraints = Any[]
155
149
for (i, f_i) in enumerate (scalars)
156
- if i != k
157
- ci = MOI. Utilities. normalize_and_add_constraint (
158
- model. inner,
159
- f_i,
160
- SetType (ε[i] + δ),
161
- )
162
- push! (ε_constraints, ci)
150
+ if i == k
151
+ continue
163
152
end
153
+ ci = MOI. Utilities. normalize_and_add_constraint (
154
+ model. inner,
155
+ f_i,
156
+ MOI. LessThan {Float64} (uᵢ[i- 1 ] - δ),
157
+ )
158
+ push! (ε_constraints, ci)
164
159
end
165
160
MOI. optimize! (model. inner)
166
161
if ! _is_scalar_status_optimal (model)
@@ -171,7 +166,7 @@ function optimize_multiobjective!(algorithm::KirlikSayin, model::Optimizer)
171
166
zₖ = MOI. get (model. inner, MOI. ObjectiveValue ())
172
167
# Solving the second stage model: Q_k(ε, zₖ)
173
168
# Set objective sum(model.f)
174
- sum_f = sum ( 1.0 * s for s in scalars)
169
+ sum_f = MOI . Utilities . operate ( + , Float64, scalars... )
175
170
MOI. set (model. inner, MOI. ObjectiveFunction {typeof(sum_f)} (), sum_f)
176
171
# Constraint to eliminate weak dominance
177
172
zₖ_constraint = MOI. Utilities. normalize_and_add_constraint (
0 commit comments