332 if (
params.load_population !=
"")
339 if (!
params.logfile.empty())
340 log.open(
params.logfile, std::ofstream::app);
348 threads = std::thread::hardware_concurrency();
349 else if (
params.n_jobs == 0)
350 threads =
params.num_islands;
354 tf::Executor executor(threads);
356 assert( (executor.num_workers() > 0) &&
"Invalid number of workers");
358 tf::Taskflow taskflow;
361 unsigned generation = 0;
362 unsigned stall_count = 0;
368 return ( (generation ==
params.max_gens)
369 && ((
params.max_stall == 0 || stall_count <
params.max_stall)
376 vector<vector<size_t>> island_parents;
377 vector<vector<size_t>> survivors;
378 island_parents.clear();
379 island_parents.resize(
pop.num_islands);
382 survivors.resize(
pop.num_islands);
384 for (
int i=0; i<
params.num_islands; i++){
385 size_t idx_start = std::floor(i*
params.pop_size/
params.num_islands);
386 size_t idx_end = std::floor((i+1)*
params.pop_size/
params.num_islands);
388 auto delta = idx_end - idx_start;
390 survivors.at(i).clear();
391 island_parents.at(i).clear();
393 survivors.at(i).resize(
delta);
394 island_parents.at(i).resize(
delta);
398 auto [
init, cond, body, back, done] = taskflow.emplace(
403 [&](tf::Subflow& subflow) {
404 auto prepare_gen = subflow.emplace([&]() {
405 params.set_current_gen(generation);
407 }).name(
"prepare generation");
409 auto run_generation = subflow.for_each_index(0, this->
params.num_islands, 1, [&](
int island) {
410 evaluator.update_fitness(this->pop, island, data, params, true);
415 evaluator.update_fitness(this->pop, island, batch, params, false);
417 vector<size_t> parents = selector.select(this->pop, island, params);
419 for (int i=0; i< parents.size(); i++){
420 island_parents.at(island).at(i) = parents.at(i);
423 this->pop.add_offspring_indexes(island);
424 variator.vary(this->pop, island, island_parents.at(island));
431 vector<size_t> island_survivors =
survivor.survive(this->pop, island,
params);
433 for (
int i=0; i< island_survivors.size(); i++){
434 survivors.at(island).at(i) = island_survivors.at(i);
436 }).name(
"runs one generation at each island in parallel");
438 auto update_pop = subflow.emplace([&]() {
439 this->
pop.update(survivors);
441 }).name(
"update, migrate and disentangle indexes between islands");
443 auto finish_gen = subflow.emplace([&]() {
454 fraction =
params.max_time == -1 ? ((generation+1)*1.0)/
params.max_gens :
459 else if(
params.verbosity == 1)
462 if (!
params.logfile.empty())
465 if (generation == 0 || updated_best )
472 }).name(
"update best, log, archive, stall");
475 prepare_gen.precede(run_generation);
476 run_generation.precede(update_pop);
477 update_pop.precede(finish_gen);
483 if (params.save_population !=
"")
484 this->pop.save(params.save_population);
486 this->set_is_fitted(
true);
494 if (!params.use_arch)
496 archive.individuals.resize(0);
497 for (
int island =0; island< pop.num_islands; ++island) {
498 vector<size_t> indices = pop.get_island_indexes(island);
500 for (
unsigned i = 0; i<indices.size(); ++i)
502 archive.individuals.push_back( *pop.individuals.at(indices.at(i)) );
511 cond.name(
"termination");
512 body.name(
"main loop");
515 taskflow.name(
"island_gp");
518 cond.precede(body, done);
522 executor.run(taskflow);
523 executor.wait_for_all();