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,width),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 than zero");
74 if (width <0 || width >1) {
75 pagmo_throw(value_error,
"mutation width must be in the [0,1] range");
105 if ( prob_c_dimension != 0 ) {
106 pagmo_throw(value_error,
"The problem is not box constrained and SGA is not suitable to solve it");
109 if ( prob_f_dimension != 1 ) {
110 pagmo_throw(value_error,
"The problem is not single objective and SGA is not suitable to solve it");
114 pagmo_throw(value_error,
"for SGA at least 5 individuals in the population are needed");
123 std::vector<decision_vector > X(NP,dummy), Xnew(NP,dummy);
125 std::vector<fitness_vector > fit(NP);
130 std::vector<double> selectionfitness(NP), cumsum(NP), cumsumTemp(NP);
134 std::vector<int> fitnessID(NP);
143 double bestidx = pop.get_best_idx();
149 for (
int j = 0; j<m_gen; j++) {
152 case selection::BEST20: {
161 tempID = fitnessID[i];
162 fitnessID[i] = fitnessID[j];
163 fitnessID[j] = tempID;
169 selection[i] = fitnessID[i % best20];
174 case selection::ROULETTE: {
182 selectionfitness[i] = fabs(worstfit[0] - fit[i][0]);
186 cumsumTemp[0] = selectionfitness[0];
188 cumsumTemp[i] = cumsumTemp[i - 1] + selectionfitness[i];
191 cumsum[i] = cumsumTemp[i]/cumsumTemp[NP-1];
199 if (cumsum[j] > r2) {
211 Xnew[i]=X[selection[i]];
224 r1 = boost::uniform_int<int>(0,NP - 1)(
m_urng);
225 }
while ( r1 == boost::numeric_cast<int>(i) );
230 case crossover::BINOMIAL: {
231 size_t n = boost::uniform_int<int>(0,D-1)(
m_urng);
232 for (
size_t L = 0; L < D; ++L) {
233 if ((
m_drng() < m_cr) || L + 1 == D) {
234 member1[n] = member2[n];
240 case crossover::EXPONENTIAL: {
241 size_t n = boost::uniform_int<int>(0,D-1)(
m_urng);
244 member1[n] = member2[n];
247 }
while ( (
m_drng() < m_cr) && (L < boost::numeric_cast<int>(D)) );
256 case mutation::GAUSSIAN: {
257 boost::normal_distribution<double> dist;
258 boost::variate_generator<boost::lagged_fibonacci607 &, boost::normal_distribution<double> > delta(
m_drng,dist);
263 double mean = Xnew[i][k];
264 double tmp = (delta() * std + mean);
265 if ( (tmp < ub[k]) && (tmp > lb[k]) ) Xnew[i][k] = tmp;
273 double mean = Xnew[i][k];
274 double tmp = boost::math::iround(delta() * std + mean);
275 if ( (tmp < ub[k]) && (tmp > lb[k]) ) Xnew[i][k] = tmp;
281 case mutation::RANDOM: {
285 Xnew[i][j] = boost::uniform_real<double>(lb[j],ub[j])(
m_drng);
290 Xnew[i][j] = boost::uniform_int<int>(lb[j],ub[j])(
m_urng);
306 prob.
objfun(bestfit,bestX);
310 prob.
objfun(fit[i],Xnew[i]);
315 pop.push_back(Xnew[i]);
323 catch (
const std::bad_cast& e)
327 prob.
objfun(fit[i],Xnew[i]);
329 std::transform(dummy.begin(), dummy.end(), pop.
get_individual(i).
cur_x.begin(), dummy.begin(),std::minus<double>());
331 pop.set_x(i,Xnew[i]);
341 if (j % m_elitism == 0) {
347 fit[worst] = bestfit;
349 std::transform(dummy.begin(), dummy.end(), pop.
get_individual(worst).
cur_x.begin(), dummy.begin(),std::minus<double>());
351 pop.set_x(worst,Xnew[worst]);
352 pop.set_v(worst,dummy);
361 return "A Simple Genetic Algorithm";
370 std::ostringstream s;
371 s <<
"gen:" << m_gen <<
' ';
372 s <<
"CR:" << m_cr <<
' ';
373 s <<
"M:" << m_m <<
' ';
374 s <<
"elitism:" << m_elitism <<
' ';
377 case mutation::RANDOM: {
381 case mutation::GAUSSIAN: {
382 s <<
"GAUSSIAN (" << m_mut.
m_width <<
") ";
388 case selection::BEST20: {
392 case selection::ROULETTE: {
399 case crossover::EXPONENTIAL: {
403 case crossover::BINOMIAL: {
boost::shared_ptr< base > base_ptr
Alias for shared pointer to base algorithm.
std::vector< double > decision_vector
Decision vector type.
type
Selection type, best 20% or roulette.
fitness_vector cur_f
Current fitness vector.
const individual_type & get_individual(const size_type &) const
Get constant reference to individual at position n.
type
Crossover type, binomial or exponential.
size_type get_dimension() const
Return global dimension.
void evolve(population &) const
Evolve implementation.
bool compare_fitness(const fitness_vector &, const fitness_vector &) const
Compare fitness vectors.
double m_width
Mutation width.
fitness_vector objfun(const decision_vector &) const
Return fitness of pagmo::decision_vector.
size_type get_i_dimension() const
Return integer dimension.
std::vector< double > fitness_vector
Fitness vector type.
c_size_type get_c_dimension() const
Return global constraints dimension.
const decision_vector & get_ub() const
Upper bounds getter.
Base Stochastic Optimization Problem.
type
Mutation type, gaussian or random.
base_ptr clone() const
Clone method.
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.
sga(int gen=1, const double &cr=.95, const double &m=.02, int elitism=1, mutation::type mut=mutation::GAUSSIAN, double width=0.1, selection::type sel=selection::ROULETTE, crossover::type cro=crossover::EXPONENTIAL)
Constructor.
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.
std::string get_name() const
Algorithm name.
The Simple Genetic Algorithm (SGA)
std::string human_readable_extra() const
Extra human readable algorithm info.
type m_type
Mutation type.
decision_vector::size_type size_type
Problem's size type: the same as pagmo::decision_vector's size type.