Apply a Selector operator to a subset of configurations inside an OptimInstance and return the index within the archive (when get_indivs FALSE) or the configurations themselves (when get_indivs is TRUE).

It is not strictly necessary for the selector to select unique individuals / individuals without replacement.

Individuals are selected independently of whether they are "alive" or not. To select only from alive individuals, set rows to inst$archive$data[, which(is.na(eol))].

mies_select_from_archive(
  inst,
  n_select,
  rows,
  selector = SelectorBest$new()$prime(inst$search_space),
  group_size = 1,
  get_indivs = TRUE
)

Arguments

inst

(OptimInstance)
Optimization instance to evaluate.

n_select

(integer(1))
Number of individuals to select.

rows

optional (integer)
Indices of rows within inst to consider. If this is not given, then the entire archive is used.

selector

(Selector)
Selector operator that selects individuals depending on configuration values and objective results. When 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. Defaults to SelectorBest.
The Selector must be primed on a superset of inst$search_space; this includes the "budget" component when performing multi-fidelity optimization. All components on which selector is primed on must occur in the archive.
The given Selector may return duplicates.

group_size

(integer)
Sampling group size hint, indicating that the caller would prefer there to not be any duplicates within this group size. The Selector may or may not ignore this value, however. This may possibly happen because of certain configuration parameters, or because the input size is too small.
Must either be a scalar value or sum up to n_select. Must be non-negative. A scalar value of 0 is interpreted the same as 1.
Default is 1.

get_indivs

(logical(1))
Whether to return configuration values from within the archive (TRUE) or just the indices within the archive (FALSE). Default is TRUE.

Value

integer | data.table: Selected individuals, either index into inst or subset of archive table, depending on get_indivs.

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)
)

s = sel("best")
s$prime(oi$search_space)

mies_init_population(inst = oi, mu = 6)

oi$archive
#> <Archive>
#>        x     y   dob   eol  x_id     Obj           timestamp batch_nr
#>    <num> <num> <num> <num> <num>   <num>              <POSc>    <int>
#> 1: -0.41  3.67     1    NA     1 3.8e-04 2024-05-13 04:41:09        1
#> 2:  0.23  1.96     1    NA     2 1.1e-01 2024-05-13 04:41:09        1
#> 3:  1.44  1.77     1    NA     3 1.4e+00 2024-05-13 04:41:09        1
#> 4:  3.45 -1.63     1    NA     4 9.4e-07 2024-05-13 04:41:09        1
#> 5: -0.79 -0.76     1    NA     5 3.0e-01 2024-05-13 04:41:09        1
#> 6:  3.39 -0.94     1    NA     6 5.5e-05 2024-05-13 04:41:09        1

# Default: get individuals
mies_select_from_archive(oi, n_select = 2, rows = 1:6, selector = s)
#>             x          y
#>         <num>      <num>
#> 1: -0.7899084 -0.7641526
#> 2:  1.4371202  1.7746843

# Alternatively: get rows within archive
mies_select_from_archive(oi, n_select = 2, rows = 1:6, selector = s,
  get_indivs = FALSE)
#> [1] 5 3

# Rows gotten from archive are relative from *all* rows, not from archive[rows]:
mies_select_from_archive(oi, n_select = 2, rows = 3:6, selector = s,
  get_indivs = FALSE)
#> [1] 3 5

##
# When using additional components: mies_select_from_archive learns about
# additional components from primed selector.

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

mies_init_population(inst = oi, mu = 6,
  additional_component_sampler = Sampler1DRfun$new(
    param = ParamDbl$new("additional", -1, 1), rfun = function(n) -1
  )
)

oi$archive
#> <Archive>
#>    additional     x     y   dob   eol  x_id   Obj           timestamp batch_nr
#>         <num> <num> <num> <num> <num> <num> <num>              <POSc>    <int>
#> 1:         -1  2.96   2.9     1    NA     1 0.335 2024-05-13 04:41:09        1
#> 2:         -1  2.01   1.9     1    NA     2 1.973 2024-05-13 04:41:09        1
#> 3:         -1  2.77   2.7     1    NA     3 0.684 2024-05-13 04:41:09        1
#> 4:         -1 -1.35   1.3     1    NA     4 0.028 2024-05-13 04:41:09        1
#> 5:         -1  2.34   1.2     1    NA     5 0.907 2024-05-13 04:41:09        1
#> 6:         -1  0.47   2.7     1    NA     6 0.112 2024-05-13 04:41:09        1

# Wrong: using selector primed only on search space. The resulting
# individuals do not have the additional component.
mies_select_from_archive(oi, n_select = 2, rows = 1:6, selector = s)
#>           x        y
#>       <num>    <num>
#> 1: 2.342266 1.178317
#> 2: 2.010800 1.882361

# Correct: selector must be primed on search space + additional component
mies_prime_operators(oi$search_space, selectors = list(s),
  additional_components = ps(additional = p_dbl(-1, 1)))

mies_select_from_archive(oi, n_select = 2, rows = 1:6, selector = s)
#>           x        y additional
#>       <num>    <num>      <num>
#> 1: 2.010800 1.882361         -1
#> 2: 2.342266 1.178317         -1