25 #include <boost/math/constants/constants.hpp>
26 #include <boost/random/uniform_int.hpp>
27 #include <boost/random/uniform_real.hpp>
28 #include <boost/random/normal_distribution.hpp>
29 #include <boost/random/cauchy_distribution.hpp>
30 #include <boost/random/variate_generator.hpp>
36 #include "../exceptions.h"
37 #include "../population.h"
42 namespace pagmo {
namespace algorithm {
56 mde_pbx::mde_pbx(
int gen,
double qperc,
double nexp,
double ftol,
double xtol):
base(), m_gen(gen), m_fsuccess(), m_fm(0.5),
57 m_crsuccess(), m_crm(0.7), m_qperc(qperc), m_nexp(nexp), m_ftol(ftol), m_xtol(xtol) {
59 pagmo_throw(value_error,
"number of generations must be nonnegative");
61 if (qperc < 0.0 || qperc > 1.0) {
62 pagmo_throw(value_error,
"percentage of population to choose from must be between 0.0 and 1.0");
65 pagmo_throw(value_error,
"the exponent of the powermean must not be 0.0!");
93 pagmo_throw(value_error,
"Dimension of the problem shall not be zero!");
97 pagmo_throw(value_error,
"The problem is not box constrained and MDE_pBX is not suitable to solve it");
101 pagmo_throw(value_error,
"The problem is not single objective and MDE_pBX is not suitable to solve it");
105 pagmo_throw(value_error,
"for this algorithm, at least 3 individuals in the population are needed");
109 pagmo_throw(value_error,
"You need a higher number of individuals in your population for sampling");
122 m_fsuccess.reserve(NP);
123 m_crsuccess.reserve(NP);
126 boost::uniform_real<double> uniform(0.0,1.0);
127 boost::variate_generator<boost::lagged_fibonacci607 &, boost::uniform_real<double> > r_dist(
m_drng,uniform);
129 boost::uniform_int<decision_vector::size_type> r_c_idx(0,D-1);
130 boost::variate_generator<boost::mt19937 &, boost::uniform_int<decision_vector::size_type> > c_idx(
m_urng,r_c_idx);
132 boost::uniform_int<population::size_type> r_p_idx(0,NP-1);
133 boost::variate_generator<boost::mt19937 &, boost::uniform_int<population::size_type> > p_idx(
m_urng,r_p_idx);
135 boost::normal_distribution<double> nd(0.0, 1.0);
136 boost::variate_generator<boost::lagged_fibonacci607 &, boost::normal_distribution<double> > gauss(
m_drng,nd);
141 std::vector<population::size_type> a(NP-1,0);
145 for (
int gen = 0; gen < m_gen; ++gen) {
157 p = ceil((NP / 2.0) * ( 1.0 - (
double)(gen) / m_gen));
160 std::vector<population::size_type> pbest = pop_old.get_best_idx(p);
168 (k<i) ? a[k] = k : a[k] = k+1;
172 r1 = boost::uniform_int<int>(k,NP-2)(
m_urng);
173 std::swap(a[k], a[r1]);
188 }
while ((r1==i) || (r1==bestq_idx));
193 }
while ((r2==i) || (r2==r1) || (r2==bestq_idx));
195 bestp_idx = pbest[boost::uniform_int<int>(0,p-1)(
m_urng)];
199 cri = 0.1 * gauss()+m_crm;
203 cri = std::min(1.0,std::max(0.0,cri));
208 fi = m_fm + 0.1 * tan(boost::math::constants::pi<double>() * ( r_dist() - 0.5 ));
209 fi = std::min(1.0,fi);
216 for (
size_t j = 0; j < D; ++j) {
217 if (j == j_rand || r_dist() < cri) {
220 if ((tmp[j] < lb[j]) || (tmp[j] > ub[j])) {
221 tmp[j] = lb[j]+ r_dist()*(ub[j]-lb[j]);
232 prob.
objfun(newfitness, tmp);
237 std::transform(tmp.begin(), tmp.end(), pop_old.
get_individual(i).
cur_x.begin(), tmp.begin(),std::minus<double>());
242 m_crsuccess.push_back(cri);
243 m_fsuccess.push_back(fi);
248 if (!m_crsuccess.empty()) {
252 m_crm = (0.9+0.001*std::abs(gauss()))*m_crm + 0.1*(1+0.001*std::abs(gauss())) *
powermean(m_crsuccess, m_nexp);
255 (m_fm < 0.85) ? m_fm = (0.9+0.01*std::abs(gauss()))*m_fm + 0.1*(1+0.01*std::abs(gauss())) *
powermean(m_fsuccess, m_nexp) :
256 m_fm = (0.8+0.01*std::abs(gauss()))*m_fm + 0.1*(1+0.01*std::abs(gauss())) *
powermean(m_fsuccess, m_nexp);
264 for (decision_vector::size_type k = 0; k < D; ++k) {
266 dx += std::fabs(tmp[k]);
271 std::cout <<
"Exit condition -- xtol < " << m_xtol << std::endl;
280 std::cout <<
"Exit condition -- ftol < " << m_ftol << std::endl;
287 std::cout <<
"Generation " << gen <<
" ***" << std::endl;
288 std::cout <<
" Best global fitness: " << pop.champion().
f << std::endl;
289 std::cout <<
" Fm: " << m_fm <<
", Crm: " << m_crm <<
", p: " << p << std::endl;
290 std::cout <<
" xtol: " << dx <<
", ftol: " << mah << std::endl;
296 std::cout <<
"Exit condition -- generations > " << m_gen << std::endl;
311 size_t vsize = v.size();
313 if (vsize == 0)
return 0;
315 for (
size_t i = 0; i < vsize; ++i) {
316 sum += std::pow(v[i], exp) ;
318 return std::pow((sum / vsize), (1.0 / exp));
327 std::ostringstream s;
328 s <<
"gen:" << m_gen <<
' ';
329 s <<
"q percentage:" << m_qperc <<
' ';
330 s <<
"power mean exponent:" << m_nexp <<
' ';
331 s <<
"ftol:" << m_ftol <<
' ';
332 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.
std::string human_readable_extra() const
Extra human readable algorithm info.
MDE_pBX - Differential Evolution variant.
double powermean(std::vector< double >, double) const
Computes the powermean of a set given as a vector.
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.
fitness_vector f
Fitness vector.
fitness_vector objfun(const decision_vector &) const
Return fitness of pagmo::decision_vector.
base_ptr clone() const
Clone method.
bool m_screen_output
Indicates to the derived class whether to print stuff on screen.
mde_pbx(int=100, double=0.15, double=1.5, double=1e-30, double=1e-30)
Constructor.
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.
std::string get_name() const
Algorithm name.