25 #include <boost/random/uniform_int.hpp>
26 #include <boost/random/uniform_real.hpp>
30 #include "../exceptions.h"
31 #include "../population.h"
36 namespace pagmo {
namespace algorithm {
50 de::de(
int gen,
double f,
double cr,
int strategy,
double ftol,
double xtol):
base(),m_gen(gen),m_f(f),m_cr(cr),m_strategy(strategy),m_ftol(ftol),m_xtol(xtol) {
52 pagmo_throw(value_error,
"number of generations must be nonnegative");
54 if (strategy < 1 || strategy > 10) {
55 pagmo_throw(value_error,
"strategy index must be one of 1 ... 10");
57 if (cr < 0 || f < 0 || cr > 1 || f > 1) {
58 pagmo_throw(value_error,
"the f and cr parameters must be in the [0,1] range");
88 pagmo_throw(value_error,
"There is no continuous part in the problem decision vector for DE to optimise");
91 if ( prob_c_dimension != 0 ) {
92 pagmo_throw(value_error,
"The problem is not box constrained and DE is not suitable to solve it");
95 if ( prob_f_dimension != 1 ) {
96 pagmo_throw(value_error,
"The problem is not single objective and DE is not suitable to solve it");
100 pagmo_throw(value_error,
"for DE at least 6 individuals in the population are needed");
109 std::vector<decision_vector> popold(NP,dummy), popnew(NP,dummy);
113 std::vector<fitness_vector> fit(NP,gbfit);
116 for (std::vector<double>::size_type i = 0; i < NP; ++i) {
123 gbX=pop.champion().
x;
124 gbfit=pop.champion().
f;
129 size_t r1,r2,r3,r4,r5;
130 for (
int gen = 0; gen < m_gen; ++gen) {
132 for (
size_t i = 0; i < NP; ++i) {
135 r1 = boost::uniform_int<int>(0,NP-1)(
m_urng);
140 r2 = boost::uniform_int<int>(0,NP-1)(
m_urng);
141 }
while ((r2==i) || (r2==r1));
145 r3 = boost::uniform_int<int>(0,NP-1)(
m_urng);
146 }
while ((r3==i) || (r3==r1) || (r3==r2));
150 r4 = boost::uniform_int<int>(0,NP-1)(
m_urng);
151 }
while ((r4==i) || (r4==r1) || (r4==r2) || (r4==r3));
155 r5 = boost::uniform_int<int>(0,NP-1)(
m_urng);
156 }
while ((r5==i) || (r5==r1) || (r5==r2) || (r5==r3) || (r5==r4));
162 if (m_strategy == 1) {
164 size_t n = boost::uniform_int<int>(0,Dc-1)(
m_urng), L = 0;
166 tmp[n] = gbIter[n] + m_f*(popold[r2][n]-popold[r3][n]);
169 }
while ((
m_drng() < m_cr) && (L < Dc));
176 else if (m_strategy == 2) {
178 size_t n = boost::uniform_int<int>(0,Dc-1)(
m_urng), L = 0;
180 tmp[n] = popold[r1][n] + m_f*(popold[r2][n]-popold[r3][n]);
183 }
while ((
m_drng() < m_cr) && (L < Dc));
190 else if (m_strategy == 3) {
192 size_t n = boost::uniform_int<int>(0,Dc-1)(
m_urng), L = 0;
194 tmp[n] = tmp[n] + m_f*(gbIter[n] - tmp[n]) + m_f*(popold[r1][n]-popold[r2][n]);
197 }
while ((
m_drng() < m_cr) && (L < Dc));
200 else if (m_strategy == 4) {
202 size_t n = boost::uniform_int<int>(0,Dc-1)(
m_urng), L = 0;
205 (popold[r1][n]+popold[r2][n]-popold[r3][n]-popold[r4][n])*m_f;
208 }
while ((
m_drng() < m_cr) && (L < Dc));
211 else if (m_strategy == 5) {
213 size_t n = boost::uniform_int<int>(0,Dc-1)(
m_urng), L = 0;
215 tmp[n] = popold[r5][n] +
216 (popold[r1][n]+popold[r2][n]-popold[r3][n]-popold[r4][n])*m_f;
219 }
while ((
m_drng() < m_cr) && (L < Dc));
225 else if (m_strategy == 6) {
227 size_t n = boost::uniform_int<int>(0,Dc-1)(
m_urng);
228 for (
size_t L = 0; L < Dc; ++L) {
229 if ((
m_drng() < m_cr) || L + 1 == Dc) {
230 tmp[n] = gbIter[n] + m_f*(popold[r2][n]-popold[r3][n]);
236 else if (m_strategy == 7) {
238 size_t n = boost::uniform_int<int>(0,Dc-1)(
m_urng);
239 for (
size_t L = 0; L < Dc; ++L) {
240 if ((
m_drng() < m_cr) || L + 1 == Dc) {
241 tmp[n] = popold[r1][n] + m_f*(popold[r2][n]-popold[r3][n]);
247 else if (m_strategy == 8) {
249 size_t n = boost::uniform_int<int>(0,Dc-1)(
m_urng);
250 for (
size_t L = 0; L < Dc; ++L) {
251 if ((
m_drng() < m_cr) || L + 1 == Dc) {
252 tmp[n] = tmp[n] + m_f*(gbIter[n] - tmp[n]) + m_f*(popold[r1][n]-popold[r2][n]);
258 else if (m_strategy == 9) {
260 size_t n = boost::uniform_int<int>(0,Dc-1)(
m_urng);
261 for (
size_t L = 0; L < Dc; ++L) {
262 if ((
m_drng() < m_cr) || L + 1 == Dc) {
264 (popold[r1][n]+popold[r2][n]-popold[r3][n]-popold[r4][n])*m_f;
270 else if (m_strategy == 10) {
272 size_t n = boost::uniform_int<int>(0,Dc-1)(
m_urng);
273 for (
size_t L = 0; L < Dc; ++L) {
274 if ((
m_drng() < m_cr) || L + 1 == Dc) {
275 tmp[n] = popold[r5][n] +
276 (popold[r1][n]+popold[r2][n]-popold[r3][n]-popold[r4][n])*m_f;
287 if ((tmp[i2] < lb[i2]) || (tmp[i2] > ub[i2]))
288 tmp[i2] = boost::uniform_real<double>(lb[i2],ub[i2])(
m_drng);
293 prob.
objfun(newfitness, tmp);
299 std::transform(tmp.begin(), tmp.end(), pop.
get_individual(i).
cur_x.begin(), tmp.begin(),std::minus<double>());
301 pop.set_x(i,popnew[i]);
309 popnew[i] = popold[i];
318 std::swap(popold, popnew);
324 for (decision_vector::size_type i = 0; i < D; ++i) {
326 dx += std::fabs(tmp[i]);
331 std::cout <<
"Exit condition -- xtol < " << m_xtol << std::endl;
340 std::cout <<
"Exit condition -- ftol < " << m_ftol << std::endl;
347 std::cout <<
"Generation " << gen <<
" ***" << std::endl;
348 std::cout <<
" Best global fitness: " << pop.champion().
f << std::endl;
349 std::cout <<
" xtol: " << dx <<
", ftol: " << mah << std::endl;
350 std::cout <<
" xtol: " << dx <<
", ftol: " << mah << std::endl;
358 std::cout <<
"Exit condition -- generations > " << m_gen << std::endl;
366 return "Differential Evolution";
376 if (cr < 0 || cr > 1 ) {
377 pagmo_throw(value_error,
"the cr parameter must be in the [0,1] range");
389 if (f < 0 || f > 1 ) {
390 pagmo_throw(value_error,
"the cr parameter must be in the [0,1] range");
421 std::ostringstream s;
422 s <<
"gen:" << m_gen <<
' ';
423 s <<
"F: " << m_f <<
' ';
424 s <<
"CR: " << m_cr <<
' ';
425 s <<
"variant:" << m_strategy <<
' ';
426 s <<
"ftol:" << m_ftol <<
' ';
427 s <<
"xtol:" << m_xtol;
boost::shared_ptr< base > base_ptr
Alias for shared pointer to base algorithm.
void evolve(population &) const
Evolve implementation.
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.
void set_f(double cr)
Sets f parameter.
de(int=100, double=0.8, double=0.9, int=2, double=1e-6, double=1e-6)
Constructor.
void set_cr(double cr)
Sets crossover parameter.
base_ptr clone() const
Clone method.
size_type get_dimension() const
Return global dimension.
decision_vector x
Decision vector.
bool compare_fitness(const fitness_vector &, const fitness_vector &) const
Compare fitness vectors.
double get_f() const
Gets f parameter.
fitness_vector f
Fitness vector.
Differential Evolution Algorithm.
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.
double get_cr() const
Gets crossover parameter.
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.
std::string human_readable_extra() const
Extra human readable algorithm info.
const decision_vector & get_lb() const
Lower bounds getter.
std::string get_name() const
Algorithm name.
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.