Choose survivors during a MIES iteration using the "Comma" survival strategy, i.e. selecting survivors from the latest generation only, using a Selector operator, and choosing "elites" from survivors from previous generations using a different Selector operator.

When n_elite is greater than the number of alive individuals from previous generations, then all these individuals from previous generations survive. In this case, it is possible that more than mu - n_elite individuals from the current generation survive. Similarly, when mu is greater than the number of alive individuals from the last generation, then all these individuals survive.

mies_survival_comma(inst, mu, survival_selector, n_elite, elite_selector, ...)

Arguments

inst

(OptimInstance)
Optimization instance to evaluate.

mu

(integer(1))
Population target size, non-negative integer.

survival_selector

(Selector)
Selector operator that selects surviving individuals depending on configuration values and objective results. When survival_selector$operate() is called, then objectives that are being minimized are multiplied with -1 (through mies_get_fitnesses), since Selectors always try to maximize fitness.
The Selector must be primed on inst$search_space; this includes the "budget" component when performing multi-fidelity optimization.
The given Selector may not return duplicates.

n_elite

(integer(1))
Number of individuals to carry over from previous generations. n_elite individuals will be selected by elite_selector, while mu - n_elite will be selected by survival_selector from the most recent generation. n_elite may be 0 (no elitism), in which case only individuals from the newest generation survive. n_elite must be strictly smaller than mu to permit any optimization progress.

elite_selector

(Selector)
Selector operator that selects "elites", i.e. surviving individuals from previous generations, depending on configuration values and objective results. When elite_selector$operate() is called, then objectives that are being minimized are multiplied with -1 (through mies_get_fitnesses()), since Selectors always try to maximize fitness.
The Selector must be primed on inst$search_space; this includes the "budget" component when performing multi-fidelity optimization.
The given Selector may not return duplicates.

...

(any)
Ignored, for compatibility with other mies_survival_* functions.

Value

invisible data.table: The value of inst$archive$data, changed in-place with eol set to the current generation for non-survivors.

Examples

set.seed(1)
library("bbotk")
lgr::threshold("warn")

# Define the objective to optimize
objective <- ObjectiveRFun$new(
  fun = function(xs) {
    z <- exp(-xs$x^2 - xs$y^2) + 2 * exp(-(2 - xs$x)^2 - (2 - xs$y)^2)
    list(Obj = z)
  },
  domain = ps(x = p_dbl(-2, 4), y = p_dbl(-2, 4)),
  codomain = ps(Obj = p_dbl(tags = "maximize"))
)

# Get a new OptimInstance
oi <- OptimInstanceSingleCrit$new(objective,
  terminator = trm("evals", n_evals = 100)
)

mies_init_population(inst = oi, mu = 3)
# Usually the offspring is generated using mies_generate_offspring()
# Here shorter for demonstration purposes.
offspring = generate_design_random(oi$search_space, 3)$data
mies_evaluate_offspring(oi, offspring = offspring)

# State before: different generations of individuals. Alive individuals have
# 'eol' set to 'NA'.
oi$archive
#> <Archive>
#>        x     y dob eol x_id     Obj              timestamp batch_nr
#> 1: -0.41  3.45   1  NA    1 7.5e-04 2023-09-20 04:41:25.18        1
#> 2:  0.23 -0.79   1  NA    2 5.1e-01 2023-09-20 04:41:25.18        1
#> 3:  1.44  3.39   1  NA    3 2.1e-01 2023-09-20 04:41:25.18        1
#> 4:  3.67 -1.63   2  NA    4 3.4e-07 2023-09-20 04:41:25.20        2
#> 5:  1.96 -0.76   2  NA    5 1.3e-02 2023-09-20 04:41:25.20        2
#> 6:  1.77 -0.94   2  NA    6 1.8e-02 2023-09-20 04:41:25.20        2

s = sel("best")
s$prime(oi$search_space)
mies_survival_comma(oi, mu = 3, survival_selector = s,
  n_elite = 2, elite_selector = s)

# sel("best") lets only the best individuals survive.
# mies_survival_comma selects from new individuals (generation 2 in this case)
# and old individuals (all others) separately: n_elite = 2 from old,
# mu - n_elite = 1 from new.
# The surviving individuals have 'eol' set to 'NA'
oi$archive
#> <Archive>
#>        x     y dob eol x_id     Obj              timestamp batch_nr
#> 1: -0.41  3.45   1   2    1 7.5e-04 2023-09-20 04:41:25.18        1
#> 2:  0.23 -0.79   1  NA    2 5.1e-01 2023-09-20 04:41:25.18        1
#> 3:  1.44  3.39   1  NA    3 2.1e-01 2023-09-20 04:41:25.18        1
#> 4:  3.67 -1.63   2   2    4 3.4e-07 2023-09-20 04:41:25.20        2
#> 5:  1.96 -0.76   2   2    5 1.3e-02 2023-09-20 04:41:25.20        2
#> 6:  1.77 -0.94   2  NA    6 1.8e-02 2023-09-20 04:41:25.20        2