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"
38 namespace pagmo {
namespace algorithm {
52 jde::jde(
int gen,
int variant,
int variant_adptv,
double ftol,
double xtol,
bool memory):
base(), m_gen(gen), m_f(0), m_cr(0),
53 m_variant(variant), m_variant_adptv(variant_adptv), m_ftol(ftol), m_xtol(xtol), m_memory(memory) {
55 pagmo_throw(value_error,
"number of generations must be nonnegative");
57 if (variant < 1 || variant > 18) {
58 pagmo_throw(value_error,
"variant index must be one of 1 ... 18");
60 if (variant_adptv < 1 || variant_adptv > 2) {
61 pagmo_throw(value_error,
"adaptive variant index must be one of 1 ... 2");
91 pagmo_throw(value_error,
"There is no continuous part in the problem decision vector for DE to optimise");
94 if ( prob_c_dimension != 0 ) {
95 pagmo_throw(value_error,
"The problem is not box constrained and DE is not suitable to solve it");
98 if ( prob_f_dimension != 1 ) {
99 pagmo_throw(value_error,
"The problem is not single objective and DE is not suitable to solve it");
103 pagmo_throw(value_error,
"for jDE at least 8 individuals in the population are needed");
112 std::vector<decision_vector> popold(NP,dummy), popnew(NP,dummy);
116 std::vector<fitness_vector> fit(NP,gbfit);
119 for (std::vector<double>::size_type i = 0; i < NP; ++i) {
126 gbX=pop.champion().
x;
127 gbfit=pop.champion().
f;
132 boost::normal_distribution<double> normal(0.0,1.0);
133 boost::variate_generator<boost::lagged_fibonacci607 &, boost::normal_distribution<double> > n_dist(
m_drng,normal);
134 boost::uniform_real<double> uniform(0.0,1.0);
135 boost::variate_generator<boost::lagged_fibonacci607 &, boost::uniform_real<double> > r_dist(
m_drng,uniform);
136 boost::uniform_int<int> r_p_idx(0,NP-1);
137 boost::variate_generator<boost::mt19937 &, boost::uniform_int<int> > p_idx(
m_urng,r_p_idx);
138 boost::uniform_int<int> r_c_idx(0,Dc-1);
139 boost::variate_generator<boost::mt19937 &, boost::uniform_int<int> > c_idx(
m_urng,r_c_idx);
143 if ( (m_cr.size() != NP) || (m_f.size() != NP) || (!m_memory) ) {
144 m_cr.resize(NP); m_f.resize(NP);
145 if (m_variant_adptv==1) {
146 for (
size_t i = 0; i < NP; ++i) {
148 m_f[i] = r_dist() * 0.9 + 0.1;
151 else if (m_variant_adptv==2) {
152 for (
size_t i = 0; i < NP; ++i) {
153 m_cr[i] = n_dist() * 0.15 + 0.5;
154 m_f[i] = n_dist() * 0.15 + 0.5;
159 double gbIterF = m_f[0];
160 double gbIterCR = m_cr[0];
163 size_t r1,r2,r3,r4,r5,r6,r7;
164 for (
int gen = 0; gen < m_gen; ++gen) {
168 for (decision_vector::size_type i = 0; i < D; ++i) {
170 dx += std::fabs(tmp[i]);
175 std::cout <<
"Exit condition -- xtol < " << m_xtol << std::endl;
184 std::cout <<
"Exit condition -- ftol < " << m_ftol << std::endl;
191 for (
size_t i = 0; i < NP; ++i) {
200 }
while ((r2==i) || (r2==r1));
205 }
while ((r3==i) || (r3==r1) || (r3==r2));
210 }
while ((r4==i) || (r4==r1) || (r4==r2) || (r4==r3));
215 }
while ((r5==i) || (r5==r1) || (r5==r2) || (r5==r3) || (r5==r4));
219 }
while ((r6==i) || (r6==r1) || (r6==r2) || (r6==r3) || (r6==r4) || (r6==r5));
223 }
while ((r7==i) || (r7==r1) || (r7==r2) || (r7==r3) || (r7==r4) || (r7==r5) || (r7==r6));
227 if (m_variant_adptv==1) {
228 F = (r_dist() < 0.9) ? m_f[i] : r_dist() * 0.9 + 0.1;
229 CR = (r_dist() < 0.9) ? m_cr[i] : r_dist();
235 if (m_variant == 1) {
236 if (m_variant_adptv==2) {
237 F = gbIterF + n_dist() * 0.5 * (m_f[r2]-m_f[r3]);
238 CR = gbIterCR + n_dist() * 0.5 * (m_cr[r2]-m_cr[r3]);
241 size_t n = c_idx(), L = 0;
243 tmp[n] = gbIter[n] + F*(popold[r2][n]-popold[r3][n]);
246 }
while ((r_dist() < CR) && (L < Dc));
253 else if (m_variant == 2) {
254 if (m_variant_adptv==2) {
255 F = m_f[r1] + n_dist() * 0.5 * (m_f[r2]-m_f[r3]);
256 CR = m_cr[r1] + n_dist() * 0.5 * (m_cr[r2]-m_cr[r3]);
259 size_t n = c_idx(), L = 0;
261 tmp[n] = popold[r1][n] + F*(popold[r2][n]-popold[r3][n]);
264 }
while ((r_dist() < CR) && (L < Dc));
271 else if (m_variant == 3) {
272 if (m_variant_adptv==2) {
273 F = m_f[i] + n_dist() * 0.5 * (gbIterF-m_f[i]) + n_dist() * 0.5 * (m_f[r1] - m_f[r2]);
274 CR = m_cr[i] + n_dist() * 0.5 * (gbIterCR-m_cr[i]) + n_dist() * 0.5 * (m_cr[r1] - m_cr[r2]);
277 size_t n = c_idx(), L = 0;
279 tmp[n] = tmp[n] + F*(gbIter[n] - tmp[n]) + F*(popold[r1][n]-popold[r2][n]);
282 }
while ((r_dist() < CR) && (L < Dc));
285 else if (m_variant == 4) {
286 if (m_variant_adptv==2) {
287 F = gbIterF + n_dist() * 0.5 * (m_f[r1] - m_f[r3]) + n_dist() * 0.5 * (m_f[r2] - m_f[r4]);
288 CR = gbIterCR + n_dist() * 0.5 * (m_cr[r1] - m_cr[r3]) + n_dist() * 0.5 * (m_cr[r2] - m_cr[r4]);
291 size_t n = c_idx(), L = 0;
294 (popold[r1][n]+popold[r2][n]-popold[r3][n]-popold[r4][n])*F;
297 }
while ((r_dist() < CR) && (L < Dc));
300 else if (m_variant == 5) {
301 if (m_variant_adptv==2) {
302 F = m_f[r5] + n_dist() * 0.5 * (m_f[r1] - m_f[r3]) + n_dist() * 0.5 * (m_f[r2] - m_f[r4]);
303 CR = m_cr[r5] + n_dist() * 0.5 * (m_cr[r1] - m_cr[r3]) + n_dist() * 0.5 * (m_cr[r2] - m_cr[r4]);
306 size_t n = c_idx(), L = 0;
308 tmp[n] = popold[r5][n] +
309 (popold[r1][n]+popold[r2][n]-popold[r3][n]-popold[r4][n])*F;
312 }
while ((r_dist() < CR) && (L < Dc));
318 else if (m_variant == 6) {
319 if (m_variant_adptv==2) {
320 F = gbIterF + n_dist() * 0.5 * (m_f[r2]-m_f[r3]);
321 CR = gbIterCR + n_dist() * 0.5 * (m_cr[r2]-m_cr[r3]);
325 for (
size_t L = 0; L < Dc; ++L) {
326 if ((r_dist() < CR) || L + 1 == Dc) {
327 tmp[n] = gbIter[n] + F*(popold[r2][n]-popold[r3][n]);
333 else if (m_variant == 7) {
334 if (m_variant_adptv==2) {
335 F = m_f[r1] + n_dist() * 0.5 * (m_f[r2]-m_f[r3]);
336 CR = m_cr[r1] + n_dist() * 0.5 * (m_cr[r2]-m_cr[r3]);
340 for (
size_t L = 0; L < Dc; ++L) {
341 if ((r_dist() < CR) || L + 1 == Dc) {
342 tmp[n] = popold[r1][n] + F*(popold[r2][n]-popold[r3][n]);
348 else if (m_variant == 8) {
349 if (m_variant_adptv==2) {
350 F = m_f[i] + n_dist() * 0.5 * (gbIterF-m_f[i]) + n_dist() * 0.5 * (m_f[r1] - m_f[r2]);
351 CR = m_cr[i] + n_dist() * 0.5 * (gbIterCR-m_cr[i]) + n_dist() * 0.5 * (m_cr[r1] - m_cr[r2]);
355 for (
size_t L = 0; L < Dc; ++L) {
356 if ((r_dist() < CR) || L + 1 == Dc) {
357 tmp[n] = tmp[n] + F*(gbIter[n] - tmp[n]) + F*(popold[r1][n]-popold[r2][n]);
363 else if (m_variant == 9) {
364 if (m_variant_adptv==2) {
365 F = gbIterF + n_dist() * 0.5 * (m_f[r1] - m_f[r3]) + n_dist() * 0.5 * (m_f[r2] - m_f[r4]);
366 CR = gbIterCR + n_dist() * 0.5 * (m_cr[r1] - m_cr[r3]) + n_dist() * 0.5 * (m_cr[r2] - m_cr[r4]);
370 for (
size_t L = 0; L < Dc; ++L) {
371 if ((r_dist() < CR) || L + 1 == Dc) {
373 (popold[r1][n]+popold[r2][n]-popold[r3][n]-popold[r4][n])*F;
379 else if (m_variant == 10) {
380 if (m_variant_adptv==2) {
381 F = m_f[r5] + n_dist() * 0.5 * (m_f[r1] - m_f[r3]) + n_dist() * 0.5 * (m_f[r2] - m_f[r4]);
382 CR = m_cr[r5] + n_dist() * 0.5 * (m_cr[r1] - m_cr[r3]) + n_dist() * 0.5 * (m_cr[r2] - m_cr[r4]);
386 for (
size_t L = 0; L < Dc; ++L) {
387 if ((r_dist() < CR) || L + 1 == Dc) {
388 tmp[n] = popold[r5][n] +
389 (popold[r1][n]+popold[r2][n]-popold[r3][n]-popold[r4][n])*F;
396 if (m_variant == 11) {
397 if (m_variant_adptv==2) {
398 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]);
399 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]);
402 size_t n = c_idx(), L = 0;
404 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]);
407 }
while ((r_dist() < CR) && (L < Dc));
410 else if (m_variant == 12) {
411 if (m_variant_adptv==2) {
412 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]);
413 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]);
417 for (
size_t L = 0; L < Dc; ++L) {
418 if ((r_dist() < CR) || L + 1 == Dc) {
419 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]);
425 if (m_variant == 13) {
426 if (m_variant_adptv==2) {
427 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]);
428 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]);
431 size_t n = c_idx(), L = 0;
433 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]);
436 }
while ((r_dist() < CR) && (L < Dc));
439 else if (m_variant == 14) {
440 if (m_variant_adptv==2) {
441 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]);
442 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]);
446 for (
size_t L = 0; L < Dc; ++L) {
447 if ((r_dist() < CR) || L + 1 == Dc) {
448 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]);
454 if (m_variant == 15) {
455 if (m_variant_adptv==2) {
456 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]);
457 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]);
460 size_t n = c_idx(), L = 0;
462 tmp[n] = popold[r7][n] + F*(popold[r1][n]-popold[i][n]) + F*(popold[r3][n]-popold[r4][n]);
465 }
while ((r_dist() < CR) && (L < Dc));
468 else if (m_variant == 16) {
469 if (m_variant_adptv==2) {
470 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]);
471 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]);
475 for (
size_t L = 0; L < Dc; ++L) {
476 if ((r_dist() < CR) || L + 1 == Dc) {
477 tmp[n] = popold[r7][n] + F*(popold[r1][n]-popold[i][n]) + F*(popold[r3][n]-popold[r4][n]);
483 if (m_variant == 17) {
484 if (m_variant_adptv==2) {
485 F = m_f[r7] + n_dist() * 0.5 * (m_f[r1] - m_f[i]) + n_dist() * 0.5 * (gbIterF - m_f[r4]);
486 CR = m_cr[r7] + n_dist() * 0.5 * (m_cr[r1] - m_cr[i]) + n_dist() * 0.5 * (gbIterCR - m_cr[r4]);
489 size_t n = c_idx(), L = 0;
491 tmp[n] = popold[r7][n] + F*(popold[r1][n]-popold[i][n]) + F*(gbIter[n]-popold[r4][n]);
494 }
while ((r_dist() < CR) && (L < Dc));
497 else if (m_variant == 18) {
498 if (m_variant_adptv==2) {
499 F = m_f[r7] + n_dist() * 0.5 * (m_f[r1] - m_f[i]) + n_dist() * 0.5 * (gbIterF - m_f[r4]);
500 CR = m_cr[r7] + n_dist() * 0.5 * (m_cr[r1] - m_cr[i]) + n_dist() * 0.5 * (gbIterCR - m_cr[r4]);
504 for (
size_t L = 0; L < Dc; ++L) {
505 if ((r_dist() < CR) || L + 1 == Dc) {
506 tmp[n] = popold[r7][n] + F*(popold[r1][n]-popold[i][n]) + F*(gbIter[n]-popold[r4][n]);
516 if ((tmp[i2] < lb[i2]) || (tmp[i2] > ub[i2]))
517 tmp[i2] = r_dist() * (ub[i2]-lb[i2]) + lb[i2];
522 prob.
objfun(newfitness, tmp);
533 std::transform(tmp.begin(), tmp.end(), pop.
get_individual(i).
cur_x.begin(), tmp.begin(),std::minus<double>());
536 pop.set_x(i,popnew[i]);
544 popnew[i] = popold[i];
553 std::swap(popold, popnew);
557 std::cout <<
"Exit condition -- generations > " << m_gen << std::endl;
573 std::ostringstream s;
574 s <<
"gen:" << m_gen <<
' ';
575 s <<
"variant:" << m_variant <<
' ';
576 s <<
"self_adaptation:" << m_variant_adptv <<
' ';
577 s <<
"memory:" << m_memory <<
' ';
578 s <<
"ftol:" << m_ftol <<
' ';
579 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.
fitness_vector cur_f
Current fitness vector.
const individual_type & get_individual(const size_type &) const
Get constant reference to individual at position n.
base_ptr clone() const
Clone method.
jde(int=100, int=2, int=1, double=1e-6, double=1e-6, bool=false)
Constructor.
std::string human_readable_extra() const
Extra human readable algorithm info.
size_type get_dimension() const
Return global dimension.
decision_vector x
Decision vector.
void evolve(population &) const
Evolve implementation.
std::string get_name() const
Algorithm name.
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.
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.
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.
jDE - Differential Evolution Algorithm - Self-Adaptive C and R (2011)