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>
33 #include "../exceptions.h"
34 #include "../population.h"
35 #include "../problem/base.h"
38 #include "../problem/base_stochastic.h"
39 #include "../problem/decompose.h"
41 namespace pagmo {
namespace algorithm {
59 :
base(),m_gen(gen),m_cr(cr),m_m(m),m_elitism(elitism),m_mut(mut,width),m_cro(cro)
62 pagmo_throw(value_error,
"number of generations must be nonnegative");
64 if (cr > 1 || cr < 0) {
65 pagmo_throw(value_error,
"crossover probability must be in the [0,1] range");
68 pagmo_throw(value_error,
"mutation probability must be in the [0,1] range");
71 pagmo_throw(value_error,
"elitisim must be greater than zero");
73 if (width <0 || width >1) {
74 pagmo_throw(value_error,
"mutation width must be in the [0,1] range");
101 if( prob_c_dimension != 0 ) {
102 pagmo_throw(value_error,
"The problem is not box constrained and VEGA is not suitable to solve it");
105 if( prob_f_dimension < 2 ) {
106 pagmo_throw(value_error,
"The problem is not multiobjective and VEGA is not suitable to solve it");
109 if(NP < 5*prob_f_dimension) {
110 pagmo_throw(value_error,
"for VEGA at least 5 * number of objectives individuals in the population are needed");
113 if( (NP%prob_f_dimension != 0) && (NP != 1) ) {
114 pagmo_throw(value_error,
"for VEGA the population size must a multiple of the number of objectives");
127 std::vector<decision_vector > X(NP,dummy);
128 std::vector<decision_vector > Xnew(NP,dummy);
130 std::vector<fitness_vector > fit(NP);
133 std::vector<double> selectionfitness(sub_pop_size);
134 std::vector<double> cumsum(sub_pop_size);
135 std::vector<double> cumsumTemp(sub_pop_size);
137 std::vector<population::size_type> selection(sub_pop_size);
153 std::vector<problem::base_ptr> sub_probs;
154 std::vector< std::vector<decision_vector> > sub_x(prob_f_dimension);
155 std::vector< std::vector<fitness_vector> > sub_f(prob_f_dimension);
158 for(
unsigned int i=0; i<prob_f_dimension; i++) {
159 std::vector<double> sub_prob_weights(prob_f_dimension,0.);
160 sub_prob_weights[i] = 1.;
165 for(
int j=0; j<m_gen; j++) {
167 boost::uniform_int<int> pop_idx(0,NP-1);
168 boost::variate_generator<boost::mt19937 &, boost::uniform_int<int> > p_idx(
m_urng,pop_idx);
171 std::random_shuffle(X.begin(),X.end(),p_idx);
174 for(
unsigned int sp_idx=0; sp_idx<prob_f_dimension; sp_idx++) {
176 std::vector<fitness_vector> ¤t_sub_f = sub_f[sp_idx];
177 std::vector<decision_vector> ¤t_sub_x = sub_x[sp_idx];
179 current_sub_f = std::vector<fitness_vector>(sub_pop_size);
180 current_sub_x = std::vector<decision_vector>(sub_pop_size);
187 current_sub_x[k] = X.at(sub_pop_begin_idx + k);
188 current_sub_f[k] = current_sub_prob->objfun(current_sub_x[k]);
193 for(
unsigned int sp_idx=0; sp_idx<prob_f_dimension; sp_idx++) {
195 std::vector<fitness_vector> ¤t_sub_f = sub_f[sp_idx];
207 if(current_sub_prob->compare_fitness(worstfit, current_sub_f[i]))
208 worstfit = current_sub_f[i];
212 selectionfitness[i] = fabs(worstfit[0] - current_sub_f[i][0]);
216 cumsumTemp[0] = selectionfitness[0];
219 cumsumTemp[i] = cumsumTemp[i - 1] + selectionfitness[i];
222 cumsum[i] = cumsumTemp[i] / cumsumTemp[sub_pop_size-1];
243 std::vector<decision_vector> ¤t_sub_x = sub_x[sp_idx];
247 Xnew[sub_pop_begin_idx + i] = current_sub_x[selection[i]];
261 r1 = boost::uniform_int<int>(0,NP - 1)(
m_urng);
262 }
while ( r1 == boost::numeric_cast<int>(i) );
267 case crossover::BINOMIAL: {
268 size_t n = boost::uniform_int<int>(0,D-1)(
m_urng);
269 for (
size_t L = 0; L < D; ++L) {
270 if ((
m_drng() < m_cr) || L + 1 == D) {
271 member1[n] = member2[n];
277 case crossover::EXPONENTIAL: {
278 size_t n = boost::uniform_int<int>(0,D-1)(
m_urng);
281 member1[n] = member2[n];
284 }
while ( (
m_drng() < m_cr) && (L < boost::numeric_cast<int>(D)) );
293 case mutation::GAUSSIAN: {
294 boost::normal_distribution<double> dist;
295 boost::variate_generator<boost::lagged_fibonacci607 &, boost::normal_distribution<double> > delta(
m_drng,dist);
300 double mean = Xnew[i][k];
301 double tmp = (delta() * std + mean);
302 if ( (tmp < ub[k]) && (tmp > lb[k]) ) Xnew[i][k] = tmp;
310 double mean = Xnew[i][k];
311 double tmp = boost::math::iround(delta() * std + mean);
312 if ( (tmp < ub[k]) && (tmp > lb[k]) ) Xnew[i][k] = tmp;
318 case mutation::RANDOM: {
322 Xnew[i][j] = boost::uniform_real<double>(lb[j],ub[j])(
m_drng);
327 Xnew[i][j] = boost::uniform_int<int>(lb[j],ub[j])(
m_urng);
343 prob.
objfun(bestfit,bestX);
347 prob.
objfun(fit[i],Xnew[i]);
352 pop.push_back(Xnew[i]);
360 catch (
const std::bad_cast& e)
364 prob.
objfun(fit[i],Xnew[i]);
366 std::transform(dummy.begin(), dummy.end(), pop.
get_individual(i).
cur_x.begin(), dummy.begin(),std::minus<double>());
368 pop.set_x(i,Xnew[i]);
380 if (j % m_elitism == 0) {
386 fit[worst] = bestfit;
388 std::transform(dummy.begin(), dummy.end(), pop.
get_individual(worst).
cur_x.begin(), dummy.begin(),std::minus<double>());
390 pop.set_x(worst,Xnew[worst]);
391 pop.set_v(worst,dummy);
402 return "Vector evaluated genetic algorithm (VEGA)";
411 std::ostringstream s;
412 s <<
"gen:" << m_gen <<
' ';
413 s <<
"CR:" << m_cr <<
' ';
414 s <<
"M:" << m_m <<
' ';
415 s <<
"elitism:" << m_elitism <<
' ';
418 case mutation::RANDOM: {
422 case mutation::GAUSSIAN: {
423 s <<
"GAUSSIAN (" << m_mut.
m_width <<
") ";
429 case crossover::EXPONENTIAL: {
433 case crossover::BINOMIAL: {
boost::shared_ptr< base > base_ptr
Alias for shared pointer to base algorithm.
boost::shared_ptr< base > base_ptr
Alias for shared pointer to base problem.
std::vector< double > decision_vector
Decision vector type.
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 m_type
Mutation type.
vega(int gen=1, const double &cr=.95, const double &m=.02, int elitism=1, mutation::type mut=mutation::GAUSSIAN, double width=0.1, crossover::type cro=crossover::EXPONENTIAL)
Constructor.
std::string human_readable_extra() const
Extra human readable algorithm info.
size_type get_dimension() const
Return global dimension.
std::string get_name() const
Algorithm name.
bool compare_fitness(const fitness_vector &, const fitness_vector &) const
Compare fitness vectors.
fitness_vector objfun(const decision_vector &) const
Return fitness of pagmo::decision_vector.
VEGA based multi-objective algorithm.
size_type get_i_dimension() const
Return integer dimension.
type
Mutation type, gaussian or random.
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.
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.
The fitness function is the weighted sum of the multiple original fitnesses.
const decision_vector & get_lb() const
Lower bounds getter.
double m_width
Mutation width.
rng_double m_drng
Random number generator for double-precision floating point values.
void evolve(population &) const
Evolve implementation.
decision_vector::size_type size_type
Problem's size type: the same as pagmo::decision_vector's size type.
type
Crossover type, binomial or exponential.
base_ptr clone() const
Clone method.