@@ -108,6 +108,7 @@ mutable struct Optimizer <: MOI.AbstractOptimizer
108
108
time_limit_sec:: Union{Nothing,Float64}
109
109
solve_time:: Float64
110
110
ideal_point:: Vector{Float64}
111
+ compute_ideal_point:: Bool
111
112
112
113
function Optimizer (optimizer_factory)
113
114
return new (
@@ -119,6 +120,7 @@ mutable struct Optimizer <: MOI.AbstractOptimizer
119
120
nothing ,
120
121
NaN ,
121
122
Float64[],
123
+ default (ComputeIdealPoint ()),
122
124
)
123
125
end
124
126
end
@@ -130,6 +132,7 @@ function MOI.empty!(model::Optimizer)
130
132
model. termination_status = MOI. OPTIMIZE_NOT_CALLED
131
133
model. solve_time = NaN
132
134
empty! (model. ideal_point)
135
+ model. compute_ideal_point = default (ComputeIdealPoint ())
133
136
return
134
137
end
135
138
@@ -139,7 +142,8 @@ function MOI.is_empty(model::Optimizer)
139
142
isempty (model. solutions) &&
140
143
model. termination_status == MOI. OPTIMIZE_NOT_CALLED &&
141
144
isnan (model. solve_time) &&
142
- isempty (model. ideal_point)
145
+ isempty (model. ideal_point) &&
146
+ model. compute_ideal_point == default (ComputeIdealPoint ())
143
147
end
144
148
145
149
MOI. supports_incremental_interface (:: Optimizer ) = true
@@ -351,6 +355,33 @@ struct LexicographicAllPermutations <: AbstractAlgorithmAttribute end
351
355
352
356
default (:: LexicographicAllPermutations ) = true
353
357
358
+ """
359
+ ComputeIdealPoint <: AbstractOptimizerAttribute -> Bool
360
+
361
+ Controls whether to compute the ideal point.
362
+
363
+ Defaults to true`.
364
+
365
+ If this attribute is set to `true`, the ideal point can be queried using the
366
+ `MOI.ObjectiveBound` attribute.
367
+
368
+ Computing the ideal point requires as many solves as the dimension of the
369
+ objective function. Thus, if you do not need the ideal point information, you
370
+ can improve the performance of MOA by setting this attribute to `false`.
371
+ """
372
+ struct ComputeIdealPoint <: MOI.AbstractOptimizerAttribute end
373
+
374
+ default (:: ComputeIdealPoint ) = true
375
+
376
+ MOI. supports (:: Optimizer , :: ComputeIdealPoint ) = true
377
+
378
+ function MOI. set (model:: Optimizer , :: ComputeIdealPoint , value:: Bool )
379
+ model. compute_ideal_point = value
380
+ return
381
+ end
382
+
383
+ MOI. get (model:: Optimizer , :: ComputeIdealPoint ) = model. compute_ideal_point
384
+
354
385
# ## RawOptimizerAttribute
355
386
356
387
function MOI. supports (model:: Optimizer , attr:: MOI.RawOptimizerAttribute )
@@ -530,16 +561,12 @@ function MOI.delete(model::Optimizer, ci::MOI.ConstraintIndex)
530
561
return
531
562
end
532
563
533
- function MOI. optimize! (model:: Optimizer )
534
- start_time = time ()
535
- empty! (model. solutions)
536
- model. termination_status = MOI. OPTIMIZE_NOT_CALLED
537
- if model. f === nothing
538
- model. termination_status = MOI. INVALID_MODEL
539
- return
540
- end
564
+ function _compute_ideal_point (model:: Optimizer )
541
565
objectives = MOI. Utilities. eachscalar (model. f)
542
566
model. ideal_point = fill (NaN , length (objectives))
567
+ if ! MOI. get (model, ComputeIdealPoint ())
568
+ return
569
+ end
543
570
for (i, f) in enumerate (objectives)
544
571
MOI. set (model. inner, MOI. ObjectiveFunction {typeof(f)} (), f)
545
572
MOI. optimize! (model. inner)
@@ -548,6 +575,18 @@ function MOI.optimize!(model::Optimizer)
548
575
model. ideal_point[i] = MOI. get (model. inner, MOI. ObjectiveValue ())
549
576
end
550
577
end
578
+ return
579
+ end
580
+
581
+ function MOI. optimize! (model:: Optimizer )
582
+ start_time = time ()
583
+ empty! (model. solutions)
584
+ model. termination_status = MOI. OPTIMIZE_NOT_CALLED
585
+ if model. f === nothing
586
+ model. termination_status = MOI. INVALID_MODEL
587
+ return
588
+ end
589
+ _compute_ideal_point (model)
551
590
algorithm = something (model. algorithm, default (Algorithm ()))
552
591
status, solutions = optimize_multiobjective! (algorithm, model)
553
592
model. termination_status = status
0 commit comments