Applies a fitness_aggregator
function to the values that were alive in the archive at at any generation.
mies_aggregate_single_generation()
is used, see there for more information about fitness_aggregator
.
Generations for which fitness_aggregator
returns NULL
, or which are not present in any dob
in the archive,
or which contain no alive individuals (e.g. because eol
is smaller or equal dob
for all of them) are ignored.
as.list()
is applied to the values returned by fitness_aggregator
, and data.table::rbindlist()
is called on
the list of resulting values. If the first non-NULL
-value returned by fitness_aggregator
, then data.table::rbindlist()
is called with fill = TRUE
and use.names = TRUE
.
If no non-empty generations are present, or fitness_aggregator
returns NULL
on every call, then the return value
is data.table(dob = numeric(0))
.
In contrast with mies_aggregate_generations()
, mies_generate_apply()
can construct aggregated values for
entire fitness matrices, not only individual objectives (see examples). However, mies_aggregate_generations()
is simpler
if per-objective aggregates are desired.
mies_generation_apply(
archive,
fitness_aggregator,
include_previous_generations = FALSE
)
(Archive
)
The archive over which to aggregate.
(function
)
Aggregation function, called with information about alive individuals of each generation. See mies_aggregate_single_generation()
.
(logical(1)
)
Aggregate all individuals that were alive at generation
or at any point before that.
Duplicates with the same x_id
are removed, meaning that if an individual was re-evaluated with different fidelity, only the last
re-evaluation is counted.
However, note that individuals from different generations may still have been evaluated with different fidelity, so if
Default FALSE
.
data.table
with columns dob
, next to the columns constructed from the return values of fitness_aggregator
.
set.seed(1)
library("bbotk")
lgr::threshold("warn")
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 = trm("evals", n_evals = 40))
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)
#> x1 x2 x_domain y1 y2
#> <num> <num> <list> <num> <num>
#> 1: 1 -1 <list[2]> 1 -1
# Aggregated hypervolume of individuals alive in each gen:
mies_generation_apply(oi$archive, function(fitnesses) {
domhv(fitnesses)
})
#> dob V1
#> <num> <num>
#> 1: 1 0.4299653
#> 2: 2 0.4842743
#> 3: 3 0.6508345
#> 4: 4 0.8669871
#> 5: 5 0.8932747
#> 6: 6 0.8987237
#> 7: 7 0.9668899
#> 8: 8 0.9674088
#> 9: 9 1.0000000
#> 10: 10 1.0000000
# Aggregated hypervolume of all points evaluated up to each gen
# (may be slightly more, since the domhv of more points is evaluated).
# This would be the dominated hypervolume of the result set at each
# generation:
mies_generation_apply(oi$archive, function(fitnesses) {
domhv(fitnesses)
}, include_previous_generations = TRUE)
#> dob V1
#> <num> <num>
#> 1: 1 0.4299653
#> 2: 2 0.4900229
#> 3: 3 0.6562904
#> 4: 4 0.8724430
#> 5: 5 0.8986106
#> 6: 6 0.9286387
#> 7: 7 0.9722402
#> 8: 8 0.9727591
#> 9: 9 1.0000000
#> 10: 10 1.0000000
# The following are simpler with mies_aggregate_single_generations():
mies_generation_apply(oi$archive, function(fitnesses) {
apply(fitnesses, 2, mean)
})
#> dob y1 y2
#> <num> <num> <num>
#> 1: 1 0.5296734 0.3236138
#> 2: 2 0.5285369 0.5169834
#> 3: 3 0.6970645 0.5814416
#> 4: 4 0.7709625 0.6907804
#> 5: 5 0.8663453 0.8039020
#> 6: 6 0.8563497 0.8824235
#> 7: 7 0.8854497 0.9866064
#> 8: 8 0.9382245 0.9870996
#> 9: 9 0.9490188 1.0000000
#> 10: 10 0.9609022 1.0000000
# Compare:
mies_aggregate_generations(oi, aggregations = list(mean = mean))
#> dob mean.y1 mean.y2
#> <int> <num> <num>
#> 1: 1 0.5296734 0.3236138
#> 2: 2 0.5285369 0.5169834
#> 3: 3 0.6970645 0.5814416
#> 4: 4 0.7709625 0.6907804
#> 5: 5 0.8663453 0.8039020
#> 6: 6 0.8563497 0.8824235
#> 7: 7 0.8854497 0.9866064
#> 8: 8 0.9382245 0.9870996
#> 9: 9 0.9490188 1.0000000
#> 10: 10 0.9609022 1.0000000
mies_generation_apply(oi$archive, function(objectives_unscaled) {
apply(objectives_unscaled, 2, mean)
})
#> dob y1 y2
#> <num> <num> <num>
#> 1: 1 0.5296734 -0.3236138
#> 2: 2 0.5285369 -0.5169834
#> 3: 3 0.6970645 -0.5814416
#> 4: 4 0.7709625 -0.6907804
#> 5: 5 0.8663453 -0.8039020
#> 6: 6 0.8563497 -0.8824235
#> 7: 7 0.8854497 -0.9866064
#> 8: 8 0.9382245 -0.9870996
#> 9: 9 0.9490188 -1.0000000
#> 10: 10 0.9609022 -1.0000000
# Compare:
mies_aggregate_generations(oi, aggregations = list(mean = mean),
as_fitnesses = FALSE)
#> dob mean.y1 mean.y2
#> <int> <num> <num>
#> 1: 1 0.5296734 -0.3236138
#> 2: 2 0.5285369 -0.5169834
#> 3: 3 0.6970645 -0.5814416
#> 4: 4 0.7709625 -0.6907804
#> 5: 5 0.8663453 -0.8039020
#> 6: 6 0.8563497 -0.8824235
#> 7: 7 0.8854497 -0.9866064
#> 8: 8 0.9382245 -0.9870996
#> 9: 9 0.9490188 -1.0000000
#> 10: 10 0.9609022 -1.0000000