void report(population& p) { switch(cfg.report_every) { case config::report::none: break; case config::report::avg: { float avg = 0.0; for(auto i = p.begin(); i != p.end(); ++i) avg += i->eval; avg /= static_cast<float>(p.size()); std::cout << iter << ' ' << avg << '\n'; } break; case config::report::best: std::cout << iter << ' ' << p[0].eval << '\n'; break; } if(cfg.report_var) { std::cout << iter << ' ' << statistics::variance(p) << '\n'; } }
void increase_tree_depth(generation_table& gtable, population& pop, int& from_depth, combo::arity_t& needed_arg_count, int fill_from_arg, const reduct::rule& reduction_rule) { for (population::iterator it = pop.begin(); it != pop.end(); ++it) { int number_of_combinations = 1; bool can_have_leaves = false; std::vector<generation_table::iterator> assignment; std::vector<combo::combo_tree::leaf_iterator> leaves; for (combo::combo_tree::leaf_iterator lit = it->begin_leaf(); lit != it->end_leaf(); ++lit) { if (combo::is_argument(*lit)) if (combo::get_argument(*lit).abs_idx() <= needed_arg_count) continue; for (std::vector<generation_node>::iterator it2 = gtable.begin(); it2 != gtable.end(); it2++) if (combo::equal_type_tree(it2->node, combo::infer_vertex_type(*it, lit))) { if (it2->glist.size() != 0) can_have_leaves = true; assignment.push_back(it2); number_of_combinations *= it2->glist.size(); break; } } if (!can_have_leaves) number_of_combinations = 0; for (int i = 0; i < number_of_combinations; i++) { combo::combo_tree temp_tree(*it); int ongoing_count = 1; leaves.clear(); for (combo::combo_tree::leaf_iterator lit = temp_tree.begin_leaf(); lit != temp_tree.end_leaf(); ++lit) leaves.push_back(lit); std::vector<generation_table::iterator>::iterator it2 = assignment.begin(); for (std::vector<combo::combo_tree::leaf_iterator>::iterator lit = leaves.begin(); lit != leaves.end(); ++lit) { if (combo::is_argument(**lit)) if (combo::get_argument(**lit).abs_idx() <= needed_arg_count) continue; if ((*it2)->glist.size() != 0) { node_list::iterator it3 = (*it2)->glist.begin(); for (int n = 0; n < (int)(i/(number_of_combinations/(ongoing_count * (*it2)->glist.size())) % (*it2)->glist.size()); n++) it3++; temp_tree.replace(*lit, *it3); ongoing_count *= (*it2)->glist.size(); } it2++; } bool erased = true; for (combo::combo_tree::leaf_iterator lit = temp_tree.begin_leaf(); lit != temp_tree.end_leaf(); ++lit) { if (combo::get_arity(*lit) != 0 && !combo::is_argument(*lit)) { erased = false; break; } } if (combo::does_contain_all_arg_up_to(temp_tree, needed_arg_count)) { erased = false; } if (!erased) { //Uses less memory but is very slow /*fill_leaves_single(temp_tree, fill_from_arg); reduced_insertion(new_pop, temp_tree, reduction_rule);*/ pop.push_front(temp_tree); } } } }
void report_end(population& p) { if(cfg.report_every == config::report::none) { if(cfg.report_population) { if(cfg.debug) { std::cout << "Reporting population\n"; std::cout << "Evaluation = [ permutation ]\n"; } std::sort(p.begin(), p.end(), eval_cmp()); for(auto i = p.begin(); i != p.end(); ++i) std::cout << i->eval << " = " << i->perm << std::endl; } if(cfg.report_best) { if(cfg.debug) { std::cout << "Reporting best speciman\n"; std::cout << "Evaluation = [ permutation ]\n"; } std::cout << best_specimen.eval << " = " << best_specimen.perm << std::endl; } if(cfg.optimum > -1) { if(cfg.debug) { std::cout << "Reporting number of iterations needed to compute best specimen with given optimum value or --max-iter if optimum is not reached\n"; } std::cout << iter << "\n"; } if(cfg.compare_operators) { std::cout << "ox = " << ox_count << "\n"; std::cout << "cx = " << cx_count << "\n"; std::cout << "pmx = " << pmx_count << "\n"; std::cout << "crossovers = " << x_count << "\n"; } } }
void adapt_population(population& p) { float F_min = min_element(p.begin(),p.end(),eval_comp)->eval; for(unsigned int i=0; i<p.size(); i++) { float sum = 0.0; for(unsigned int j=0; j<p.size(); j++) sum += p[j].eval - F_min; p[i].adapt = (p[i].eval - F_min)/sum; } }
std::vector<population::individual_type> best_s_policy::select(const population &pop) const { const population::size_type migration_rate = get_n_individuals(pop); // Create a temporary array of individuals. std::vector<population::individual_type> result(pop.begin(),pop.end()); // Sort the individuals (best go first). std::sort(result.begin(),result.end(),dom_comp(pop)); // Leave only desired number of elements in the result. result.erase(result.begin() + migration_rate,result.end()); return result; }
void mutation_function(population& p) { for(auto i = p.begin(); i != p.end(); ++i) { float prob = 1 - i->adapt; // probability of mutation float r = uniform_random(); // random float between <0,1) if(r < prob) { mutation::random_transposition(i->perm); i->eval = evaluation(i->perm); // after mutation is done we have to evaluate this specimen again } } }
void fill_leaves(population& pop, int& from_arg) { for (population::iterator it = pop.begin(); it != pop.end(); ++it) { int local_from_arg = from_arg; for (combo::combo_tree::leaf_iterator lit = it->begin_leaf(); lit != it->end_leaf(); ++lit) { if (!combo::is_argument(*lit)) { combo::arity_t number_of_leaves = combo::get_arity(*lit); if (number_of_leaves < 0) number_of_leaves = -1 * number_of_leaves + 1; for (combo::arity_t count = 0; count < number_of_leaves; count++) { (*it).append_child(lit, combo::argument(++local_from_arg)); } } } } }
void replacement(population& p) { std::sort(p.begin(), p.end(), eval_cmp()); p.resize(population_size); if( p[0].eval < best_specimen.eval ) { best_specimen = p[0]; deviate_count = 0; } else { deviate_count++; } }
// perform (\lambda+\mu) -> (\lambda) selection void dgea_alg::select(population& pop, population& child_pop) { int pop_size=pop.size(); int num_dims=m_ppara->get_dim(); int i; population pop_merged(pop_size); vector<vector<double> > prev_x(pop_size); for ( i=0;i<pop_size;i++ ) { prev_x[i].resize(num_dims); pop_merged[i]=pop[i]; // record previous x prev_x[i]=pop[i].x; }// for every individual // push child population at the tail of merged population copy( child_pop.begin(),child_pop.end(),back_inserter(pop_merged) ); nth_element(pop_merged.begin(), pop_merged.begin()+pop_size, pop_merged.end()); //// heap sorting //make_heap(pop_merged.begin(),pop_merged.end()); //for ( i=0;i<pop_size;i++ ) //{ // // record delta x for stat purpose // pop_heap(pop_merged.begin(),pop_merged.end()); // pop_merged.pop_back(); // const individual& new_ind=pop_merged.front(); // pop[i]=new_ind; // m_alg_stat.delta_x[i]=pop[i].x-prev_x[i];// pop_merged:{parents,offsprings} //} for ( i=0;i<pop_size;i++ ) { pop[i]=pop_merged[i]; // record delta x m_alg_stat.delta_x[i] = (pop[i].x-prev_x[i]); }// for every individual }// end function select
void enumerate_program_trees(generation_table& gtable, int depth, combo::type_tree& ttree, population& pop, const reduct::rule& reduction_rule) { pop.clear(); // For each generation node with the right return-type, add it to the pop for (std::vector<generation_node>::iterator it = gtable.begin(); it != gtable.end(); ++it) { if (combo::equal_type_tree(it->node, combo::get_signature_output(ttree))) { for (node_list::iterator it2 = it->glist.begin(); it2 != it->glist.end(); it2++) pop.push_back(combo::combo_tree(*it2)); break; } } // add the right number of arguments int from_arg = combo::get_signature_inputs(ttree).size(); combo::arity_t needed_arg_count = combo::type_tree_arity(ttree); std::cout << ttree << " " << needed_arg_count << std::endl; for (int i = 1; i < depth; i++) { fill_leaves(pop, from_arg); reduce(pop, reduction_rule); increase_tree_depth(gtable, pop, i, needed_arg_count, from_arg, reduction_rule); } for (population::iterator it = pop.begin(); it != pop.end();) { bool erased = false; for (combo::combo_tree::leaf_iterator lit = it->begin_leaf(); lit != it->end_leaf(); ++lit) { if (get_arity(*lit) != 0 && !combo::is_argument(*lit)) { erased = true; break; } } if (!combo::does_contain_all_arg_up_to(*it, needed_arg_count)) { erased = true; } if (erased) it = pop.erase(it); else ++it; } }
void crossover_function(population& p) { population new_population; std::vector<int> cross_set; std::vector<int>::iterator it; float rd; // choose which specimen will crossover for(int i=0; i<population_size; i++) { rd = (randid()*1.0f) / (RAND_MAX*1.0f*population_size); if(rd > p[i].adapt) cross_set.push_back(i); } // we want even number of parents if(cross_set.size() & 1) cross_set.pop_back(); // more randomness random_shuffle ( cross_set.begin(), cross_set.end(), p_randgenid ); it = cross_set.begin(); // crossover each pair from left to right while( it != cross_set.end()) { std::pair<permutation,permutation> desc; crossover::type ctype; if(cfg.compare_operators) { switch(randid() % xop_count) { case 0: ctype = crossover::type::OX; break; case 1: ctype = crossover::type::CX; break; case 2: default: ctype = crossover::type::PMX; break; } desc = crossover::random_crossover(ctype, p[*it].perm, p[*(it+1)].perm); } else { desc = crossover::random_crossover(cfg.crossover_type, p[*it].perm, p[*(it+1)].perm); } specimen ch1, ch2; ch1.perm = desc.first; ch1.eval = evaluation(ch1.perm); ch1.adapt = 0.0; ch2.perm = desc.second; ch2.eval = evaluation(ch2.perm); ch2.adapt = 0.0; if(cfg.compare_operators && ( ((p[*it].eval + p[*(it+1)].eval) / (ch1.eval + ch2.eval)) >= 1 ) ) { switch(ctype) { case crossover::type::OX: ox_count++; break; case crossover::type::CX: cx_count++; break; case crossover::type::PMX: default: pmx_count++; break; } } it++; it++; x_count++; new_population.push_back(ch1); new_population.push_back(ch2); } p.insert(p.end(), new_population.begin(), new_population.end()); }