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; } }
/** * Run the co-evolution algorithm * * @param[in,out] pop input/output pagmo::population to be evolved. */ void cstrs_co_evolution::evolve(population &pop) const { // Let's store some useful variables. const problem::base &prob = pop.problem(); const population::size_type pop_size = pop.size(); const problem::base::size_type prob_dimension = prob.get_dimension(); // get the constraints dimension problem::base::c_size_type prob_c_dimension = prob.get_c_dimension(); //We perform some checks to determine wether the problem/population are suitable for co-evolution if(prob_c_dimension < 1) { pagmo_throw(value_error,"The problem is not constrained and co-evolution is not suitable to solve it"); } if(prob.get_f_dimension() != 1) { pagmo_throw(value_error,"The problem is multiobjective and co-evolution is not suitable to solve it"); } // Get out if there is nothing to do. if(pop_size == 0) { return; } //get the dimension of the chromosome of P2 unsigned int pop_2_dim = 0; switch(m_method) { case algorithm::cstrs_co_evolution::SIMPLE: { pop_2_dim = 2; break; } case algorithm::cstrs_co_evolution::SPLIT_NEQ_EQ: { pop_2_dim = 4; break; } case algorithm::cstrs_co_evolution::SPLIT_CONSTRAINTS: pop_2_dim = 2*prob.get_c_dimension(); break; default: pagmo_throw(value_error,"The constraints co-evolutionary method is not valid."); break; } // split the population into two populations // the population P1 associated to the modified problem with penalized fitness // and population P2 encoding the penalty weights // Populations size population::size_type pop_1_size = pop_size; population::size_type pop_2_size = m_pop_penalties_size; //Creates problem associated to P2 problem::cstrs_co_evolution_penalty prob_2(prob,pop_2_dim,pop_2_size); prob_2.set_bounds(m_pen_lower_bound,m_pen_upper_bound); //random initialization of the P2 chromosome (needed for the fist generation) std::vector<decision_vector> pop_2_x(pop_2_size); std::vector<fitness_vector> pop_2_f(pop_2_size); for(population::size_type j=0; j<pop_2_size; j++) { pop_2_x[j] = decision_vector(pop_2_dim,0.); // choose random coefficients between lower bound and upper bound for(population::size_type i=0; i<pop_2_dim;i++) { pop_2_x[j][i] = boost::uniform_real<double>(m_pen_lower_bound,m_pen_upper_bound)(m_drng); } } //vector of the population P1. Initialized with clones of the original population std::vector<population> pop_1_vector; for(population::size_type i=0; i<pop_2_size; i++){ pop_1_vector.push_back(population(pop)); } // Main Co-Evolution loop for(int k=0; k<m_gen; k++) { // for each individuals of pop 2, evolve the current population, // and store the position of the feasible idx for(population::size_type j=0; j<pop_2_size; j++) { problem::cstrs_co_evolution prob_1(prob, pop_1_vector.at(j), m_method); // modify the problem by setting decision vector encoding penalty // coefficients w1 and w2 in prob 1 prob_1.set_penalty_coeff(pop_2_x.at(j)); // creating the POPULATION 1 instance based on the // updated prob 1 // prob_1 is a BASE_META???? THE CLONE OF prob_1 IN POP_1 IS AT THE LEVEL OF // THE BASE CLASS AND NOT AT THE LEVEL OF THE BASE_META, NO?!? population pop_1(prob_1,0); // initialize P1 chromosomes. The fitnesses related to problem 1 are computed for(population::size_type i=0; i<pop_1_size; i++) { pop_1.push_back(pop_1_vector.at(j).get_individual(i).cur_x); } // evolve the P1 instance m_original_algo->evolve(pop_1); //updating the original problem population (computation of fitness and constraints) pop_1_vector.at(j).clear(); for(population::size_type i=0; i<pop_1_size; i++){ pop_1_vector.at(j).push_back(pop_1.get_individual(i).cur_x); } // set up penalization variables needs for the population 2 // the constraints has not been evaluated yet. prob_2.update_penalty_coeff(j,pop_2_x.at(j),pop_1_vector.at(j)); } // creating the POPULATION 2 instance based on the // updated prob 2 population pop_2(prob_2,0); // compute the fitness values of the second population for(population::size_type i=0; i<pop_2_size; i++) { pop_2.push_back(pop_2_x[i]); } m_original_algo_penalties->evolve(pop_2); // store the new chromosomes for(population::size_type i=0; i<pop_2_size; i++) { pop_2_x[i] = pop_2.get_individual(i).cur_x; pop_2_f[i] = pop_2.get_individual(i).cur_f; } // Check the exit conditions (every 40 generations, just as DE) if(k % 40 == 0) { // finds the best population population::size_type best_idx = 0; for(population::size_type j=1; j<pop_2_size; j++) { if(pop_2_f[j][0] < pop_2_f[best_idx][0]) { best_idx = j; } } const population ¤t_population = pop_1_vector.at(best_idx); decision_vector tmp(prob_dimension); double dx = 0; for(decision_vector::size_type i=0; i<prob_dimension; i++) { tmp[i] = current_population.get_individual(current_population.get_worst_idx()).best_x[i] - current_population.get_individual(current_population.get_best_idx()).best_x[i]; dx += std::fabs(tmp[i]); } if(dx < m_xtol ) { if (m_screen_output) { std::cout << "Exit condition -- xtol < " << m_xtol << std::endl; } break; } double mah = std::fabs(current_population.get_individual(current_population.get_worst_idx()).best_f[0] - current_population.get_individual(current_population.get_best_idx()).best_f[0]); if(mah < m_ftol) { if(m_screen_output) { std::cout << "Exit condition -- ftol < " << m_ftol << std::endl; } break; } // outputs current values if(m_screen_output) { std::cout << "Generation " << k << " ***" << std::endl; std::cout << " Best global fitness: " << current_population.champion().f << std::endl; std::cout << " xtol: " << dx << ", ftol: " << mah << std::endl; std::cout << " xtol: " << dx << ", ftol: " << mah << std::endl; } } } // find the best fitness population in the final pop population::size_type best_idx = 0; for(population::size_type j=1; j<pop_2_size; j++) { if(pop_2_f[j][0] < pop_2_f[best_idx][0]) { best_idx = j; } } // store the final population in the main population // can't avoid to recompute the vectors here, otherwise we // clone the problem stored in the population with the // pop = operator! pop.clear(); for(population::size_type i=0; i<pop_1_size; i++) { pop.push_back(pop_1_vector.at(best_idx).get_individual(i).cur_x); } }
/** * Run the CORE algorithm * * @param[in,out] pop input/output pagmo::population to be evolved. */ void cstrs_core::evolve(population &pop) const { // store useful variables const problem::base &prob = pop.problem(); const population::size_type pop_size = pop.size(); const problem::base::size_type prob_dimension = prob.get_dimension(); // get the constraints dimension problem::base::c_size_type prob_c_dimension = prob.get_c_dimension(); //We perform some checks to determine wether the problem/population are suitable for CORE if(prob_c_dimension < 1) { pagmo_throw(value_error,"The problem is not constrained and CORE is not suitable to solve it"); } if(prob.get_f_dimension() != 1) { pagmo_throw(value_error,"The problem is multiobjective and CORE is not suitable to solve it"); } // Get out if there is nothing to do. if(pop_size == 0) { return; } // generates the unconstrained problem problem::con2uncon prob_unconstrained(prob); // associates the population to this problem population pop_uncon(prob_unconstrained); // fill this unconstrained population pop_uncon.clear(); for(population::size_type i=0; i<pop_size; i++) { pop_uncon.push_back(pop.get_individual(i).cur_x); } // vector containing the infeasibles positions std::vector<population::size_type> pop_infeasibles; // Main CORE loop for(int k=0; k<m_gen; k++) { if(k%m_repair_frequency == 0) { pop_infeasibles.clear(); // get the infeasible individuals for(population::size_type i=0; i<pop_size; i++) { if(!prob.feasibility_c(pop.get_individual(i).cur_c)) { pop_infeasibles.push_back(i); } } // random shuffle of infeasibles? population::size_type number_of_repair = (population::size_type)(m_repair_ratio * pop_infeasibles.size()); // repair the infeasible individuals for(population::size_type i=0; i<number_of_repair; i++) { const population::size_type ¤t_individual_idx = pop_infeasibles.at(i); pop.repair(current_individual_idx, m_repair_algo); } // the population is repaired, it can be now used in the new unconstrained population // only the repaired individuals are put back in the population for(population::size_type i=0; i<number_of_repair; i++) { population::size_type current_individual_idx = pop_infeasibles.at(i); pop_uncon.set_x(current_individual_idx, pop.get_individual(current_individual_idx).cur_x); } } m_original_algo->evolve(pop_uncon); // push back the population in the main problem pop.clear(); for(population::size_type i=0; i<pop_size; i++) { pop.push_back(pop_uncon.get_individual(i).cur_x); } // Check the exit conditions (every 40 generations, just as DE) if(k % 40 == 0) { decision_vector tmp(prob_dimension); double dx = 0; for(decision_vector::size_type i=0; i<prob_dimension; i++) { tmp[i] = pop.get_individual(pop.get_worst_idx()).best_x[i] - pop.get_individual(pop.get_best_idx()).best_x[i]; dx += std::fabs(tmp[i]); } if(dx < m_xtol ) { if (m_screen_output) { std::cout << "Exit condition -- xtol < " << m_xtol << std::endl; } break; } double mah = std::fabs(pop.get_individual(pop.get_worst_idx()).best_f[0] - pop.get_individual(pop.get_best_idx()).best_f[0]); if(mah < m_ftol) { if(m_screen_output) { std::cout << "Exit condition -- ftol < " << m_ftol << std::endl; } break; } // outputs current values if(m_screen_output) { std::cout << "Generation " << k << " ***" << std::endl; std::cout << " Best global fitness: " << pop.champion().f << std::endl; std::cout << " xtol: " << dx << ", ftol: " << mah << std::endl; std::cout << " xtol: " << dx << ", ftol: " << mah << std::endl; } } } }