56 if (
params.num_islands < 0) {
60 if (
static_cast<size_t>(
params.num_islands) >
pop.island_indexes.size()) {
62 "params.num_islands is greater than pop.island_indexes size in calculate_stats");
65 for (
int island=0; island<
params.num_islands; ++island)
67 auto indices =
pop.island_indexes.at(island);
68 pop_size += indices.size();
71 ArrayXf scores(pop_size);
72 ArrayXf scores_v(pop_size);
81 for (
int island=0; island<
params.num_islands; ++island)
83 auto indices =
pop.island_indexes.at(island);
84 for (
unsigned int i=0; i<indices.size(); ++i)
86 const size_t population_index = indices[i];
87 if (population_index >= this->
pop.individuals.size()) {
89 "Invalid population index in island " +
to_string(island)
91 +
" (individuals size=" +
to_string(this->
pop.individuals.size()) +
")");
94 const auto& p = this->
pop.individuals.at(population_index);
100 float fitness_loss = 0.0f;
101 float fitness_loss_v = 0.0f;
102 unsigned individual_size = 0;
103 unsigned individual_complexity = 0;
105 fitness_loss = p->fitness.get_loss();
106 fitness_loss_v = p->fitness.get_loss_v();
107 individual_size = p->get_size();
108 individual_complexity = p->get_complexity();
109 }
catch (
const std::exception& e) {
111 "Failed to get fitness/size/complexity from individual at population index "
112 +
to_string(population_index) +
": " + e.what());
115 "Failed to get fitness/size/complexity from individual at population index "
116 +
to_string(population_index) +
": unknown error");
119 if (!std::isfinite(fitness_loss) || !std::isfinite(fitness_loss_v)) {
121 "Invalid non-finite fitness values at population index "
130 scores(index) = fitness_loss;
131 scores_v(index) = fitness_loss_v;
132 sizes(index) = individual_size;
133 complexities(index) = individual_complexity;
140 scores.conservativeResize(index);
141 scores_v.conservativeResize(index);
142 sizes.conservativeResize(index);
143 complexities.conservativeResize(index);
147 float best_score = index > 0 ? (scores*error_weight).maxCoeff()*error_weight : 0.0f;
148 float best_score_v = this->
best_ind.fitness.get_loss_v();
150 if (!std::isfinite(best_score_v)) {
151 HANDLE_ERROR_THROW(
"Invalid non-finite validation loss in best_ind while calculating stats");
154 float med_score = index > 0 ?
median(scores) : 0.0f;
155 float med_score_v = index > 0 ?
median(scores_v) : 0.0f;
156 unsigned med_size = index > 0 ?
median(sizes) : 0;
157 unsigned med_complexity = index > 0 ?
median(complexities) : 0;
158 unsigned max_size = index > 0 ? sizes.maxCoeff() : 0;
159 unsigned max_complexity = index > 0 ? complexities.maxCoeff() : 0;
163 timer.Elapsed().count(),
435 if (
params.load_population !=
"") {
438 else if (this->
pop.individuals.size() == 0)
460 if (!
params.logfile.empty()) {
461 log.open(
params.logfile, std::ofstream::app);
462 if (!log.is_open()) {
473 threads = std::thread::hardware_concurrency();
474 else if (
params.n_jobs == 0)
475 threads =
params.num_islands;
479 tf::Executor executor(threads);
481 assert( (executor.num_workers() > 0) &&
"Invalid number of workers");
483 tf::Taskflow taskflow;
486 unsigned generation = 0;
487 unsigned stall_count = 0;
491 bool condition = ( (generation ==
params.max_gens)
492 || (
params.max_stall != 0 && stall_count >
params.max_stall)
501 vector<vector<size_t>> island_parents;
503 island_parents.clear();
504 island_parents.resize(
pop.num_islands);
506 for (
int i=0; i<
params.num_islands; i++){
507 size_t idx_start = std::floor(i*
params.pop_size/
params.num_islands);
508 size_t idx_end = std::floor((i+1)*
params.pop_size/
params.num_islands);
510 auto delta = idx_end - idx_start;
512 island_parents.at(i).clear();
513 island_parents.at(i).resize(
delta);
517 auto [
init, cond, body, back, done] = taskflow.emplace(
518 [&](tf::Subflow& subflow) {
519 auto fit_init_pop = subflow.for_each_index(0, this->
params.num_islands, 1, [&](
int island) {
523 evaluator.update_fitness(this->pop, island, data, params, true, true);
525 auto find_init_best = subflow.emplace([&]() {
533 fit_init_pop.precede(find_init_best);
538 [&](tf::Subflow& subflow) {
539 auto prepare_gen = subflow.emplace([&]() {
540 params.set_current_gen(generation);
542 }).name(
"prepare generation");
544 auto run_generation = subflow.for_each_index(0, this->
params.num_islands, 1, [&](
int island) {
546 evaluator.update_fitness(this->pop, island, data, params, false, false);
551 evaluator.update_fitness(this->pop, island, batch, params, false, false);
553 vector<size_t> parents = selector.select(this->pop, island, params);
554 for (int i=0; i< parents.size(); i++){
555 island_parents.at(island).at(i) = parents.at(i);
558 this->pop.add_offspring_indexes(island);
560 }).name(
"runs one generation at each island in parallel");
562 auto update_pop = subflow.emplace([&]() {
565 for (
int island = 0; island < this->
params.num_islands; ++island) {
576 (generation>=
params.max_gens/2) || (stall_count ==
params.max_stall) || (generation==
params.max_gens-1)
590 this->
pop.update({survivor_indices});
592 }).name(
"update, migrate and disentangle indexes between islands");
594 auto finish_gen = subflow.emplace([&]() {
596 for (
int island = 0; island < this->
params.num_islands; ++island) {
606 fraction =
params.max_time == -1 ? ((generation+1)*1.0)/
params.max_gens :
615 else if(
params.verbosity == 1)
618 if (!
params.logfile.empty() && log.is_open())
621 if (generation == 0 || updated_best )
628 }).name(
"update best, update ss, log, archive, stall");
631 prepare_gen.precede(run_generation);
632 run_generation.precede(update_pop);
633 update_pop.precede(finish_gen);
638 [&](tf::Subflow& subflow) {
640 for (
int island = 0; island < this->params.num_islands; ++island) {
641 evaluator.update_fitness(this->pop, island, data, params,
true,
true);
644 archive.update(pop, params);
647 if (params.save_population !=
"")
648 this->pop.save(params.save_population);
653 if (!params.logfile.empty() && params.inexact_simplification) {
654 std::ofstream log_simplification;
655 log_simplification.open(params.logfile+
"_simplification_table", std::ofstream::app);
656 variator.log_simplification_table(log_simplification);
658 log_simplification.close();
666 this->ss = variator.search_space;
667 this->params = variator.parameters;
673 cond.name(
"termination");
674 body.name(
"main loop");
677 taskflow.name(
"island_gp");
680 cond.precede(body, done);
684 executor.run(taskflow);
685 executor.wait_for_all();