@@ -123,6 +123,7 @@ mutable struct Optimizer <: MOI.AbstractOptimizer
123123 solve_time:: Float64
124124 ideal_point:: Vector{Float64}
125125 compute_ideal_point:: Bool
126+ subproblem_count:: Int
126127
127128 function Optimizer (optimizer_factory)
128129 return new (
@@ -135,6 +136,7 @@ mutable struct Optimizer <: MOI.AbstractOptimizer
135136 NaN ,
136137 Float64[],
137138 default (ComputeIdealPoint ()),
139+ 0 ,
138140 )
139141 end
140142end
@@ -146,6 +148,7 @@ function MOI.empty!(model::Optimizer)
146148 model. termination_status = MOI. OPTIMIZE_NOT_CALLED
147149 model. solve_time = NaN
148150 empty! (model. ideal_point)
151+ model. subproblem_count = 0
149152 return
150153end
151154
394397
395398MOI. get (model:: Optimizer , :: ComputeIdealPoint ) = model. compute_ideal_point
396399
400+ # ## SubproblemCount
401+
402+ """
403+ SubproblemCount <: AbstractModelAttribute -> Int
404+
405+ A result attribute for querying the total number of subproblem solves by an
406+ algorithm.
407+ """
408+ struct SubproblemCount <: MOI.AbstractModelAttribute end
409+
410+ MOI. is_set_by_optimize (:: SubproblemCount ) = true
411+
412+ MOI. get (model:: Optimizer , :: SubproblemCount ) = model. subproblem_count
413+
397414# ## RawOptimizerAttribute
398415
399416function MOI. supports (model:: Optimizer , attr:: MOI.RawOptimizerAttribute )
@@ -573,6 +590,18 @@ function MOI.delete(model::Optimizer, ci::MOI.ConstraintIndex)
573590 return
574591end
575592
593+ """
594+ optimize_inner!(model::Optimizer)
595+
596+ A function that must be called instead of `MOI.optimize!(model.inner)` because
597+ it also increments the `subproblem_count`.
598+ """
599+ function optimize_inner! (model:: Optimizer )
600+ MOI. optimize! (model. inner)
601+ model. subproblem_count += 1
602+ return
603+ end
604+
576605function _compute_ideal_point (model:: Optimizer , start_time)
577606 for (i, f) in enumerate (MOI. Utilities. eachscalar (model. f))
578607 if _time_limit_exceeded (model, start_time)
@@ -582,7 +611,7 @@ function _compute_ideal_point(model::Optimizer, start_time)
582611 continue # The algorithm already updated this information
583612 end
584613 MOI. set (model. inner, MOI. ObjectiveFunction {typeof(f)} (), f)
585- MOI . optimize ! (model. inner )
614+ optimize_inner ! (model)
586615 status = MOI. get (model. inner, MOI. TerminationStatus ())
587616 if _is_scalar_status_optimal (status)
588617 model. ideal_point[i] = MOI. get (model. inner, MOI. ObjectiveValue ())
@@ -619,6 +648,7 @@ function MOI.optimize!(model::Optimizer)
619648 start_time = time ()
620649 empty! (model. solutions)
621650 model. termination_status = MOI. OPTIMIZE_NOT_CALLED
651+ model. subproblem_count = 0
622652 if model. f === nothing
623653 model. termination_status = MOI. INVALID_MODEL
624654 empty! (model. ideal_point)
0 commit comments