25 #include <boost/random/uniform_int.hpp>
26 #include <boost/random/uniform_real.hpp>
27 #include <boost/random/normal_distribution.hpp>
28 #include <boost/random/variate_generator.hpp>
32 #include "../exceptions.h"
33 #include "../population.h"
40 namespace pagmo {
namespace algorithm {
55 de_1220::de_1220(
int gen,
int variant_adptv,
const std::vector<int> & allowed_variants,
bool memory,
double ftol,
double xtol):
base(), m_gen(gen),
56 m_variant_adptv(variant_adptv), m_allowed_variants(allowed_variants), m_memory(memory), m_ftol(ftol), m_xtol(xtol), m_f(0), m_cr(0), m_variants(0) {
58 pagmo_throw(value_error,
"number of generations must be nonnegative");
60 if (variant_adptv < 1 || variant_adptv > 2) {
61 pagmo_throw(value_error,
"the index describing the adaptive variant must be one of 1 ... 2");
63 for (
unsigned int i = 0; i < allowed_variants.size(); ++i) {
64 if ( (allowed_variants[i] <1) || (allowed_variants[i]>18) ) {
65 pagmo_throw(value_error,
"allowed variants must all be n [1,18]");
96 pagmo_throw(value_error,
"There is no continuous part in the problem decision vector for DE to optimise");
99 if ( prob_c_dimension != 0 ) {
100 pagmo_throw(value_error,
"The problem is not box constrained and DE is not suitable to solve it");
103 if ( prob_f_dimension != 1 ) {
104 pagmo_throw(value_error,
"The problem is not single objective and DE is not suitable to solve it");
108 pagmo_throw(value_error,
"for DE Self-Adaptive at least 8 individuals in the population are needed");
117 std::vector<decision_vector> popold(NP,dummy), popnew(NP,dummy);
121 std::vector<fitness_vector> fit(NP,gbfit);
124 for (std::vector<double>::size_type i = 0; i < NP; ++i) {
131 gbX=pop.champion().
x;
132 gbfit=pop.champion().
f;
137 boost::normal_distribution<double> normal(0.0,1.0);
138 boost::variate_generator<boost::lagged_fibonacci607 &, boost::normal_distribution<double> > n_dist(
m_drng,normal);
139 boost::uniform_real<double> uniform(0.0,1.0);
140 boost::variate_generator<boost::lagged_fibonacci607 &, boost::uniform_real<double> > r_dist(
m_drng,uniform);
141 boost::uniform_int<int> r_p_idx(0,NP-1);
142 boost::variate_generator<boost::mt19937 &, boost::uniform_int<int> > p_idx(
m_urng,r_p_idx);
143 boost::uniform_int<int> r_c_idx(0,Dc-1);
144 boost::variate_generator<boost::mt19937 &, boost::uniform_int<int> > c_idx(
m_urng,r_c_idx);
145 boost::uniform_int<int> r_v_idx(0,m_allowed_variants.size()-1);
146 boost::variate_generator<boost::mt19937 &, boost::uniform_int<int> > v_idx(
m_urng,r_v_idx);
150 if ( (m_cr.size() != NP) || (m_f.size() != NP) || (m_variants.size() != NP) || (!m_memory) ) {
151 m_cr.resize(NP); m_f.resize(NP); m_variants.resize(NP);
152 if (m_variant_adptv==1) {
153 for (
size_t i = 0; i < NP; ++i) {
155 m_f[i] = r_dist() * 0.9 + 0.1;
158 else if (m_variant_adptv==2) {
159 for (
size_t i = 0; i < NP; ++i) {
160 m_cr[i] = n_dist() * 0.15 + 0.5;
161 m_f[i] = n_dist() * 0.15 + 0.5;
164 for (
size_t i = 0; i < NP; ++i) {
166 m_variants[i] = m_allowed_variants[idx];
170 double gbIterF = m_f[0];
171 double gbIterCR = m_cr[0];
174 size_t r1,r2,r3,r4,r5,r6,r7;
175 for (
int gen = 0; gen < m_gen; ++gen) {
177 for (
size_t i = 0; i < NP; ++i) {
186 }
while ((r2==i) || (r2==r1));
191 }
while ((r3==i) || (r3==r1) || (r3==r2));
196 }
while ((r4==i) || (r4==r1) || (r4==r2) || (r4==r3));
201 }
while ((r5==i) || (r5==r1) || (r5==r2) || (r5==r3) || (r5==r4));
205 }
while ((r6==i) || (r6==r1) || (r6==r2) || (r6==r3) || (r6==r4) || (r6==r5));
209 }
while ((r7==i) || (r7==r1) || (r7==r2) || (r7==r3) || (r7==r4) || (r7==r5) || (r7==r6));
214 if (m_variant_adptv==1) {
215 F = (r_dist() < 0.9) ? m_f[i] : r_dist() * 0.9 + 0.1;
216 CR = (r_dist() < 0.9) ? m_cr[i] : r_dist();
218 VARIANT = (r_dist() < 0.9) ? m_variants[i] : m_allowed_variants[v_idx()];
224 if (m_variant_adptv==2) {
225 F = gbIterF + n_dist() * 0.5 * (m_f[r2]-m_f[r3]);
226 CR = gbIterCR + n_dist() * 0.5 * (m_cr[r2]-m_cr[r3]);
229 size_t n = c_idx(), L = 0;
231 tmp[n] = gbIter[n] + F*(popold[r2][n]-popold[r3][n]);
234 }
while ((r_dist() < CR) && (L < Dc));
241 else if (VARIANT == 2) {
242 if (m_variant_adptv==2) {
243 F = m_f[r1] + n_dist() * 0.5 * (m_f[r2]-m_f[r3]);
244 CR = m_cr[r1] + n_dist() * 0.5 * (m_cr[r2]-m_cr[r3]);
247 size_t n = c_idx(), L = 0;
249 tmp[n] = popold[r1][n] + F*(popold[r2][n]-popold[r3][n]);
252 }
while ((r_dist() < CR) && (L < Dc));
259 else if (VARIANT == 3) {
260 if (m_variant_adptv==2) {
261 F = m_f[i] + n_dist() * 0.5 * (gbIterF-m_f[i]) + n_dist() * 0.5 * (m_f[r1] - m_f[r2]);
262 CR = m_cr[i] + n_dist() * 0.5 * (gbIterCR-m_cr[i]) + n_dist() * 0.5 * (m_cr[r1] - m_cr[r2]);
265 size_t n = c_idx(), L = 0;
267 tmp[n] = tmp[n] + F*(gbIter[n] - tmp[n]) + F*(popold[r1][n]-popold[r2][n]);
270 }
while ((r_dist() < CR) && (L < Dc));
273 else if (VARIANT == 4) {
274 if (m_variant_adptv==2) {
275 F = gbIterF + n_dist() * 0.5 * (m_f[r1] - m_f[r3]) + n_dist() * 0.5 * (m_f[r2] - m_f[r4]);
276 CR = gbIterCR + n_dist() * 0.5 * (m_cr[r1] - m_cr[r3]) + n_dist() * 0.5 * (m_cr[r2] - m_cr[r4]);
279 size_t n = c_idx(), L = 0;
282 (popold[r1][n]+popold[r2][n]-popold[r3][n]-popold[r4][n])*F;
285 }
while ((r_dist() < CR) && (L < Dc));
288 else if (VARIANT == 5) {
289 if (m_variant_adptv==2) {
290 F = m_f[r5] + n_dist() * 0.5 * (m_f[r1] - m_f[r3]) + n_dist() * 0.5 * (m_f[r2] - m_f[r4]);
291 CR = m_cr[r5] + n_dist() * 0.5 * (m_cr[r1] - m_cr[r3]) + n_dist() * 0.5 * (m_cr[r2] - m_cr[r4]);
294 size_t n = c_idx(), L = 0;
296 tmp[n] = popold[r5][n] +
297 (popold[r1][n]+popold[r2][n]-popold[r3][n]-popold[r4][n])*F;
300 }
while ((r_dist() < CR) && (L < Dc));
306 else if (VARIANT == 6) {
307 if (m_variant_adptv==2) {
308 F = gbIterF + n_dist() * 0.5 * (m_f[r2]-m_f[r3]);
309 CR = gbIterCR + n_dist() * 0.5 * (m_cr[r2]-m_cr[r3]);
313 for (
size_t L = 0; L < Dc; ++L) {
314 if ((r_dist() < CR) || L + 1 == Dc) {
315 tmp[n] = gbIter[n] + F*(popold[r2][n]-popold[r3][n]);
321 else if (VARIANT == 7) {
322 if (m_variant_adptv==2) {
323 F = m_f[r1] + n_dist() * 0.5 * (m_f[r2]-m_f[r3]);
324 CR = m_cr[r1] + n_dist() * 0.5 * (m_cr[r2]-m_cr[r3]);
328 for (
size_t L = 0; L < Dc; ++L) {
329 if ((r_dist() < CR) || L + 1 == Dc) {
330 tmp[n] = popold[r1][n] + F*(popold[r2][n]-popold[r3][n]);
336 else if (VARIANT == 8) {
337 if (m_variant_adptv==2) {
338 F = m_f[i] + n_dist() * 0.5 * (gbIterF-m_f[i]) + n_dist() * 0.5 * (m_f[r1] - m_f[r2]);
339 CR = m_cr[i] + n_dist() * 0.5 * (gbIterCR-m_cr[i]) + n_dist() * 0.5 * (m_cr[r1] - m_cr[r2]);
343 for (
size_t L = 0; L < Dc; ++L) {
344 if ((r_dist() < CR) || L + 1 == Dc) {
345 tmp[n] = tmp[n] + F*(gbIter[n] - tmp[n]) + F*(popold[r1][n]-popold[r2][n]);
351 else if (VARIANT == 9) {
352 if (m_variant_adptv==2) {
353 F = gbIterF + n_dist() * 0.5 * (m_f[r1] - m_f[r3]) + n_dist() * 0.5 * (m_f[r2] - m_f[r4]);
354 CR = gbIterCR + n_dist() * 0.5 * (m_cr[r1] - m_cr[r3]) + n_dist() * 0.5 * (m_cr[r2] - m_cr[r4]);
358 for (
size_t L = 0; L < Dc; ++L) {
359 if ((r_dist() < CR) || L + 1 == Dc) {
361 (popold[r1][n]+popold[r2][n]-popold[r3][n]-popold[r4][n])*F;
367 else if (VARIANT == 10) {
368 if (m_variant_adptv==2) {
369 F = m_f[r5] + n_dist() * 0.5 * (m_f[r1] - m_f[r3]) + n_dist() * 0.5 * (m_f[r2] - m_f[r4]);
370 CR = m_cr[r5] + n_dist() * 0.5 * (m_cr[r1] - m_cr[r3]) + n_dist() * 0.5 * (m_cr[r2] - m_cr[r4]);
374 for (
size_t L = 0; L < Dc; ++L) {
375 if ((r_dist() < CR) || L + 1 == Dc) {
376 tmp[n] = popold[r5][n] +
377 (popold[r1][n]+popold[r2][n]-popold[r3][n]-popold[r4][n])*F;
385 if (m_variant_adptv==2) {
386 F = gbIterF + n_dist() * 0.5 * (m_f[r1] - m_f[r2]) + n_dist() * 0.5 * (m_f[r3] - m_f[r4]) + n_dist() * 0.5 * (m_f[r5] - m_f[r6]);
387 CR = gbIterCR + n_dist() * 0.5 * (m_cr[r1] - m_cr[r2]) + n_dist() * 0.5 * (m_cr[r3] - m_cr[r4]) + n_dist() * 0.5 * (m_cr[r5] - m_cr[r6]);
390 size_t n = c_idx(), L = 0;
392 tmp[n] = gbIter[n] + F*(popold[r1][n]-popold[r2][n]) + F*(popold[r3][n]-popold[r4][n]) + F*(popold[r5][n]-popold[r6][n]);
395 }
while ((r_dist() < CR) && (L < Dc));
398 else if (VARIANT == 12) {
399 if (m_variant_adptv==2) {
400 F = gbIterF + n_dist() * 0.5 * (m_f[r1] - m_f[r2]) + n_dist() * 0.5 * (m_f[r3] - m_f[r4]) + n_dist() * 0.5 * (m_f[r5] - m_f[r6]);
401 CR = gbIterCR + n_dist() * 0.5 * (m_cr[r1] - m_cr[r2]) + n_dist() * 0.5 * (m_cr[r3] - m_cr[r4]) + n_dist() * 0.5 * (m_cr[r5] - m_cr[r6]);
405 for (
size_t L = 0; L < Dc; ++L) {
406 if ((r_dist() < CR) || L + 1 == Dc) {
407 tmp[n] = gbIter[n] + F*(popold[r1][n]-popold[r2][n]) + F*(popold[r3][n]-popold[r4][n]) + F*(popold[r5][n]-popold[r6][n]);
414 if (m_variant_adptv==2) {
415 F = m_f[r7] + n_dist() * 0.5 * (m_f[r1] - m_f[r2]) + n_dist() * 0.5 * (m_f[r3] - m_f[r4]) + n_dist() * 0.5 * (m_f[r5] - m_f[r6]);
416 CR = m_cr[r7] + n_dist() * 0.5 * (m_cr[r1] - m_cr[r2]) + n_dist() * 0.5 * (m_cr[r3] - m_cr[r4]) + n_dist() * 0.5 * (m_cr[r5] - m_cr[r6]);
419 size_t n = c_idx(), L = 0;
421 tmp[n] = popold[r7][n] + F*(popold[r1][n]-popold[r2][n]) + F*(popold[r3][n]-popold[r4][n]) + F*(popold[r5][n]-popold[r6][n]);
424 }
while ((r_dist() < CR) && (L < Dc));
427 else if (VARIANT == 14) {
428 if (m_variant_adptv==2) {
429 F = m_f[r7] + n_dist() * 0.5 * (m_f[r1] - m_f[r2]) + n_dist() * 0.5 * (m_f[r3] - m_f[r4]) + n_dist() * 0.5 * (m_f[r5] - m_f[r6]);
430 CR = m_cr[r7] + n_dist() * 0.5 * (m_cr[r1] - m_cr[r2]) + n_dist() * 0.5 * (m_cr[r3] - m_cr[r4]) + n_dist() * 0.5 * (m_cr[r5] - m_cr[r6]);
434 for (
size_t L = 0; L < Dc; ++L) {
435 if ((r_dist() < CR) || L + 1 == Dc) {
436 tmp[n] = popold[r7][n] + F*(popold[r1][n]-popold[r2][n]) + F*(popold[r3][n]-popold[r4][n]) + F*(popold[r5][n]-popold[r6][n]);
443 if (m_variant_adptv==2) {
444 F = m_f[r7] + n_dist() * 0.5 * (m_f[r1] - m_f[i]) + n_dist() * 0.5 * (m_f[r3] - m_f[r4]) + n_dist() * 0.5 * (m_f[r5] - m_f[r6]);
445 CR = m_cr[r7] + n_dist() * 0.5 * (m_cr[r1] - m_cr[i]) + n_dist() * 0.5 * (m_cr[r3] - m_cr[r4]) + n_dist() * 0.5 * (m_cr[r5] - m_cr[r6]);
448 size_t n = c_idx(), L = 0;
450 tmp[n] = popold[r7][n] + F*(popold[r1][n]-popold[i][n]) + F*(popold[r3][n]-popold[r4][n]);
453 }
while ((r_dist() < CR) && (L < Dc));
456 else if (VARIANT == 16) {
457 if (m_variant_adptv==2) {
458 F = m_f[r7] + n_dist() * 0.5 * (m_f[r1] - m_f[i]) + n_dist() * 0.5 * (m_f[r3] - m_f[r4]) + n_dist() * 0.5 * (m_f[r5] - m_f[r6]);
459 CR = m_cr[r7] + n_dist() * 0.5 * (m_cr[r1] - m_cr[i]) + n_dist() * 0.5 * (m_cr[r3] - m_cr[r4]) + n_dist() * 0.5 * (m_cr[r5] - m_cr[r6]);
463 for (
size_t L = 0; L < Dc; ++L) {
464 if ((r_dist() < CR) || L + 1 == Dc) {
465 tmp[n] = popold[r7][n] + F*(popold[r1][n]-popold[i][n]) + F*(popold[r3][n]-popold[r4][n]);
472 if (m_variant_adptv==2) {
473 F = m_f[r7] + n_dist() * 0.5 * (m_f[r1] - m_f[i]) + n_dist() * 0.5 * (gbIterF - m_f[r4]);
474 CR = m_cr[r7] + n_dist() * 0.5 * (m_cr[r1] - m_cr[i]) + n_dist() * 0.5 * (gbIterCR - m_cr[r4]);
477 size_t n = c_idx(), L = 0;
479 tmp[n] = popold[r7][n] + F*(popold[r1][n]-popold[i][n]) + F*(gbIter[n]-popold[r4][n]);
482 }
while ((r_dist() < CR) && (L < Dc));
485 else if (VARIANT == 18) {
486 if (m_variant_adptv==2) {
487 F = m_f[r7] + n_dist() * 0.5 * (m_f[r1] - m_f[i]) + n_dist() * 0.5 * (gbIterF - m_f[r4]);
488 CR = m_cr[r7] + n_dist() * 0.5 * (m_cr[r1] - m_cr[i]) + n_dist() * 0.5 * (gbIterCR - m_cr[r4]);
492 for (
size_t L = 0; L < Dc; ++L) {
493 if ((r_dist() < CR) || L + 1 == Dc) {
494 tmp[n] = popold[r7][n] + F*(popold[r1][n]-popold[i][n]) + F*(gbIter[n]-popold[r4][n]);
504 if ((tmp[i2] < lb[i2]) || (tmp[i2] > ub[i2]))
505 tmp[i2] = r_dist() * (ub[i2]-lb[i2]) + lb[i2];
510 prob.
objfun(newfitness, tmp);
518 m_variants[i] = VARIANT;
522 std::transform(tmp.begin(), tmp.end(), pop.
get_individual(i).
cur_x.begin(), tmp.begin(),std::minus<double>());
525 pop.set_x(i,popnew[i]);
533 popnew[i] = popold[i];
542 std::swap(popold, popnew);
548 for (decision_vector::size_type i = 0; i < D; ++i) {
550 dx += std::fabs(tmp[i]);
555 std::cout <<
"Exit condition -- xtol < " << m_xtol << std::endl;
564 std::cout <<
"Exit condition -- ftol < " << m_ftol << std::endl;
573 std::cout <<
"Exit condition -- generations > " << m_gen << std::endl;
590 std::ostringstream s;
591 s <<
"gen:" << m_gen <<
' ';
592 s <<
"self_adaptation:" << m_variant_adptv <<
' ';
593 s <<
"variants:" << m_allowed_variants <<
' ';
594 s <<
"memory:" << m_memory <<
' ';
595 s <<
"ftol:" << m_ftol <<
' ';
596 s <<
"xtol:" << m_xtol;
boost::shared_ptr< base > base_ptr
Alias for shared pointer to base algorithm.
std::vector< double > decision_vector
Decision vector type.
std::string get_name() const
Algorithm name.
fitness_vector cur_f
Current fitness vector.
const individual_type & get_individual(const size_type &) const
Get constant reference to individual at position n.
Differential Evolution Algorithm - 1220 (our version!!)
size_type get_dimension() const
Return global dimension.
decision_vector x
Decision vector.
de_1220(int=100, int=1, const std::vector< int > &=construct_default_strategies(), bool=true, double=1e-6, double=1e-6)
Constructor.
bool compare_fitness(const fitness_vector &, const fitness_vector &) const
Compare fitness vectors.
fitness_vector f
Fitness vector.
fitness_vector objfun(const decision_vector &) const
Return fitness of pagmo::decision_vector.
void evolve(population &) const
Evolve implementation.
bool m_screen_output
Indicates to the derived class whether to print stuff on screen.
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.
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.
std::string human_readable_extra() const
Extra human readable algorithm info.
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.
base_ptr clone() const
Clone method.