PaGMO  1.1.5
nspso.cpp
1 /*****************************************************************************
2  * Copyright (C) 2004-2015 The PaGMO development team, *
3  * Advanced Concepts Team (ACT), European Space Agency (ESA) *
4  * *
5  * https://github.com/esa/pagmo *
6  * *
7  * act@esa.int *
8  * *
9  * This program is free software; you can redistribute it and/or modify *
10  * it under the terms of the GNU General Public License as published by *
11  * the Free Software Foundation; either version 2 of the License, or *
12  * (at your option) any later version. *
13  * *
14  * This program is distributed in the hope that it will be useful, *
15  * but WITHOUT ANY WARRANTY; without even the implied warranty of *
16  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
17  * GNU General Public License for more details. *
18  * *
19  * You should have received a copy of the GNU General Public License *
20  * along with this program; if not, write to the *
21  * Free Software Foundation, Inc., *
22  * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *
23  *****************************************************************************/
24 
25 
26 #include <string>
27 #include <vector>
28 #include <algorithm>
29 #include <fstream>
30 
31 #include <boost/math/special_functions/binomial.hpp>
32 #include <boost/random/uniform_real.hpp>
33 #include <boost/random/uniform_int.hpp>
34 #include <boost/random/variate_generator.hpp>
35 
36 #include "../exceptions.h"
37 #include "../population.h"
38 #include "../problem/base.h"
39 #include "../population.h"
40 #include "../util/neighbourhood.h"
41 #include "base.h"
42 #include "nspso.h"
43 
44 
45 namespace pagmo { namespace algorithm {
47 
62 nspso::nspso(int gen, double minW, double maxW, double C1, double C2,
63  double CHI, double v_coeff, int leader_selection_range,
64  diversity_mechanism_type diversity_mechanism):base(),
65  m_gen(gen),
66  m_minW(minW),
67  m_maxW(maxW),
68  m_C1(C1),
69  m_C2(C2),
70  m_CHI(CHI),
71  m_v_coeff(v_coeff),
72  m_leader_selection_range(leader_selection_range),
73  m_diversity_mechanism(diversity_mechanism)
74 {
75  if (gen < 0) {
76  pagmo_throw(value_error,"number of generations must be nonnegative");
77  }
78 
79  if (minW <= 0 || maxW <= 0 || C1 <=0 || C2 <= 0 || CHI <=0) {
80  pagmo_throw(value_error,"minW, maxW, C1, C2 and CHI should be greater than 0");
81  }
82 
83  if (minW > maxW) {
84  pagmo_throw(value_error,"minW should be lower than maxW");
85  }
86 
87  if (v_coeff <= 0 || v_coeff > 1) {
88  pagmo_throw(value_error,"v_coeff should be in the ]0,1] range");
89  }
90 
91  if (leader_selection_range <=0 || leader_selection_range > 100) {
92  pagmo_throw(value_error,"leader_selection_range should be in the ]0,100] range");
93  }
94 }
95 
96 
99 {
100  return base_ptr(new nspso(*this));
101 }
102 
104 
109 void nspso::evolve(population &pop) const
110 {
111  // Let's store some useful variables.
112  const problem::base &prob = pop.problem();
113  const problem::base::size_type D = prob.get_dimension(), prob_i_dimension = prob.get_i_dimension(), prob_c_dimension = prob.get_c_dimension(), prob_f_dimension = prob.get_f_dimension();
114  const problem::base::size_type Dc = D - prob_i_dimension;
115  const decision_vector &lb = prob.get_lb(), &ub = prob.get_ub();
116  const population::size_type NP = pop.size();
117 
118  //We perform some checks to determine wether the problem/population are suitable for PSO
119  if( Dc == 0 ){
120  pagmo_throw(value_error,"There is no continuous part in the problem decision vector for NSPSO to optimise");
121  }
122 
123  if( prob_c_dimension != 0 ){
124  pagmo_throw(value_error,"The problem is not box constrained and NSPSO is not suitable to solve it");
125  }
126 
127  if( prob_f_dimension < 2 ){
128  pagmo_throw(value_error,"The problem is not multi-objective. Use a single-objectie optimization algorithm instead");
129  }
130 
131  if(m_diversity_mechanism != CROWDING_DISTANCE && m_diversity_mechanism != NICHE_COUNT && m_diversity_mechanism != MAXMIN) {
132  pagmo_throw(value_error,"non existing diversity mechanism method");
133  }
134 
135  // Get out if there is nothing to do.
136  if (NP == 0 || m_gen == 0) {
137  return;
138  }
139 
140  decision_vector minV(Dc), maxV(Dc); // Maximum and minimum velocity allowed
141 
142  // Initialise the minimum and maximum velocity
143  for(problem::base::size_type d = 0; d < Dc; d++ ){
144  double v_width = (ub[d] - lb[d]) * m_v_coeff;
145  minV[d] = -1.0 * v_width;
146  maxV[d] = v_width;
147  }
148 
149  // 0 - Copy the population into nextPopList
150  std::vector<nspso_individual> nextPopList;
151  for(unsigned int i=0; i < NP; ++i) {
152  nextPopList.push_back(nspso_individual());
153  nextPopList[i].cur_x = pop.get_individual(i).cur_x;
154  nextPopList[i].best_x = pop.get_individual(i).best_x;
155  nextPopList[i].cur_v = pop.get_individual(i).cur_v;
156  nextPopList[i].cur_f = pop.get_individual(i).cur_f;
157  nextPopList[i].best_f = pop.get_individual(i).best_f;
158  nextPopList[i].cur_c = pop.get_individual(i).cur_c;
159  nextPopList[i].best_c = pop.get_individual(i).best_c;
160  }
161 
162  for(int g = 0; g < m_gen; ++g) {
163 
164  std::vector<population::size_type> bestNonDomIndices;
165  std::vector<fitness_vector> fit(NP);// particles' current fitness values
166  std::vector<constraint_vector> cons(NP);
167  for ( population::size_type i = 0; i<NP; i++ ) {
168  fit[i] = nextPopList[i].best_f;
169  cons[i] = nextPopList[i].best_c;
170  }
171 
172  // 1 - Calculate non-dominated population
173  if(m_diversity_mechanism == CROWDING_DISTANCE) {
174  std::vector<std::vector<population::size_type> > dom_list = compute_domination_list(prob,fit,cons);
175  std::vector<population::size_type> pareto_rank = compute_pareto_rank(dom_list);
176  std::vector<std::vector<population::size_type> > pareto_fronts = compute_pareto_fronts(pareto_rank);
177  std::vector<double> crowding_d = compute_crowding_d(fit, pareto_fronts);
178 
179  crowding_pareto_comp comp(pareto_rank, crowding_d);
180  std::vector<population::size_type> dummy(NP);
181  for(unsigned int i=0; i<NP; ++i) dummy[i] = i;
182  std::sort(dummy.begin(), dummy.end(),comp);
183  if(pareto_fronts[0].size() > 1) {
184  bestNonDomIndices = std::vector<population::size_type>(dummy.begin(), dummy.begin() + pareto_fronts[0].size());
185  } else { //ensure the non-dom population has at least 2 individuals (to avoid convergence to a point)
186  bestNonDomIndices = std::vector<population::size_type>(dummy.begin(), dummy.begin() + 2);
187  }
188 
189  } else if(m_diversity_mechanism == NICHE_COUNT) {
190  std::vector<decision_vector> nonDomChromosomes;
191 
192  std::vector<std::vector<population::size_type> > dom_list = compute_domination_list(prob,fit,cons);
193  std::vector<population::size_type> pareto_rank = compute_pareto_rank(dom_list);
194  std::vector<std::vector<population::size_type> > pareto_fronts = compute_pareto_fronts(pareto_rank);
195 
196  for(unsigned int i = 0; i < pareto_fronts[0].size(); ++i) {
197  nonDomChromosomes.push_back(nextPopList[pareto_fronts[0][i]].best_x);
198  }
199 
200  std::vector<double> nadir = compute_nadir(fit, pareto_rank);
201  std::vector<double> ideal = compute_ideal(fit, pareto_rank);
202 
203  //Fonseca-Fleming setting for delta
204  double delta = 1.0;
205  if (prob_f_dimension == 2) {
206  delta = ( (nadir[0] - ideal[0]) + (nadir[1] - ideal[1]) ) / (nonDomChromosomes.size()-1);
207  } else if (prob_f_dimension == 3) {
208  const double d1 = nadir[0] - ideal[0];
209  const double d2 = nadir[1] - ideal[1];
210  const double d3 = nadir[2] - ideal[2];
211  const double N = nonDomChromosomes.size();
212  delta = sqrt(4*d2*d1*N + 4*d3*d1*N + 4*d2*d3*N + pow(d1,2) + pow(d2,2) + pow(d3,2)
213  - 2*d2*d1 - 2*d3*d1 - 2*d2*d3 + d1 + d2 + d3) / (2*(N-1));
214  } else { //for higher dimension we just divide equally the entire volume containing the pareto front
215  for(unsigned int i=0; i<nadir.size(); ++i) {
216  delta *= nadir[i] - ideal[i];
217  }
218  delta = pow(delta, 1.0/nadir.size())/nonDomChromosomes.size();
219  }
220 
221  std::vector<int> count(nonDomChromosomes.size(),0);
222  compute_niche_count(count, nonDomChromosomes, delta);
223  std::vector<population::size_type> tmp = pagmo::util::neighbourhood::order(count);
224 
225  if(pareto_fronts[0].size() > 1) {
226  for(unsigned int i=0; i < tmp.size(); ++i) {
227  bestNonDomIndices.push_back(pareto_fronts[0][tmp[i]]);
228  }
229  } else { //ensure the non-dom population has at least 2 individuals (to avoid convergence to a point)
230  unsigned int minPopSize = 2;
231  for(unsigned f = 0; minPopSize > 0 && f < pareto_fronts.size(); ++f) {
232  for(unsigned int i=0; minPopSize > 0 && i < pareto_fronts[f].size(); ++i) {
233  bestNonDomIndices.push_back(pareto_fronts[f][i]);
234  minPopSize--;
235  }
236  }
237  }
238  } else { // m_diversity_method == MAXMIN
239  std::vector<double> maxmin(NP,0);
240  compute_maxmin(maxmin, fit);
241  bestNonDomIndices = pagmo::util::neighbourhood::order(maxmin);
242  unsigned int i = 1;
243  for(;i < bestNonDomIndices.size() && maxmin[bestNonDomIndices[i]] < 0; ++i);
244  if(i<2) i=2; //ensure the non-dom population has at least 2 individuals (to avoid convergence to a point)
245  bestNonDomIndices = std::vector<population::size_type>(bestNonDomIndices.begin(), bestNonDomIndices.begin() + i); //keep just the non dominated
246  }
247 
248  //decrease W from maxW to minW troughout the run
249  const double W = m_maxW - (m_maxW-m_minW)/m_gen * g;
250 
251  //2 - Move the points
252  for(population::size_type idx = 0; idx < NP; ++idx) {
253  const decision_vector &best_X = nextPopList[idx].best_x;
254  const decision_vector &cur_X = nextPopList[idx].cur_x;
255  const decision_vector &cur_V = nextPopList[idx].cur_v;
256 
257  // 2.1 - Calculate the leader
258  int ext = ceil(bestNonDomIndices.size()*m_leader_selection_range/100.0)-1;
259  if (ext < 1) ext = 1;
260  unsigned int leaderIdx;
261  do {
262  leaderIdx = boost::uniform_int<int>(0,ext)(m_drng);
263  } while (bestNonDomIndices[leaderIdx] == idx); //never pick yourself as a leader
264  decision_vector leader = nextPopList[bestNonDomIndices[leaderIdx]].best_x;
265 
266  //Calculate some random factors
267  const double r1 = boost::uniform_real<double>(0,1)(m_drng);
268  const double r2 = boost::uniform_real<double>(0,1)(m_drng);
269 
270  //Calculate new velocity and new position for each particle
271  decision_vector newX(Dc);
272  decision_vector newV(Dc);
273  for(decision_vector::size_type i = 0; i < cur_X.size(); ++i) {
274  double v = W*cur_V[i] +
275  m_C1*r1*(best_X[i] - cur_X[i]) +
276  m_C2*r2*(leader[i] - cur_X[i]);
277 
278  if(v > maxV[i]){
279  v = maxV[i];
280  }
281  else if(v < minV[i]) {
282  v = minV[i];
283  }
284 
285  double x = cur_X[i] + m_CHI*v;
286  if(x > ub[i]) {
287  x = ub[i];
288  v = 0;
289  } else if (x < lb[i]) {
290  x = lb[i];
291  v = 0;
292  }
293 
294  newV[i] = v;
295  newX[i] = x;
296  }
297 
298  //Add the moved particle to the population
299  nextPopList.push_back(nspso_individual());
300  nextPopList[idx+NP].cur_x = newX;
301  nextPopList[idx+NP].best_x = newX;
302  nextPopList[idx+NP].cur_v = newV;
303  nextPopList[idx+NP].cur_f = prob.objfun(newX);
304  nextPopList[idx+NP].best_f = nextPopList[idx+NP].cur_f;
305  nextPopList[idx+NP].cur_c = prob.compute_constraints(newX);
306  nextPopList[idx+NP].best_c = nextPopList[idx+NP].cur_c;
307  }
308 
309  //3 - Select the best NP individuals in the new population (of size 2*NP) according to pareto dominance
310  std::vector<fitness_vector> nextPop_fit(nextPopList.size());
311  std::vector<constraint_vector> nextPop_cons(nextPopList.size());
312  for(unsigned int i=0; i<nextPopList.size(); ++i) {
313  nextPop_fit[i] = nextPopList[i].best_f;
314  nextPop_cons[i] = nextPopList[i].best_c;
315  }
316 
317  std::vector<population::size_type> bestNextPopIndices(NP,0);
318 
319  if(m_diversity_mechanism != MAXMIN) {
320  std::vector<std::vector<population::size_type> > nextPop_pareto_fronts = compute_pareto_fronts(prob, nextPop_fit, nextPop_cons);
321  for(unsigned int f = 0, i=0; i<NP && f < nextPop_pareto_fronts.size(); ++f) {
322  if(nextPop_pareto_fronts[f].size() < NP-i) { //then push the whole front in the population
323  for(unsigned int j = 0; j < nextPop_pareto_fronts[f].size(); ++j) {
324  bestNextPopIndices[i] = nextPop_pareto_fronts[f][j];
325  ++i;
326  }
327  } else {
328  boost::uniform_int<int> pop_idx(0,nextPop_pareto_fronts[f].size());
329  boost::variate_generator<boost::mt19937 &, boost::uniform_int<int> > p_idx(m_urng,pop_idx);
330  std::random_shuffle(nextPop_pareto_fronts[f].begin(), nextPop_pareto_fronts[f].end(), p_idx);
331  for(unsigned int j = 0; i<NP; ++j) {
332  bestNextPopIndices[i] = nextPop_pareto_fronts[f][j];
333  ++i;
334  }
335  }
336  }
337  } else {
338  std::vector<double> maxmin(2*NP,0);
339  compute_maxmin(maxmin, nextPop_fit);
340  std::vector<population::size_type> tmp = pagmo::util::neighbourhood::order(maxmin);
341  bestNextPopIndices = std::vector<population::size_type>(tmp.begin(), tmp.begin() + NP);
342  }
343 
344  // The nextPopList for the next generation will contain the best NP individuals out of 2NP according to pareto dominance
345  std::vector<nspso_individual> tmpPop(NP);
346  for(unsigned int i=0; i < NP; ++i) {
347  tmpPop[i] = nextPopList[bestNextPopIndices[i]];
348  }
349 
350  nextPopList = tmpPop;
351  }
352 
353  //4 - Evolution is over, copy the last population back to the orginal population
354  pop.clear();
355  for(population::size_type i = 0; i < NP; ++i){
356  pop.push_back(nextPopList[i].best_x);
357  pop.set_x(i, nextPopList[i].cur_x);
358  pop.set_v(i, nextPopList[i].cur_v);
359  }
360 
361 }
362 
363 double nspso::minfit(unsigned int i, unsigned int j, const std::vector<fitness_vector> &fit) const
364 {
365  double min = fit[i][0] - fit[j][0];
366  for(unsigned int f=0; f<fit[i].size(); ++f) {
367  double tmp = fit[i][f] - fit[j][f];
368  if(tmp < min) {
369  min = tmp;
370  }
371  }
372  return min;
373 }
374 
375 void nspso::compute_maxmin(std::vector<double> &maxmin, const std::vector<fitness_vector> &fit) const
376 {
377  const unsigned int NP = fit.size();
378  for(unsigned int i=0; i<NP; ++i) {
379  maxmin[i] = minfit(i, (i+1)%NP, fit);
380  for(unsigned j=0; j<NP; ++j) {
381  if(i != j) {
382  double tmp = minfit(i, j, fit);
383  if(tmp > maxmin[i]) {
384  maxmin[i] = tmp;
385  }
386  }
387  }
388  }
389 }
390 
391 
392 
393 double nspso::euclidian_distance(const std::vector<double> &x, const std::vector<double> &y) const
394 {
395  pagmo_assert(x.size() == y.size());
396  double sum = 0;
397  for(unsigned int i = 0; i < x.size(); ++i) {
398  sum+= pow(x[i]-y[i],2);
399  }
400  return sqrt(sum);
401 }
402 
403 void nspso::compute_niche_count(std::vector<int> &count, const std::vector<std::vector<double> > &chromosomes, double delta) const
404 {
405  std::fill(count.begin(), count.end(),0);
406  for(unsigned int i=0; i<chromosomes.size(); ++i) {
407  for(unsigned int j=0; j<chromosomes.size(); ++j) {
408  if(euclidian_distance(chromosomes[i], chromosomes[j]) < delta) {
409  count[i]++;
410  }
411  }
412  }
413 
414 }
415 
416 std::vector<std::vector<population::size_type> > nspso::compute_domination_list(const pagmo::problem::base &prob,
417  const std::vector<fitness_vector> &fit,
418  const std::vector<constraint_vector> &cons) const
419 {
420  std::vector<population::size_type> dummy;
421  std::vector<std::vector<population::size_type> > domination_list(fit.size(), dummy);
422 
423  for(unsigned int i=0; i<fit.size();++i) {
424  for(unsigned int j=0; j<fit.size(); ++j) {
425  // Check if individual in position i dominates individual in position n.
426  if(prob.compare_fc(fit[i],cons[i],fit[j],cons[j])) {
427  domination_list[i].push_back(j);
428  }
429  }
430  }
431 
432  return domination_list;
433 }
434 
435 std::vector<population::size_type> nspso::compute_domination_count(const std::vector<std::vector<population::size_type> > &dom_list) const
436 {
437  std::vector<population::size_type> domination_count(dom_list.size(),0);
438  for(unsigned int i=0; i<dom_list.size(); ++i) {
439  for(unsigned int j = 0; j < dom_list[i].size(); ++j) {
440  domination_count[dom_list[i][j]]++;
441  }
442  }
443 
444  return domination_count;
445 }
446 
447 std::vector<population::size_type> nspso::compute_pareto_rank(const std::vector<std::vector<population::size_type> > &dom_list) const
448 {
449  std::vector<population::size_type> pareto_rank(dom_list.size(),0);
450 
451  // We define some utility vectors .....
452  std::vector<population::size_type> F,S;
453 
454  // And make a copy of the domination count (number of individuals that dominating one individual)
455  std::vector<population::size_type> dom_count = compute_domination_count(dom_list);
456 
457  // 1 - Find the first Pareto Front
458  for (population::size_type idx = 0; idx < dom_count.size(); ++idx){
459  if (dom_count[idx] == 0) {
460  F.push_back(idx);
461  }
462  }
463 
464  unsigned int irank = 1;
465 
466  // We loop to find subsequent fronts
467  while (F.size()!=0) {
468  //For each individual F in the current front
469  for (population::size_type i=0; i < F.size(); ++i) {
470  //For each individual dominated by F
471  for (population::size_type j=0; j<dom_list[F[i]].size(); ++j) {
472  dom_count[dom_list[F[i]][j]]--;
473  if (dom_count[dom_list[F[i]][j]] == 0){
474  S.push_back(dom_list[F[i]][j]);
475  pareto_rank[dom_list[F[i]][j]] = irank;
476  }
477  }
478  }
479  F = S;
480  S.clear();
481  irank++;
482  }
483 
484  //std::cout << "pareto rank before return " << pareto_rank << std::endl;
485  return pareto_rank;
486 }
487 
488 std::vector<double> nspso::compute_crowding_d(const std::vector<fitness_vector> &fit, const std::vector<std::vector<population::size_type> > &pareto_fronts) const {
489 
490  std::vector<double> crowding_d(fit.size(),0);
491 
492  for(unsigned f=0; f < pareto_fronts.size(); ++f) {
493  std::vector<fitness_vector::size_type> I(pareto_fronts[f]);
494 
495  fitness_vector::size_type lastidx = I.size() - 1;
496 
497  // we construct the comparison functor along the first fitness component
498  one_dim_fit_comp funct(fit,0);
499 
500  // we loop along fitness components
501  for (fitness_vector::size_type i = 0; i < fit[0].size(); ++i) {
502  funct.m_dim = i;
503  // we sort I along the fitness_dimension i
504  std::sort(I.begin(),I.end(), funct);
505  // assign Inf to the boundaries
506  crowding_d[I[0]] = std::numeric_limits<double>::max();
507  crowding_d[I[lastidx]] = std::numeric_limits<double>::max();
508  //and compute the crowding distance
509  double df = fit[I[lastidx]][i] - fit[I[0]][i];
510  for (population::size_type j = 1; j < lastidx; ++j) {
511  if (df == 0.0) { // handles the case in which the pareto front collapses to one single point
512  crowding_d[I[j]] += 0.0; // avoiding creation of nans that can't be serialized
513  } else {
514  crowding_d[I[j]] += (fit[I[j+1]][i] -fit[I[j-1]][i])/df;
515  }
516  }
517  }
518  }
519 
520  return crowding_d;
521 }
522 
523 std::vector<std::vector<population::size_type> > nspso::compute_pareto_fronts(const pagmo::problem::base &prob,
524  const std::vector<fitness_vector> &fit,
525  const std::vector<constraint_vector> &cons) const
526 {
527  std::vector<std::vector<population::size_type> > dom_list = compute_domination_list(prob,fit,cons);
528  std::vector<population::size_type> pareto_rank = compute_pareto_rank(dom_list);
529 
530  return compute_pareto_fronts(pareto_rank);
531 }
532 
533 std::vector<std::vector<population::size_type> > nspso::compute_pareto_fronts(const std::vector<population::size_type> &pareto_rank) const
534 {
535  std::vector<std::vector<population::size_type> > retval;
536 
537  for (population::size_type idx = 0; idx < pareto_rank.size(); ++idx) {
538  if (pareto_rank[idx] >= retval.size()) {
539  retval.resize(pareto_rank[idx] + 1);
540  }
541  retval[pareto_rank[idx]].push_back(idx);
542  }
543 
544  return retval;
545 }
546 
547 fitness_vector nspso::compute_ideal(const std::vector<fitness_vector> &fit, const std::vector<population::size_type> &pareto_rank) const {
548 
549  unsigned int firstFrontIdx = 0;
550  for(;pareto_rank[firstFrontIdx] > 0; ++firstFrontIdx);
551 
552  fitness_vector ideal(fit[firstFrontIdx]);
553  for (population::size_type idx = 0; idx < fit.size(); ++idx) {
554  if (pareto_rank[idx] == 0) { //it is in the first pareto front
555  for(fitness_vector::size_type i = 0; i < ideal.size(); ++i) {
556  if (fit[idx][i] < ideal[i]) {
557  ideal[i] = fit[idx][i];
558  }
559  }
560  }
561  }
562  return ideal;
563 }
564 
565 fitness_vector nspso::compute_nadir(const std::vector<fitness_vector> &fit, const std::vector<population::size_type> &pareto_rank) const {
566  unsigned int firstFrontIdx = 0;
567  for(;pareto_rank[firstFrontIdx] > 0; ++firstFrontIdx);
568 
569  fitness_vector nadir(fit[firstFrontIdx]);
570  for (population::size_type idx = 0; idx < fit.size(); ++idx) {
571  if (pareto_rank[idx] == 0) { //it is in the first pareto front
572  for(fitness_vector::size_type i = 0; i < nadir.size(); ++i) {
573  if (fit[idx][i] > nadir[i]) {
574  nadir[i] = fit[idx][i];
575  }
576  }
577  }
578  }
579  return nadir;
580 }
581 
582 
584 std::string nspso::get_name() const
585 {
586  return "Non-dominated Sorting Particle Swarm Optimizer (NSPSO)";
587 }
588 
590 
593 std::string nspso::human_readable_extra() const
594 {
595  std::ostringstream s;
596  s << "gen:" << m_gen << ' ';
597  s << "minW:" << m_minW << ' ';
598  s << "maxW:" << m_maxW << ' ';
599  s << "C1:" << m_C1 << ' ';
600  s << "C2:" << m_C2 << ' ';
601  s << "CHI:" << m_CHI << ' ';
602  s << "v_coeff:" << m_v_coeff << ' ';
603  s << "leader_selection_range:" << m_leader_selection_range << ' ';
604  s << "diversity_mechanism: ";
605  switch (m_diversity_mechanism)
606  {
607  case CROWDING_DISTANCE : s << "CROWDING_DISTANCE" << ' ';
608  break;
609  case NICHE_COUNT : s << "NICHE_COUNT" << ' ';
610  break;
611  case MAXMIN : s << "MAXMIN" << ' ';
612  break;
613  }
614  return s.str();
615 }
616 
617 
618 }} //namespaces
619 
620 BOOST_CLASS_EXPORT_IMPLEMENT(pagmo::algorithm::nspso)
boost::shared_ptr< base > base_ptr
Alias for shared pointer to base algorithm.
Root PaGMO namespace.
std::vector< double > decision_vector
Decision vector type.
Definition: types.h:40
fitness_vector cur_f
Current fitness vector.
Definition: population.h:89
const individual_type & get_individual(const size_type &) const
Get constant reference to individual at position n.
Definition: population.cpp:277
Base algorithm class.
constraint_vector cur_c
Current constraint vector.
Definition: population.h:87
base_ptr clone() const
Clone method.
Definition: nspso.cpp:98
Base problem class.
Definition: problem/base.h:148
Population class.
Definition: population.h:70
std::vector< population::size_type > order(const std::vector< T > &values)
Sort according the the values in the values vector but return the permutation.
Definition: neighbourhood.h:55
size_type get_dimension() const
Return global dimension.
fitness_vector objfun(const decision_vector &) const
Return fitness of pagmo::decision_vector.
std::string human_readable_extra() const
Extra human readable algorithm info.
Definition: nspso.cpp:593
size_type get_i_dimension() const
Return integer dimension.
void evolve(population &) const
Evolve implementation.
Definition: nspso.cpp:109
nspso(int gen=100, double minW=0.4, double maxW=1.0, double C1=2.0, double C2=2.0, double CHI=1.0, double v_coeff=0.5, int leader_selection_range=10, diversity_mechanism_type=CROWDING_DISTANCE)
Constructor.
Definition: nspso.cpp:62
fitness_vector best_f
Best fitness vector so far.
Definition: population.h:95
std::vector< double > fitness_vector
Fitness vector type.
Definition: types.h:42
constraint_vector compute_constraints(const decision_vector &) const
Compute constraints and return constraint vector.
diversity_mechanism_type
Mechanism used to asses diversity.
Definition: nspso.h:55
c_size_type get_c_dimension() const
Return global constraints dimension.
decision_vector cur_v
Current velocity vector.
Definition: population.h:85
const decision_vector & get_ub() const
Upper bounds getter.
container_type::size_type size_type
Population size type.
Definition: population.h:192
decision_vector cur_x
Current decision vector.
Definition: population.h:83
rng_uint32 m_urng
Random number generator for unsigned integer values.
f_size_type get_f_dimension() const
Return fitness dimension.
constraint_vector best_c
Best constraint vector so far.
Definition: population.h:93
bool compare_fc(const fitness_vector &, const constraint_vector &, const fitness_vector &, const constraint_vector &) const
Simultaneous fitness-constraint comparison.
const decision_vector & get_lb() const
Lower bounds getter.
rng_double m_drng
Random number generator for double-precision floating point values.
decision_vector best_x
Best decision vector so far.
Definition: population.h:91
decision_vector::size_type size_type
Problem's size type: the same as pagmo::decision_vector's size type.
Definition: problem/base.h:160
std::string get_name() const
Algorithm name.
Definition: nspso.cpp:584
Non-dominated Sorting Particle Swarm Optimizer (NSPSO)
Definition: nspso.h:51
The crowding distance is used.
Definition: nspso.h:56