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