| mlr_terminators_genperfreached | R Documentation | 
Terminator that terminates when a value, aggregated over generations, reaches a target value.
The user-supplied fitness_aggregator function is called whenever the archive of evaluated configurations contains a new generation.
The function is supplied with the fitness values, and optionally other data, of all individuals that are alive at that point
(include_previous_generations = FALSE) or at any point (include_previous_generations = TRUE).
Its result is saved inside the $data_extra field of the Archive object.
Termination is then signaled when the aggregated value meets or exceeds level.
The mies_aggregate_single_generation() function is used, see the documentation there for the functioning of fitness_aggregator.
The fitness_aggregator functions used for termination must return a scalar value or NULL, if a generation should be ignored.
The value returned by fitness_aggregator should be increasing for better performance, even if the underlying objective is being minimized.
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.
This Terminator can be created with the short access form trm() (trms() to get a list),
or through the dictionary mlr_terminators in the following way:
# preferred
trm("genperfreached")
trms("genperfreached")  # takes vector IDs, returns list of Terminators
# long form
mlr_terminators$get("genperfreached")
fitness_aggregator :: function
Aggregation function, called with information about alive individuals of each generation.
This argument is passed to mies_aggregate_single_generation(), see there for more details.
The aggregated values returned by fitness_aggregator should be maximized, so a larger value must be returned to indicate improvement in a generation,
even if an underlying objective is being minimized. The return value must be a scalar numeric(1).
include_previous_generations :: logical(1)
Whether to aggregate over all individuals that were evaluated (TRUE), or only the individuals alive in the current generation (FALSE).
If multi-fidelity optimization is being performed and individuals were re-evaluated with a different fidelity, their x_id will be the same and only
the last fidelity-reevaluation will be given to fitness_aggregator. However, individuals from different generations may still have been evaluated
with different fidelity and it may be necessary to inspect the budget value given to fitness_aggregator if include_previous_generations is TRUE in a
multi-fidelity-setting. See the "Multi-Fidelity Optimization" section for more.
level :: numeric(1)
Minimum aggregated value for which to terminate.
bbotk::Terminator -> TerminatorGenerationPerfReached
new()Initialize the TerminatorGenerationPerfReached object.
TerminatorGenerationPerfReached$new()
is_terminated()Is TRUE if when the termination criterion is matched, FALSE otherwise.
TerminatorGenerationPerfReached$is_terminated(archive)
archiveArchive
Archive to check.
logical(1): Whether to terminate.
clone()The objects of this class are cloneable with this method.
TerminatorGenerationPerfReached$clone(deep = FALSE)
deepWhether to make a deep clone.
set.seed(1)
library("bbotk")
lgr::threshold("warn")
# Terminate when hypervolume with nadir `c(0, 0, ...)`
# does not improve for 3 generations by at least 0.1:
tg <- trm("genperfreached",
  fitness_aggregator = function(fitnesses) domhv(fitnesses),
  include_previous_generations = TRUE,
  level = 1
)
set.seed(1)
objective <- ObjectiveRFun$new(
  fun = function(xs) {
    list(y1 = xs$x1, y2 = xs$x2)
  },
  domain = ps(x1 = p_dbl(0, 1), x2 = p_dbl(-1, 0)),
  codomain = ps(y1 = p_dbl(0, 1, tags = "maximize"),
    y2 = p_dbl(-1, 0, tags = "minimize"))
)
oi <- OptimInstanceMultiCrit$new(objective, terminator = tg)
op <- opt("mies",
  lambda = 4, mu = 4,
  mutator = mut("gauss", sdev = 0.1),
  recombinator = rec("xounif"),
  parent_selector = sel("random"),
  survival_selector = sel("best", scl("hypervolume"))
)
op$optimize(oi)
# the observed aggregated values:
oi$archive$data_extra$TerminatorGenerationPerfReached
# ... or as calculated by mies_generation_apply
mies_generation_apply(oi$archive, function(fitnesses) {
  domhv(fitnesses)
}, include_previous_generations = TRUE)
#' @export
Add the following code to your website.
For more information on customizing the embed code, read Embedding Snippets.