416 if (
params.load_population !=
"") {
417 cout <<
"Loading population from file " <<
params.load_population << std::endl;
422 else if (this->
pop.individuals.size() > 0) {
438 for (
auto& individual : this->
pop.individuals) {
439 if (individual !=
nullptr) {
440 individual->set_is_fitted(
false);
451 if (!
params.logfile.empty())
452 log.open(
params.logfile, std::ofstream::app);
460 threads = std::thread::hardware_concurrency();
461 else if (
params.n_jobs == 0)
462 threads =
params.num_islands;
466 tf::Executor executor(threads);
468 assert( (executor.num_workers() > 0) &&
"Invalid number of workers");
470 tf::Taskflow taskflow;
473 unsigned generation = 0;
474 unsigned stall_count = 0;
478 return ( (generation ==
params.max_gens)
479 || (
params.max_stall != 0 && stall_count >
params.max_stall)
486 vector<vector<size_t>> island_parents;
488 island_parents.clear();
489 island_parents.resize(
pop.num_islands);
491 for (
int i=0; i<
params.num_islands; i++){
492 size_t idx_start = std::floor(i*
params.pop_size/
params.num_islands);
493 size_t idx_end = std::floor((i+1)*
params.pop_size/
params.num_islands);
495 auto delta = idx_end - idx_start;
497 island_parents.at(i).clear();
498 island_parents.at(i).resize(
delta);
502 auto [
init, cond, body, back, done] = taskflow.emplace(
503 [&](tf::Subflow& subflow) {
504 auto fit_init_pop = subflow.for_each_index(0, this->
params.num_islands, 1, [&](
int island) {
508 evaluator.update_fitness(this->pop, island, data, params, true, true);
511 auto find_init_best = subflow.emplace([&]() {
520 fit_init_pop.precede(find_init_best);
525 [&](tf::Subflow& subflow) {
526 auto prepare_gen = subflow.emplace([&]() {
527 params.set_current_gen(generation);
529 }).name(
"prepare generation");
531 auto run_generation = subflow.for_each_index(0, this->
params.num_islands, 1, [&](
int island) {
534 evaluator.update_fitness(this->pop, island, data, params, false, false);
539 evaluator.update_fitness(this->pop, island, batch, params, false, false);
541 vector<size_t> parents = selector.select(this->pop, island, params);
543 for (int i=0; i< parents.size(); i++){
544 island_parents.at(island).at(i) = parents.at(i);
547 this->pop.add_offspring_indexes(island);
549 }).name(
"runs one generation at each island in parallel");
551 auto update_pop = subflow.emplace([&]() {
554 for (
int island = 0; island < this->
params.num_islands; ++island) {
580 this->
pop.update({survivor_indices});
585 }).name(
"update, migrate and disentangle indexes between islands");
587 auto finish_gen = subflow.emplace([&]() {
593 for (
int island = 0; island < this->
params.num_islands; ++island) {
599 fraction =
params.max_time == -1 ? ((generation+1)*1.0)/
params.max_gens :
610 else if(
params.verbosity == 1)
613 if (!
params.logfile.empty())
616 if (generation == 0 || updated_best )
623 }).name(
"update best, update ss, log, archive, stall");
626 prepare_gen.precede(run_generation);
627 run_generation.precede(update_pop);
628 update_pop.precede(finish_gen);
633 [&](tf::Subflow& subflow) {
635 for (
int island = 0; island < this->params.num_islands; ++island) {
636 evaluator.update_fitness(this->pop, island, data, params,
true,
false);
641 if (!params.use_arch)
643 std::cout <<
"saving final population as archive..." << std::endl;
646 archive.update(pop, params);
649 if (params.save_population !=
"")
650 this->pop.save(params.save_population);
659 this->ss = variator.search_space;
660 this->params = variator.parameters;
666 cond.name(
"termination");
667 body.name(
"main loop");
670 taskflow.name(
"island_gp");
673 cond.precede(body, done);
677 executor.run(taskflow);
678 executor.wait_for_all();