365 if (
params.load_population !=
"") {
368 else if (this->
pop.individuals.size() == 0)
390 if (!
params.logfile.empty())
391 log.open(
params.logfile, std::ofstream::app);
399 threads = std::thread::hardware_concurrency();
400 else if (
params.n_jobs == 0)
401 threads =
params.num_islands;
405 tf::Executor executor(threads);
407 assert( (executor.num_workers() > 0) &&
"Invalid number of workers");
409 tf::Taskflow taskflow;
412 unsigned generation = 0;
413 unsigned stall_count = 0;
417 bool condition = ( (generation ==
params.max_gens)
418 || (
params.max_stall != 0 && stall_count >
params.max_stall)
427 vector<vector<size_t>> island_parents;
429 island_parents.clear();
430 island_parents.resize(
pop.num_islands);
432 for (
int i=0; i<
params.num_islands; i++){
433 size_t idx_start = std::floor(i*
params.pop_size/
params.num_islands);
434 size_t idx_end = std::floor((i+1)*
params.pop_size/
params.num_islands);
436 auto delta = idx_end - idx_start;
438 island_parents.at(i).clear();
439 island_parents.at(i).resize(
delta);
443 auto [
init, cond, body, back, done] = taskflow.emplace(
444 [&](tf::Subflow& subflow) {
445 auto fit_init_pop = subflow.for_each_index(0, this->
params.num_islands, 1, [&](
int island) {
449 evaluator.update_fitness(this->pop, island, data, params, true, true);
451 auto find_init_best = subflow.emplace([&]() {
459 fit_init_pop.precede(find_init_best);
464 [&](tf::Subflow& subflow) {
465 auto prepare_gen = subflow.emplace([&]() {
466 params.set_current_gen(generation);
468 }).name(
"prepare generation");
470 auto run_generation = subflow.for_each_index(0, this->
params.num_islands, 1, [&](
int island) {
472 evaluator.update_fitness(this->pop, island, data, params, false, false);
477 evaluator.update_fitness(this->pop, island, batch, params, false, false);
479 vector<size_t> parents = selector.select(this->pop, island, params);
480 for (int i=0; i< parents.size(); i++){
481 island_parents.at(island).at(i) = parents.at(i);
484 this->pop.add_offspring_indexes(island);
486 }).name(
"runs one generation at each island in parallel");
488 auto update_pop = subflow.emplace([&]() {
491 for (
int island = 0; island < this->
params.num_islands; ++island) {
502 (generation>=
params.max_gens/2) || (stall_count ==
params.max_stall-1)
516 this->
pop.update({survivor_indices});
518 }).name(
"update, migrate and disentangle indexes between islands");
520 auto finish_gen = subflow.emplace([&]() {
522 for (
int island = 0; island < this->
params.num_islands; ++island) {
530 fraction =
params.max_time == -1 ? ((generation+1)*1.0)/
params.max_gens :
539 else if(
params.verbosity == 1)
542 if (!
params.logfile.empty())
545 if (generation == 0 || updated_best )
552 }).name(
"update best, update ss, log, archive, stall");
555 prepare_gen.precede(run_generation);
556 run_generation.precede(update_pop);
557 update_pop.precede(finish_gen);
562 [&](tf::Subflow& subflow) {
564 for (
int island = 0; island < this->params.num_islands; ++island) {
565 evaluator.update_fitness(this->pop, island, data, params,
false,
true);
568 archive.update(pop, params);
571 if (params.save_population !=
"")
572 this->pop.save(params.save_population);
576 if (!params.logfile.empty()) {
577 std::ofstream log_simplification;
578 log_simplification.open(params.logfile+
"simplification_table", std::ofstream::app);
579 variator.log_simplification_table(log_simplification);
581 log_simplification.close();
589 this->ss = variator.search_space;
590 this->params = variator.parameters;
596 cond.name(
"termination");
597 body.name(
"main loop");
600 taskflow.name(
"island_gp");
603 cond.precede(body, done);
607 executor.run(taskflow);
608 executor.wait_for_all();