@@ -41,7 +41,7 @@ function _update_search_region(
4141 bounds_to_remove = Vector{Float64}[]
4242 bounds_to_add = Dict{Vector{Float64},Vector{Vector{Vector{Float64}}}}()
4343 for u in keys (U_N)
44- if all (y .< u)
44+ if _is_less (y, u, 0 ) # k=0 here because we want to check every element
4545 push! (bounds_to_remove, u)
4646 for l in 1 : p
4747 u_l = _get_child (u, y, l)
@@ -55,7 +55,7 @@ function _update_search_region(
5555 end
5656 else
5757 for k in 1 : p
58- if (y[k] == u[k]) && all ( _project (y, k) .< _project ( u, k) )
58+ if _is_less (y, u, k)
5959 push! (U_N[u][k], y)
6060 end
6161 end
@@ -68,6 +68,21 @@ function _update_search_region(
6868 return
6969end
7070
71+ function _is_less (y, u, k)
72+ for i in 1 : length (y)
73+ if i == k
74+ if ! (y[i] == u[i])
75+ return false
76+ end
77+ else
78+ if ! (y[i] < u[i])
79+ return false
80+ end
81+ end
82+ end
83+ return true
84+ end
85+
7186function _get_child (u:: Vector{Float64} , y:: Vector{Float64} , k:: Int )
7287 @assert length (u) == length (y)
7388 return vcat (u[1 : (k- 1 )], y[k], u[(k+ 1 ): length (y)])
@@ -80,52 +95,78 @@ function _select_search_zone(
8095)
8196 upper_bounds = collect (keys (U_N))
8297 p = length (yI)
83- hvs = [
84- u[k] == yN[k] ? 0.0 : prod (_project (u, k) .- _project (yI, k)) for
85- k in 1 : p, u in upper_bounds
86- ]
87- k_star, j_star = argmax (hvs). I
88- return k_star, upper_bounds[j_star]
98+ k_star, u_star, v_star = 1 , first (upper_bounds), 0.0
99+ for k in 1 : p
100+ for u in upper_bounds
101+ if u[k] != yN[k]
102+ v = 1.0
103+ for i in 1 : p
104+ if i != k
105+ v *= u[i] - yI[i]
106+ end
107+ end
108+ if v > v_star
109+ k_star, u_star, v_star = k, u, v
110+ end
111+ end
112+ end
113+ end
114+ return k_star, u_star
89115end
90116
91117function minimize_multiobjective! (
92118 algorithm:: TambyVanderpooten ,
93119 model:: Optimizer ,
94120)
95- @assert MOI. get (model. inner, MOI. ObjectiveSense ()) == MOI. MIN_SENSE
96- warm_start_supported = false
97- if MOI. supports (model, MOI. VariablePrimalStart (), MOI. VariableIndex)
98- warm_start_supported = true
99- end
100121 solutions = Dict {Vector{Float64},Dict{MOI.VariableIndex,Float64}} ()
101- variables = MOI. get (model. inner, MOI. ListOfVariableIndices ())
102- n = MOI. output_dimension (model. f)
122+ status = _minimize_multiobjective! (
123+ algorithm,
124+ model,
125+ model. inner,
126+ model. f,
127+ solutions,
128+ ):: MOI.TerminationStatusCode
129+ return status, SolutionPoint[SolutionPoint (X, Y) for (Y, X) in solutions]
130+ end
131+
132+ function _minimize_multiobjective! (
133+ algorithm:: TambyVanderpooten ,
134+ model:: Optimizer ,
135+ inner:: MOI.ModelLike ,
136+ f:: MOI.AbstractVectorFunction ,
137+ solutions:: Dict{Vector{Float64},Dict{MOI.VariableIndex,Float64}} ,
138+ )
139+ @assert MOI. get (inner, MOI. ObjectiveSense ()) == MOI. MIN_SENSE
140+ warm_start_supported =
141+ MOI. supports (inner, MOI. VariablePrimalStart (), MOI. VariableIndex)
142+ variables = MOI. get (inner, MOI. ListOfVariableIndices ())
143+ n = MOI. output_dimension (f)
103144 yI, yN = zeros (n), zeros (n)
104- scalars = MOI. Utilities. scalarize (model . f)
145+ scalars = MOI. Utilities. scalarize (f)
105146 for (i, f_i) in enumerate (scalars)
106- MOI. set (model . inner, MOI. ObjectiveFunction {typeof(f_i)} (), f_i)
107- MOI. set (model . inner, MOI. ObjectiveSense (), MOI. MIN_SENSE)
147+ MOI. set (inner, MOI. ObjectiveFunction {typeof(f_i)} (), f_i)
148+ MOI. set (inner, MOI. ObjectiveSense (), MOI. MIN_SENSE)
108149 optimize_inner! (model)
109- status = MOI. get (model . inner, MOI. TerminationStatus ())
150+ status = MOI. get (inner, MOI. TerminationStatus ())
110151 if ! _is_scalar_status_optimal (status)
111- return status, nothing
152+ return status
112153 end
113154 _, Y = _compute_point (model, variables, f_i)
114155 _log_subproblem_solve (model, variables)
115156 yI[i] = Y
116157 model. ideal_point[i] = Y
117- MOI. set (model . inner, MOI. ObjectiveSense (), MOI. MAX_SENSE)
158+ MOI. set (inner, MOI. ObjectiveSense (), MOI. MAX_SENSE)
118159 optimize_inner! (model)
119- status = MOI. get (model . inner, MOI. TerminationStatus ())
160+ status = MOI. get (inner, MOI. TerminationStatus ())
120161 if ! _is_scalar_status_optimal (status)
121162 _warn_on_nonfinite_anti_ideal (algorithm, MOI. MIN_SENSE, i)
122- return status, nothing
163+ return status
123164 end
124165 _, Y = _compute_point (model, variables, f_i)
125166 _log_subproblem_solve (model, variables)
126167 yN[i] = Y + 1
127168 end
128- MOI. set (model . inner, MOI. ObjectiveSense (), MOI. MIN_SENSE)
169+ MOI. set (inner, MOI. ObjectiveSense (), MOI. MIN_SENSE)
129170 U_N = Dict{Vector{Float64},Vector{Vector{Vector{Float64}}}}()
130171 V = [Tuple{Vector{Float64},Vector{Float64}}[] for k in 1 : n]
131172 U_N[yN] = [[_get_child (yN, yI, k)] for k in 1 : n]
@@ -137,15 +178,15 @@ function minimize_multiobjective!(
137178 end
138179 k, u = _select_search_zone (U_N, yI, yN)
139180 MOI. set (
140- model . inner,
181+ inner,
141182 MOI. ObjectiveFunction {typeof(scalars[k])} (),
142183 scalars[k],
143184 )
144185 ε_constraints = Any[]
145186 for (i, f_i) in enumerate (scalars)
146187 if i != k
147188 ci = MOI. Utilities. normalize_and_add_constraint (
148- model . inner,
189+ inner,
149190 f_i,
150191 MOI. LessThan {Float64} (u[i] - 1 ),
151192 )
@@ -157,7 +198,7 @@ function minimize_multiobjective!(
157198 variables_start = solutions[first (U_N[u][k])]
158199 for x_i in variables
159200 MOI. set (
160- model . inner,
201+ inner,
161202 MOI. VariablePrimalStart (),
162203 x_i,
163204 variables_start[x_i],
@@ -167,27 +208,27 @@ function minimize_multiobjective!(
167208 end
168209 optimize_inner! (model)
169210 _log_subproblem_solve (model, " auxillary subproblem" )
170- status = MOI. get (model . inner, MOI. TerminationStatus ())
211+ status = MOI. get (inner, MOI. TerminationStatus ())
171212 if ! _is_scalar_status_optimal (status)
172213 MOI. delete .(model, ε_constraints)
173- return status, nothing
214+ return status
174215 end
175- y_k = MOI. get (model . inner, MOI. ObjectiveValue ())
216+ y_k = MOI. get (inner, MOI. ObjectiveValue ()):: Float64
176217 sum_f = sum (1.0 * s for s in scalars)
177- MOI. set (model . inner, MOI. ObjectiveFunction {typeof(sum_f)} (), sum_f)
218+ MOI. set (inner, MOI. ObjectiveFunction {typeof(sum_f)} (), sum_f)
178219 y_k_constraint = MOI. Utilities. normalize_and_add_constraint (
179- model . inner,
220+ inner,
180221 scalars[k],
181222 MOI. EqualTo (y_k),
182223 )
183224 optimize_inner! (model)
184- status = MOI. get (model . inner, MOI. TerminationStatus ())
225+ status = MOI. get (inner, MOI. TerminationStatus ())
185226 if ! _is_scalar_status_optimal (status)
186227 MOI. delete .(model, ε_constraints)
187228 MOI. delete (model, y_k_constraint)
188- return status, nothing
229+ return status
189230 end
190- X, Y = _compute_point (model, variables, model . f)
231+ X, Y = _compute_point (model, variables, f)
191232 _log_subproblem_solve (model, Y)
192233 MOI. delete .(model, ε_constraints)
193234 MOI. delete (model, y_k_constraint)
@@ -205,8 +246,9 @@ function minimize_multiobjective!(
205246 push! (bounds_to_remove, u_i)
206247 else
207248 for (u_j, y_j) in V[k]
208- if all (_project (u_i, k) .<= _project (u_j, k)) &&
209- isapprox (y_j[k], u_i[k]; atol = 1e-6 )
249+ if isapprox (y_j[k], u_i[k]; atol = 1e-6 ) &&
250+ _is_less_eq (u_i, u_j, k)
251+
210252 push! (bounds_to_remove, u_i)
211253 end
212254 end
@@ -219,5 +261,14 @@ function minimize_multiobjective!(
219261 end
220262 end
221263 end
222- return status, [SolutionPoint (X, Y) for (Y, X) in solutions]
264+ return status
265+ end
266+
267+ function _is_less_eq (y, u, k)
268+ for i in 1 : length (y)
269+ if i != k && ! (y[i] <= u[i])
270+ return false
271+ end
272+ end
273+ return true
223274end
0 commit comments