25 #include <boost/random/uniform_int.hpp>
26 #include <boost/random/uniform_real.hpp>
27 #include <boost/random/variate_generator.hpp>
28 #include <boost/random/normal_distribution.hpp>
29 #include <boost/math/special_functions/round.hpp>
34 #include "../exceptions.h"
35 #include "../population.h"
39 #include "../problem/base_stochastic.h"
41 namespace pagmo {
namespace algorithm {
60 :
base(),m_gen(gen),m_cr(cr),m_m(m),m_elitism(elitism),m_mut(mut),m_sel(sel),m_cro(cro)
63 pagmo_throw(value_error,
"number of generations must be nonnegative");
65 if (cr > 1 || cr < 0) {
66 pagmo_throw(value_error,
"crossover probability must be in the [0,1] range");
69 pagmo_throw(value_error,
"mutation probability must be in the [0,1] range");
72 pagmo_throw(value_error,
"elitisim must be greater or equal than zero");
76 m_max_encoding_integer = int(std::pow(2., m_bit_encoding));
101 if ( prob_c_dimension != 0 ) {
102 pagmo_throw(value_error,
"The problem is not box constrained and sga_gray is not suitable to solve it");
105 if ( prob_f_dimension != 1 ) {
106 pagmo_throw(value_error,
"The problem is not single objective and sga_gray is not suitable to solve it");
110 pagmo_throw(value_error,
"for sga_gray at least 5 individuals in the population are needed");
114 pagmo_throw(value_error,
"This version of SGA gray is not compatble with discrete problems.");
123 std::vector<decision_vector > X(NP,dummy), Xnew(NP,dummy);
125 std::vector< std::vector<int> > chrom_vect(NP);
127 std::vector<fitness_vector > fit(NP);
141 double bestidx = pop.get_best_idx();
146 for(
int j=0; j<m_gen; j++) {
148 selection = this->selection(fit,prob);
152 chrom_vect[i] = this->encode(X.at(selection.at(i)), lb, ub);
156 this->mutate(chrom_vect);
160 Xnew[i] = this->decode(chrom_vect.at(i), lb, ub);
171 prob.
objfun(bestfit,bestX);
175 prob.
objfun(fit[i],Xnew[i]);
180 pop.push_back(Xnew[i]);
188 catch (
const std::bad_cast& e)
192 prob.
objfun(fit[i],Xnew[i]);
194 std::transform(dummy.begin(), dummy.end(), pop.
get_individual(i).
cur_x.begin(), dummy.begin(),std::minus<double>());
196 pop.set_x(i,Xnew[i]);
206 if ((m_elitism != 0) && (j % m_elitism == 0) ) {
212 fit[worst] = bestfit;
214 std::transform(dummy.begin(), dummy.end(), pop.
get_individual(worst).
cur_x.begin(), dummy.begin(),std::minus<double>());
216 pop.set_x(worst,Xnew[worst]);
217 pop.set_v(worst,dummy);
226 return "A Simple Genetic Algorithm with Gray encoding";
235 std::ostringstream s;
236 s <<
"gen:" << m_gen <<
' ';
237 s <<
"CR:" << m_cr <<
' ';
238 s <<
"M:" << m_m <<
' ';
239 s <<
"elitism:" << m_elitism <<
' ';
242 case mutation::UNIFORM: {
249 case selection::BEST20: {
253 case selection::ROULETTE: {
260 case crossover::SINGLE_POINT: {
261 s <<
"SINGLE_POINT ";
281 std::vector<int> selection(NP);
284 case selection::BEST20: {
289 std::vector<int> fitnessID(NP);
301 tempID = fitnessID[i];
302 fitnessID[i] = fitnessID[j];
303 fitnessID[j] = tempID;
311 selection[i] = fitnessID[i % best20];
315 case selection::ROULETTE: {
316 std::vector<double> selectionfitness(NP), cumsum(NP), cumsumTemp(NP);
327 selectionfitness[i] = fabs(worstfit[0] - pop_f[i][0]);
331 cumsumTemp[0] = selectionfitness[0];
333 cumsumTemp[i] = cumsumTemp[i - 1] + selectionfitness[i];
336 cumsum[i] = cumsumTemp[i]/cumsumTemp[NP-1];
344 if (cumsum[j] > r2) {
362 void sga_gray::crossover(std::vector< std::vector<int> > &pop_x)
const
367 fitness_vector::size_type D = pop_x.at(0).size();
369 std::vector<population::size_type> mating_pool(0);
373 mating_pool.push_back(i);
378 if (mating_pool_size % 2 != 0) {
382 mating_pool.push_back(boost::uniform_int<int>(0,mating_pool_size - 1)(
m_urng));
384 mating_pool.erase(mating_pool.begin()+boost::uniform_int<int>(0,mating_pool_size - 1)(
m_urng));
388 mating_pool_size = mating_pool.size();
390 if(mating_pool_size == 0) {
396 case crossover::SINGLE_POINT:
401 std::vector<int> &member1 = pop_x[mating_pool[i*2]];
402 std::vector<int> &member2 = pop_x[mating_pool[i*2 + 1]];
405 int position = boost::uniform_int<int>(1, D-1)(
m_urng);
407 std::swap_ranges(member1.begin(), member1.begin()+position, member2.begin());
420 void sga_gray::mutate(std::vector< std::vector<int> > &pop_x)
const
426 case mutation::UNIFORM: {
430 pop_x[i][j] = pop_x[i][j] == 0 ? 1:0;
447 std::vector<int> sga_gray::double_to_binary(
const double &number,
const double &lb,
const double &ub)
const
450 std::vector<int> binary(m_bit_encoding, 0);
454 int temp_number = (number - lb) * (m_max_encoding_integer - 1) / (ub - lb) ;
458 while (temp_number!=0)
460 if( (temp_number % 2) == 0 ) {
461 binary[position] = 0;
463 binary[position] = 1;
465 temp_number = (int)std::floor(temp_number/2);
469 std::reverse(binary.begin(),binary.end());
481 double sga_gray::binary_to_double(
const std::vector<int> &binary,
const double &lb,
const double &ub)
const
485 for(
int i=0; i<m_bit_encoding; i++) {
486 temp_number += binary.at(m_bit_encoding - 1 - i) * std::pow(2.,i);
491 return temp_number * (ub - lb) / (m_max_encoding_integer - 1) + lb;
499 std::vector<int> sga_gray::gray_to_binary(
const std::vector<int> &gray)
const
502 int length = gray.size();
504 std::vector<int> binary = gray;
507 for(
int i=1; i<length; i++) {
508 binary[i] = (binary[i-1]+gray[i]) % 2;
519 std::vector<int> sga_gray::binary_to_gray(
const std::vector<int> &binary)
const
521 int length = binary.size();
522 std::vector<int> gray = binary;
526 for(
int i = 1; i < length; i++) {
527 gray[i] = binary[i]^binary[i-1];
542 std::vector<int> encoded_x(x.size() * m_bit_encoding, 0);
544 for(decision_vector::size_type i=0; i<x.size(); i++) {
545 std::vector<int> encoded_gene = binary_to_gray(double_to_binary(x.at(i),lb.at(i),ub.at(i)));
547 for(
int j=0; j<m_bit_encoding; j++) {
548 encoded_x[i*m_bit_encoding + j] = encoded_gene.at(j);
566 for(decision_vector::size_type i=0; i<decoded_x.size(); i++) {
568 std::vector<int> encoded_gene(m_bit_encoding);
570 for(
int j=0; j<m_bit_encoding; j++) {
571 encoded_gene[j] = chrom.at(i*m_bit_encoding + j);
574 decoded_x[i] = binary_to_double(gray_to_binary(encoded_gene),lb.at(i),ub.at(i));
boost::shared_ptr< base > base_ptr
Alias for shared pointer to base algorithm.
std::vector< double > decision_vector
Decision vector type.
fitness_vector cur_f
Current fitness vector.
type
Mutation type, uniform.
const individual_type & get_individual(const size_type &) const
Get constant reference to individual at position n.
void evolve(population &) const
Evolve implementation.
size_type get_dimension() const
Return global dimension.
bool compare_fitness(const fitness_vector &, const fitness_vector &) const
Compare fitness vectors.
base_ptr clone() const
Clone method.
fitness_vector objfun(const decision_vector &) const
Return fitness of pagmo::decision_vector.
size_type get_i_dimension() const
Return integer dimension.
sga_gray(int gen=1, const double &cr=.95, const double &m=.02, int elitism=1, mutation::type mut=mutation::UNIFORM, selection::type sel=selection::ROULETTE, crossover::type cro=crossover::SINGLE_POINT)
Constructor.
type
Selection type, best 20% or roulette.
std::vector< double > fitness_vector
Fitness vector type.
c_size_type get_c_dimension() const
Return global constraints dimension.
std::string human_readable_extra() const
Extra human readable algorithm info.
const decision_vector & get_ub() const
Upper bounds getter.
Base Stochastic Optimization Problem.
The Simple Genetic Algorithm with gray encoding (sga_gray)
type
Crossover type, single point.
container_type::size_type size_type
Population size type.
decision_vector cur_x
Current decision vector.
rng_uint32 m_urng
Random number generator for unsigned integer values.
f_size_type get_f_dimension() const
Return fitness dimension.
const decision_vector & get_lb() const
Lower bounds getter.
rng_double m_drng
Random number generator for double-precision floating point values.
decision_vector::size_type size_type
Problem's size type: the same as pagmo::decision_vector's size type.
std::string get_name() const
Algorithm name.