25 #include <boost/random/uniform_int.hpp>
26 #include <boost/random/uniform_real.hpp>
33 namespace pagmo {
namespace algorithm {
54 pso::pso(
int gen,
double omega,
double eta1,
double eta2,
double vcoeff,
int variant,
int neighb_type,
int neighb_param):
base(),m_gen(gen),m_omega(omega),m_eta1(eta1),m_eta2(eta2),m_vcoeff(vcoeff),m_variant(variant),m_neighb_type(neighb_type),m_neighb_param(neighb_param) {
56 pagmo_throw(value_error,
"number of generations must be nonnegative");
59 if (m_omega < 0 || m_omega > 1) {
62 pagmo_throw(value_error,
"the particles' inertia must be in the [0,1] range");
65 pagmo_throw(value_error,
"the particles' constriction coefficient must be in the [0,1] range");
68 if (eta1 < 0 || eta2 < 0 || eta1 > 4 || eta2 > 4) {
69 pagmo_throw(value_error,
"the eta parameters must be in the [0,4] range");
72 if (vcoeff <= 0 || vcoeff > 1) {
73 pagmo_throw(value_error,
"fraction of variables' range in which velocity may vary should be in ]0,1]");
76 if (variant < 1 || variant > 6) {
77 pagmo_throw(value_error,
"algorithm variant must be one of 1 ... 6");
80 if (neighb_type < 1 || neighb_type > 4) {
81 pagmo_throw(value_error,
"swarm topology variant must be one of 1 ... 4");
112 pagmo_throw(value_error,
"There is no continuous part in the problem decision vector for PSO to optimise");
115 if( prob_c_dimension != 0 ){
116 pagmo_throw(value_error,
"The problem is not box constrained and PSO is not suitable to solve it");
119 if( prob_f_dimension != 1 ){
120 pagmo_throw(value_error,
"The problem is not single objective and PSO is not suitable to solve it");
124 if (swarm_size == 0 || m_gen == 0) {
129 std::vector<double> dummy(Dc,0);
131 std::vector<decision_vector> X(swarm_size,dummy);
132 std::vector<fitness_vector> fit(swarm_size);
134 std::vector<decision_vector > V(swarm_size,dummy);
136 std::vector<decision_vector> lbX(swarm_size,dummy);
137 std::vector<fitness_vector> lbfit(swarm_size);
139 std::vector< std::vector<int> > neighb(swarm_size);
143 bool best_fit_improved;
157 for( d = 0; d < Dc; d++ ){
158 vwidth = ( ub[d] - lb[d] ) * m_vcoeff;
159 minv[d] = -1.0 * vwidth;
164 for( p = 0; p < swarm_size; p++ ){
171 for( p = 0; p < swarm_size; p++ ){
177 switch( m_neighb_type ){
181 best_fit = pop.champion().
f;
189 double acceleration_coefficient = m_eta1 + m_eta2;
198 for(
int g = 0; g < m_gen; ++g ){
200 best_fit_improved =
false;
203 for( p = 0; p < swarm_size; p++ ){
208 if( m_neighb_type != 1 && m_variant != 6)
214 if( m_variant == 1 ){
215 for( d = 0; d < Dc; d++ ){
218 V[p][d] = m_omega * V[p][d] + m_eta1 * r1 * (lbX[p][d] - X[p][d]) + m_eta2 * r2 * (best_neighb[d] - X[p][d]);
225 else if( m_variant == 2 ){
226 for( d = 0; d < Dc; d++ ){
228 V[p][d] = m_omega * V[p][d] + m_eta1 * r1 * (lbX[p][d] - X[p][d]) + m_eta2 * r1 * (best_neighb[d] - X[p][d]);
234 else if( m_variant == 3 ){
237 for( d = 0; d < Dc; d++ ){
238 V[p][d] = m_omega * V[p][d] + m_eta1 * r1 * (lbX[p][d] - X[p][d]) + m_eta2 * r2 * (best_neighb[d] - X[p][d]);
245 else if( m_variant == 4 ){
247 for( d = 0; d < Dc; d++ ){
248 V[p][d] = m_omega * V[p][d] + m_eta1 * r1 * (lbX[p][d] - X[p][d]) + m_eta2 * r1 * (best_neighb[d] - X[p][d]);
265 else if( m_variant == 5 ){
266 for( d = 0; d < Dc; d++ ){
269 V[p][d] = m_omega * ( V[p][d] + m_eta1 * r1 * (lbX[p][d] - X[p][d]) + m_eta2 * r2 * (best_neighb[d] - X[p][d]) );
283 else if( m_variant == 6 ){
284 for( d = 0; d < Dc; d++ ){
286 for( n = 0; n < neighb[p].size(); n++ )
287 sum_forces +=
m_drng() * acceleration_coefficient * ( lbX[ neighb[p][n] ][d] - X[p][d] );
289 V[p][d] = m_omega * ( V[p][d] + sum_forces / neighb[p].size() );
295 for( d = 0; d < Dc; d++ ){
297 if( V[p][d] > maxv[d] )
300 else if( V[p][d] < minv[d] )
304 new_x = X[p][d] + V[p][d];
315 else if( new_x > ub[d] ){
326 prob.
objfun( fit[p], X[p] );
336 if( ( m_neighb_type == 1 || m_neighb_type == 4 ) && prob.
compare_fitness( fit[p], best_fit ) ){
339 best_fit_improved =
true;
346 if( m_neighb_type == 4 && !best_fit_improved )
353 for( p = 0; p < swarm_size; p++ ){
354 pop.set_x( p, lbX[p] );
355 pop.set_x( p, X[p] );
356 pop.set_v( p, V[p] );
375 switch( m_neighb_type ){
378 pagmo_throw(value_error,
"particle__get_best_neighbor() invoked while using a gbest swarm topology");
385 bnidx = neighb[pidx][0];
386 for( nidx = 1; nidx < neighb[pidx].size(); nidx++ )
387 if( prob.
compare_fitness( lbfit[ neighb[pidx][nidx] ], lbfit[ bnidx ] ) )
388 bnidx = neighb[pidx][nidx];
417 gbX = pop.champion().
x;
418 gbfit = pop.champion().
f;
424 if( m_variant == 6 ){
426 for( i = 0; i < neighb.size(); i++ )
427 neighb[0].push_back( i );
428 for( i = 1; i < neighb.size(); i++ )
429 neighb[i] = neighb[0];
448 int swarm_size = neighb.size();
452 int radius = m_neighb_param / 2;
454 for( pidx = 0; pidx < swarm_size; pidx++ ){
455 for( j = -radius; j <= radius; j++ ){
457 nidx = (pidx + j) % swarm_size;
458 if( nidx < 0 ) nidx = swarm_size + nidx;
459 neighb[pidx].push_back( nidx );
495 int swarm_size = neighb.size();
501 rows = std::sqrt( swarm_size );
502 while( swarm_size % rows != 0 )
504 cols = swarm_size / rows;
506 for( pidx = 0; pidx < swarm_size; pidx++ ){
510 for( nidx = 0; nidx < 4; nidx++ ){
511 n_x = ( p_x + vonNeumann_neighb_diff[nidx][0] ) % cols;
if( n_x < 0 ) n_x = cols + n_x;
512 n_y = ( p_y + vonNeumann_neighb_diff[nidx][1] ) % rows;
if( n_y < 0 ) n_y = rows + n_y;
514 neighb[pidx].push_back( n_y * cols + n_x );
544 int swarm_size = neighb.size();
549 for( pidx = 0; pidx < swarm_size; pidx++ )
550 neighb[pidx].clear();
553 for( pidx = 0; pidx < swarm_size; pidx++ ){
556 neighb[pidx].push_back( pidx );
558 for( j = 1; j < m_neighb_param; j++ ){
559 nidx =
m_drng() * swarm_size;
560 neighb[nidx].push_back( pidx );
572 return "Particle Swarm optimization";
582 std::ostringstream s;
583 s <<
"gen:" << m_gen <<
' ';
584 s <<
"omega:" << m_omega <<
' ';
585 s <<
"eta1:" << m_eta1 <<
' ';
586 s <<
"eta2:" << m_eta2 <<
' ';
587 s <<
"variant:" << m_variant <<
' ';
588 s <<
"topology:" << m_neighb_type <<
' ';
589 if( m_neighb_type == 2 || m_neighb_type == 4 )
590 s <<
"topology param.:" << m_neighb_param <<
' ';
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.
Particle Swarm optimization.
void initialize_topology__lbest(std::vector< std::vector< int > > &neighb) const
Defines the Swarm topology as a ring, where particles are influenced by their immediate neighbors to ...
const int vonNeumann_neighb_diff[4][2]
Von Neumann neighborhood (increments on particles' lattice coordinates that produce the coordinates o...
void initialize_topology__von(std::vector< std::vector< int > > &neighb) const
Arranges particles in a lattice, where each interacts with its immediate 4 neighbors to the N...
std::string human_readable_extra() const
Extra human readable algorithm info.
void initialize_topology__gbest(const population &pop, decision_vector &gbX, fitness_vector &gbfit, std::vector< std::vector< int > > &neighb) const
Defines the Swarm topology as a fully connected graph, where particles are influenced by all other pa...
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.
decision_vector particle__get_best_neighbor(population::size_type pidx, std::vector< std::vector< int > > &neighb, const std::vector< decision_vector > &lbX, const std::vector< fitness_vector > &lbfit, const problem::base &prob) const
Get information on the best position already visited by any of a particle's neighbours.
fitness_vector f
Fitness vector.
fitness_vector objfun(const decision_vector &) const
Return fitness of pagmo::decision_vector.
unsigned int m_fevals
A counter for the number of function evaluations.
size_type get_i_dimension() const
Return integer dimension.
base_ptr clone() const
Clone method.
void initialize_topology__adaptive_random(std::vector< std::vector< int > > &neighb) const
Arranges particles in a random graph having a parameterized maximum outdegree; the graph changes adap...
fitness_vector best_f
Best fitness vector so far.
std::vector< double > fitness_vector
Fitness vector type.
std::string get_name() const
Algorithm name.
c_size_type get_c_dimension() const
Return global constraints dimension.
decision_vector cur_v
Current velocity vector.
const decision_vector & get_ub() const
Upper bounds getter.
pso(int gen=1, double omega=0.7298, double eta1=2.05, double eta2=2.05, double vcoeff=0.5, int variant=5, int neighb_type=2, int neighb_param=4)
Constructor.
container_type::size_type size_type
Population size type.
decision_vector cur_x
Current decision vector.
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.
void evolve(population &) const
Evolve implementation.
decision_vector best_x
Best decision vector so far.
decision_vector::size_type size_type
Problem's size type: the same as pagmo::decision_vector's size type.