Multi-fidelity optimization can introduce a few edge-cases because the individuals inside the generation(s) being aggregated may have
been evaluated with different fidelity values, which can give biased results.
When OptimizerMies
is constructed with multi_fidelity
set to TRUE
, it typically evaluates some configurations multiple times,
at first with a lower fidelity, followed by an evaluation at "full" fidelity.
fitness_aggregator
will only be called for generations containing entirely full-fidelity-evaluations will be aggregated.
This is achieved by caching aggregated fitness values in the $data_extra
field of the Archive
and only ever calling
fitness_aggregator
for a generation that does not have a cached value. Since mies_step_fidelity()
will
count low-fidelity evaluations as part of the "previous" generation, fitness_aggregator
will not see them.
Note, however that if fitness_aggregator
returns NULL
, it will be called again should a second evaluation occur in the same generation,
since NULL
is not cached and instead treated as absent.
It is possible for fitness_aggregator
to see fitness values that were evaluated with different fidelities when using OptimizerMies
,
and
fidelity_monotonic
is set to TRUE
and fidelity decreases (unlikely setup), or
if fidelity_current_gen_only
is set to FALSE
(advanced usage), or
The value returned by the fidelity
configuration parameter (not fidelity_offspring
) changes over the course of optimization and
include_previous_generations
of TerminatorGenerationStagnation
is set to TRUE
.
(1) and (2) only need consideration in advanced scenarios, but (3) may be a common, e.g. when doing multi-fidelity optimization
and stopping on reaching an overall dominated hypervolume target. In this case, it may be necessary to inspect the budget
value given to fitness_aggregator
and to remove all individuals evaluated with a different than the current fidelity.
When using a custom-written optimization loop, case (1) relates to fidelity_monotonic
argument of mies_step_fidelity()
and mies_init_population()
,
and case (2) relates to the current_gen_only
argument of mies_step_fidelity()
and the fidelity_new_individuals_only
argument of mies_init_population()
.
Case (3) relates to changing the fidelity given to mies_step_fidelity()
if that function is used, or to changing the fidelity given to mies_evaluate_offspring()
if
mies_step_fidelity()
is not used.