PaGMO  1.1.5
archipelago.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 #include <boost/numeric/conversion/cast.hpp>
26 #include <boost/random/uniform_int.hpp>
27 #include <boost/thread/barrier.hpp>
28 #include <boost/tuple/tuple.hpp>
29 #include <boost/tuple/tuple_io.hpp>
30 #include <boost/random/uniform_int.hpp>
31 #include <boost/random/variate_generator.hpp>
32 #include <cstddef>
33 #include <iostream>
34 #include <iterator>
35 #include <sstream>
36 #include <stdexcept>
37 #include <string>
38 #include <vector>
39 
40 #include "archipelago.h"
41 #include "algorithm/base.h"
42 #include "base_island.h"
43 #include "exceptions.h"
44 #include "island.h"
45 #include "population.h"
46 #include "problem/base.h"
47 #include "rng.h"
48 #include "topology/base.h"
49 #include "topology/unconnected.h"
50 
51 namespace pagmo {
52 
53 // Check we are not using bogus values for the enums.
54 void archipelago::check_migr_attributes() const
55 {
56  if (m_dist_type < 0 || m_dist_type > 1 ||m_migr_dir < 0 || m_migr_dir > 1) {
57  pagmo_throw(value_error,"invalid value for migration attribute (destination and/or direction)");
58  }
59 }
60 
62 
68 archipelago::archipelago(distribution_type dt, migration_direction md):m_islands_sync_point(),m_topology(new topology::unconnected()),
69  m_dist_type(dt),m_migr_dir(md),
70  m_migr_map(),m_drng(rng_generator::get<rng_double>()),m_urng(rng_generator::get<rng_uint32>()),m_migr_mutex()
71 {
72  check_migr_attributes();
73 }
74 
76 
85  m_islands_sync_point(),m_topology(),m_dist_type(dt),m_migr_dir(md),
86  m_migr_map(),m_drng(rng_generator::get<rng_double>()),m_urng(rng_generator::get<rng_uint32>()),m_migr_mutex()
87 {
88  // NOTE: we cannot set the topology in the initialiser list directly,
89  // since we do not know if the topology is suitable. Set it here.
90  check_migr_attributes();
91  set_topology(t);
92 }
93 
95 
108  m_islands_sync_point(),m_topology(new topology::unconnected()),m_dist_type(dt),m_migr_dir(md),
109  m_migr_map(),m_drng(rng_generator::get<rng_double>()),m_urng(rng_generator::get<rng_uint32>()),m_migr_mutex()
110 {
111  check_migr_attributes();
112  for (size_type i = 0; i < boost::numeric_cast<size_type>(n); ++i) {
113  push_back(island(a,p,m));
114  }
115  // Set topology after pushing back, so that it is possible to give an already-built topology to the constructor
116  // without everything blowing up.
117  set_topology(t);
118 }
119 
121 
127 {
128  a.join();
129  // Deep copy from islands pointers.
130  for (size_type i = 0; i < a.m_container.size(); ++i) {
131  m_container.push_back(a.m_container[i]->clone());
132  m_container.back()->m_archi = this;
133  }
134  m_topology = a.m_topology->clone();
135  m_dist_type = a.m_dist_type;
136  m_migr_dir = a.m_migr_dir;
137  m_migr_map = a.m_migr_map;
138  m_drng = a.m_drng;
139  m_urng = a.m_urng;
140  m_migr_hist = a.m_migr_hist;
141 }
142 
144 
152 {
153  if (this != &a) {
154  join();
155  a.join();
156  m_container.clear();
157  // Deep copy from islands pointers.
158  for (size_type i = 0; i < a.m_container.size(); ++i) {
159  m_container.push_back(a.m_container[i]->clone());
160  m_container.back()->m_archi = this;
161  }
162  m_topology = a.m_topology->clone();
163  m_dist_type = a.m_dist_type;
164  m_migr_dir = a.m_migr_dir;
165  m_migr_map = a.m_migr_map;
166  m_drng = a.m_drng;
167  m_urng = a.m_urng;
168  m_migr_hist = a.m_migr_hist;
169  }
170  return *this;
171 }
172 
174 
178 {
179  join();
180  pagmo_assert(destruction_checks());
181 }
182 
184 
187 void archipelago::join() const
188 {
189  const const_iterator it_f = m_container.end();
190  for (const_iterator it = m_container.begin(); it != it_f; ++it) {
191  (*it)->join();
192  }
193 }
194 
195 archipelago::size_type archipelago::locate_island(const base_island &isl) const
196 {
197  // TODO: iterate and increase a size type instead of using distance(), which returns a signed int.
198  // Also, assert the island is actually found here?
199  // TODO: also, this can be optimized with a hash table, if needed: build it at the beginning
200  // of the evolution, and destroy it at the end.
201  const_iterator it = m_container.begin();
202  for (; it != m_container.end(); ++it) {
203  if (&(*(*it)) == &isl) {
204  break;
205  }
206  }
207  return std::distance(m_container.begin(),it);
208 }
209 
211 
220 {
221  // NOTE: the joins are already done in check_island().
222  if (!check_island(isl)) {
223  pagmo_throw(value_error,"cannot push_back() incompatible island");
224  }
225  m_container.push_back(isl.clone());
226  // Tell the island that it is living in an archipelago now.
227  m_container.back()->m_archi = this;
228  // Insert the island in the topology.
229  m_topology->push_back();
230 }
231 
233 
242 {
243  join();
244  if (idx >= m_container.size()) {
245  pagmo_throw(index_error,"invalid island index");
246  }
247  m_container[idx]->set_algorithm(a);
248 }
249 
251 
255 {
256  join();
257  return m_container.size();
258 }
259 
261 
269 std::string archipelago::human_readable() const
270 {
271  join();
272  std::ostringstream oss;
273  oss << "-= Archipelago =-\n\n";
274  oss << "Number of islands:\t" << m_container.size() << "\n\n";
275  oss << m_topology->human_readable_terse() << '\n';
276  for (size_type i = 0; i < m_container.size(); ++i) {
277  oss << "Island index: #" << i << "\n\n";
278  oss << m_container[i]->human_readable_terse() << '\n';
279  }
280  return oss.str();
281 }
282 
284 
288 {
289  join();
290  return m_topology->clone();
291 }
292 
294 
302 {
303  join();
304  topology::base_ptr t = tp.clone();
305  if (m_container.size() < boost::numeric_cast<size_type>(t->get_number_of_vertices())) {
306  pagmo_throw(value_error,"invalid topology, too many vertices");
307  }
308  // Push back the missing vertices, if any.
309  for (size_type i = boost::numeric_cast<size_type>(t->get_number_of_vertices());
310  i < m_container.size(); ++i)
311  {
312  t->push_back();
313  }
314  // The topology is ok, assign it.
315  m_topology = t;
316 }
317 
319 
324  return m_dist_type;
325 }
326 
328 
335  m_dist_type = dt;
336 }
337 
339 
352 {
353  join();
354  isl.join();
355  // We need to perform checks only if there are other islands in the archipelago.
356  // Otherwise, any island will be allowed in.
357  if (m_container.size() && (!isl.m_pop.problem().is_compatible(m_container[0]->m_pop.problem()))) {
358  return false;
359  }
360  return true;
361 }
362 
363 // Reset island synchronisation barrier. This method is intended as a shortcut,
364 // do NOT use it if the archipelago has not been joined!
365 void archipelago::reset_barrier(const size_type &size)
366 {
367  if (size) {
368  m_islands_sync_point.reset(new boost::barrier(boost::numeric_cast<unsigned int>(size)));
369  }
370 }
371 
372 // Return true if all islands in the archipelago have a m_archi pointer to this and the shared pointer count is 1, false otherwise. Used for debugging.
373 bool archipelago::destruction_checks() const
374 {
375  for (size_type i = 0; i < get_size(); ++i) {
376  if (m_container[i].use_count() != 1 || m_container[i]->m_archi != this) {
377  return false;
378  }
379  }
380  return true;
381 }
382 
383 // Helper function to insert a list of candidates immigrants into an immigrants vector, given the source and destination island.
384 void archipelago::build_immigrants_vector(std::vector<std::pair<population::size_type, individual_type > > &immigrants, const base_island &src_isl,
385  base_island &dest_isl, const std::vector<individual_type> &candidates) const
386 {
387  for (std::vector<individual_type>::const_iterator ind_it = candidates.begin();
388  ind_it != candidates.end(); ++ind_it)
389  {
390  // Skip individual if it is not within the bounds of the problem
391  // in the destination island.
392  if (!dest_isl.m_pop.problem().verify_x(ind_it->cur_x)) {
393  continue;
394  }
395  immigrants.push_back(std::make_pair(locate_island(src_isl),*ind_it));
396  }
397 }
398 
399 // Re-evaluate vector of immigrants before insertion into destination island.
400 void archipelago::reevaluate_immigrants(std::vector<std::pair<population::size_type, individual_type> > &immigrants, const base_island &isl) const
401 {
402  individual_type tmp;
403  tmp.cur_v.resize(isl.m_pop.problem().get_dimension());
404  tmp.cur_f.resize(isl.m_pop.problem().get_f_dimension());
405  tmp.cur_c.resize(isl.m_pop.problem().get_c_dimension());
406  for (std::vector<std::pair<population::size_type, individual_type> >::iterator ind_it = immigrants.begin(); ind_it != immigrants.end(); ++ind_it) {
407  tmp.cur_x = (*ind_it).second.cur_x;
408  isl.m_pop.problem().objfun(tmp.cur_f,tmp.cur_x);
409  isl.m_pop.problem().compute_constraints(tmp.cur_c,tmp.cur_x);
410  // Set the best properties to the current ones. (TODO: maybe here one could
411  // reevaluate the old best in the new environment and keep it if still better than the
412  // reevaluated current ...... discuss!! (Anche no, grazie!!)
413  tmp.best_x = tmp.cur_x;
414  tmp.best_f = tmp.cur_f;
415  tmp.best_c = tmp.cur_c;
416  (*ind_it).second = tmp;
417  }
418 }
419 
421 
427 void archipelago::set_seeds(unsigned int seed) {
428  m_drng.seed(seed);
429  m_urng.seed(seed+1); // we do not care if it overflows
430 }
431 
432 
433 
434 // This method will be called by each island of the archipelago before starting evolution. Its task is
435 // to select from the other islands, according to the topology and the migration/distribution type and direction,
436 // the individuals that will migrate into the island.
437 void archipelago::pre_evolution(base_island &isl)
438 {
439  // Make sure the island belongs to the archipelago.
440  pagmo_assert(isl.m_archi == this);
441  // Make sure the archipelago is not empty.
442  pagmo_assert(m_container.size());
443  // Determine the island's index in the archipelago.
444  const size_type isl_idx = locate_island(isl);
445  pagmo_assert(isl_idx < m_container.size());
446  //1. Obtain immigrants.
447  std::vector<std::pair<population::size_type, individual_type> > immigrants;
448  switch (m_migr_dir) {
449  case source:
450  {
451  lock_type lock(m_migr_mutex);
452  // For source migration direction, migration map contains islands' "inboxes". Or, in other words, it contains
453  // the individuals that are destined to go into the island. Such inboxes have been assembled previously,
454  // during a post_evolution operation.
455  // Iterate over all the vectors of individuals provided by the different islands.
456  for (boost::unordered_map<size_type,std::vector<individual_type> >::iterator it = m_migr_map[isl_idx].begin();
457  it != m_migr_map[isl_idx].end(); ++it)
458  {
459  pagmo_assert(it->first < m_container.size());
460  build_immigrants_vector(immigrants,*m_container[it->first],isl,it->second);
461  }
462  // Delete stuff in the migration map.
463  m_migr_map.erase(isl_idx);
464  break;
465  }
466  case destination:
467  // For destination migration direction, items in the migration map behave like "outboxes", i.e. each one is a
468  // "database of best individuals" seen in the islands of the archipelago.
469  // Get neighbours connecting into isl.
470  const std::vector<topology::base::vertices_size_type> inv_adj_islands(m_topology->get_v_inv_adjacent_vertices(boost::numeric_cast<topology::base::vertices_size_type>(isl_idx)));
471  // Do something only if there are adjacent islands.
472  if (inv_adj_islands.size()) {
473  switch (m_dist_type) {
474  case point_to_point:
475  {
476  lock_type lock(m_migr_mutex);
477  // Get the index of a random island connecting into isl.
478  boost::uniform_int<std::vector<topology::base::vertices_size_type>::size_type> u_int(0,inv_adj_islands.size() - 1);
479  const size_type rn_isl_idx = boost::numeric_cast<size_type>(inv_adj_islands[u_int(m_urng)]);
480  // Get the immigrants from the outbox of the random island. Note the redundant information in the last
481  // argument of the function.
482  pagmo_assert(m_migr_map[rn_isl_idx].size() <= 1);
483 
484  double next_rng = m_drng();
485  double migr_prob = m_topology->get_weight(rn_isl_idx, isl_idx);
486  if (next_rng < migr_prob) {
487  build_immigrants_vector(immigrants,*m_container[rn_isl_idx],isl,m_migr_map[rn_isl_idx][rn_isl_idx]);
488  }
489  break;
490  }
491  case broadcast:
492  {
493  lock_type lock(m_migr_mutex);
494  // For broadcast migration fetch immigrants from all neighbour islands' databases.
495  for (std::vector<topology::base::vertices_size_type>::size_type i = 0; i < inv_adj_islands.size(); ++i) {
496  const size_type src_isl_idx = boost::numeric_cast<size_type>(inv_adj_islands[i]);
497  pagmo_assert(m_migr_map[src_isl_idx].size() <= 1);
498  double next_rng = m_drng();
499  double migr_prob = m_topology->get_weight(src_isl_idx, isl_idx);
500  if (next_rng < migr_prob) {
501  build_immigrants_vector(immigrants,*m_container[src_isl_idx],isl,m_migr_map[src_isl_idx][src_isl_idx]);
502  }
503  }
504  }
505  }
506  }
507  }
508  //2. Insert immigrants into population.
509  if (immigrants.size()) {
510  // We re-evaluate the incoming individuals according
511  // to destination island's problem. This will make sure that stochastic problems
512  // are correctly dealt with
513  reevaluate_immigrants(immigrants,isl);
514  // We then insert the incoming individuals into the population, storing how many from where
515  std::vector<std::pair<population::size_type, size_type> > rec_history;
516  rec_history = isl.accept_immigrants(immigrants);
517  lock_type lock(m_migr_mutex);
518  // Record the migration history.
519  for (size_t i =0; i< rec_history.size(); ++i) {
520  m_migr_hist.push_back( boost::make_tuple(
521  rec_history[i].first,
522  rec_history[i].second,
523  isl_idx)
524  );
525  }
526  }
527 }
528 
529 // This method will be called after each island isl has completed an evolution. Its purpose is to get individuals
530 // emigrating from isl and put them at disposal of the other islands of the archipelago, according to the migration attributes
531 // and the topology.
532 void archipelago::post_evolution(base_island &isl)
533 {
534  // Make sure the island belongs to the archipelago.
535  pagmo_assert(isl.m_archi == this);
536  // Make sure the archipelago is not empty.
537  pagmo_assert(m_container.size());
538  // Determine the island's index in the archipelago.
539  const size_type isl_idx = locate_island(isl);
540  pagmo_assert(isl_idx < m_container.size());
541  // Create the vector of emigrants.
542  std::vector<individual_type> emigrants;
543  switch (m_migr_dir) {
544  case source:
545  {
546  // Get the islands to which isl connects.
547  const std::vector<topology::base::vertices_size_type> adj_islands(m_topology->get_v_adjacent_vertices(boost::numeric_cast<topology::base::vertices_size_type>(isl_idx)));
548  if (adj_islands.size()) {
549  emigrants = isl.get_emigrants();
550  // Do something only if we have emigrants.
551  if (emigrants.size()) {
552  switch (m_dist_type)
553  {
554  case point_to_point:
555  {
556  lock_type lock(m_migr_mutex);
557  // For one-to-one migration choose a random neighbour island and put immigrants to its inbox.
558  boost::uniform_int<std::vector<topology::base::vertices_size_type>::size_type> u_int(0,adj_islands.size() - 1);
559  const size_type chosen_adj = boost::numeric_cast<size_type>(adj_islands[u_int(m_urng)]);
560  double next_rng = m_drng();
561  double migr_prob = m_topology->get_weight(isl_idx, chosen_adj);
562  if (next_rng < migr_prob) {
563  m_migr_map[chosen_adj][isl_idx].insert(m_migr_map[chosen_adj][isl_idx].end(),emigrants.begin(),emigrants.end());
564  }
565  break;
566  }
567  case broadcast:
568  {
569  lock_type lock(m_migr_mutex);
570  // For broadcast migration put immigrants to all neighbour islands' inboxes.
571  for (std::vector<topology::base::vertices_size_type>::size_type i = 0; i < adj_islands.size(); ++i) {
572  double next_rng = m_drng();
573  double migr_prob = m_topology->get_weight(isl_idx, adj_islands[i]);
574  if (next_rng < migr_prob) {
575  m_migr_map[boost::numeric_cast<size_type>(adj_islands[i])][isl_idx]
576  .insert(m_migr_map[boost::numeric_cast<size_type>(adj_islands[i])][isl_idx].end(),
577  emigrants.begin(),emigrants.end());
578  }
579  }
580  }
581  }
582  }
583  }
584  break;
585  }
586  case destination:
587  {
588  // For destination migration direction, migration map behaves like "outboxes", i.e. each is a "database of best individuals" for corresponding island.
589  emigrants = isl.get_emigrants();
590  lock_type lock(m_migr_mutex);
591  pagmo_assert(m_migr_map[isl_idx].size() <= 1);
592  m_migr_map[isl_idx][isl_idx].swap(emigrants);
593  }
594  }
595 }
596 
598 
604 {
605  join();
606  const iterator it_f = m_container.end();
607  // Reset thread barrier.
608  reset_barrier(m_container.size());
609  for (iterator it = m_container.begin(); it != it_f; ++it) {
610  (*it)->evolve(n);
611  }
612 }
613 
615 
625 void archipelago::evolve_batch(int n, unsigned int b, bool randomize)
626 {
627  join();
628  container_type::size_type arch_size = this->get_size();
629  // Order of populations to evolve, by default biased by the index (lowest first)
630  std::vector<population::size_type> pop_order(arch_size);
631  for(population::size_type i=0; i < pop_order.size(); ++i)
632  pop_order[i] = i;
633 
634  // Optionally, randomize the order of populations (True by default)
635  if(randomize) {
636  // Variate generators
637  boost::uniform_int<int> pop_idx(0,arch_size-1);
638  boost::variate_generator<boost::mt19937 &, boost::uniform_int<int> > p_idx(m_urng,pop_idx);
639  std::random_shuffle(pop_order.begin(), pop_order.end(), p_idx);
640  }
641 
642  for(size_type p = 0; p < arch_size/b + 1; ++p) {
643  if(p == arch_size/b) { //for the last batch of islands decrease the barrier
644  reset_barrier(arch_size - p*b);
645  } else {
646  reset_barrier(b);
647  }
648  for(size_type i=0; i<b && p*b+i < arch_size; ++i) {
649  m_container[pop_order[p*b+i]]->evolve(n);
650  }
651  for(size_type i=0; i<b && p*b+i < arch_size; ++i) {
652  m_container[pop_order[p*b+i]]->join();
653  }
654  }
655 }
656 
658 
664 {
665  join();
666  const iterator it_f = m_container.end();
667  reset_barrier(m_container.size());
668  for (iterator it = m_container.begin(); it != it_f; ++it) {
669  (*it)->evolve_t(t);
670  }
671 }
672 
674 
677 bool archipelago::busy() const
678 {
679  const const_iterator it_f = m_container.end();
680  for (const_iterator it = m_container.begin(); it != it_f; ++it) {
681  if ((*it)->busy()) {
682  return true;
683  }
684  }
685  return false;
686 }
687 
689 
693 {
694  const iterator it_f = m_container.end();
695  for (iterator it = m_container.begin(); it != it_f; ++it) {
696  (*it)->interrupt();
697  }
698 }
699 
701 
709 {
710  join();
711  if (idx >= m_container.size()) {
712  pagmo_throw(index_error,"invalid island index");
713  }
714  base_island_ptr retval = m_container[idx]->clone();
715  // The island is no more in an archipelago.
716  retval->m_archi = 0;
717  return retval;
718 }
719 
721 
728 void archipelago::set_island(const size_type &idx, const base_island &isl)
729 {
730  join();
731  if (idx >= m_container.size()) {
732  pagmo_throw(index_error,"invalid island index");
733  }
734  if (!check_island(isl)) {
735  pagmo_throw(value_error,"cannot set incompatible island");
736  }
737  m_container[idx] = isl.clone();
738  // Tell the island that it is living in an archipelago now.
739  m_container[idx]->m_archi = this;
740 }
741 
743 
746 std::vector<base_island_ptr> archipelago::get_islands() const
747 {
748  join();
749  std::vector<base_island_ptr> retval;
750  for (size_type i = 0; i < get_size(); ++i) {
751  retval.push_back(m_container[i]->clone());
752  // The island is no more in an archipelago.
753  retval.back()->m_archi = 0;
754  }
755  return retval;
756 }
757 
758 // Synchronise the start of evolution in each island so that all threads are created and initialised
759 // before actually doing any computation.
760 void archipelago::sync_island_start() const
761 {
762  m_islands_sync_point->wait();
763 }
764 
766 
771 {
772  join();
773  std::ostringstream oss;
774  for (migr_hist_type::const_iterator it = m_migr_hist.begin(); it != m_migr_hist.end(); ++it) {
775  oss << "(" << (*it).get<0>()
776  << "," << (*it).get<1>()
777  << "," << (*it).get<2>() << ")"
778  << '\n';
779  }
780  return oss.str();
781 }
782 
784 
789 {
790  join();
791  m_migr_hist.clear();
792 }
793 
795 
803 std::ostream &operator<<(std::ostream &s, const archipelago &a)
804 {
805  s << a.human_readable();
806  return s;
807 }
808 
809 }
virtual base_island_ptr clone() const =0
Clone method.
Root PaGMO namespace.
migration_direction
Migration direction.
Definition: archipelago.h:87
Generic thread-safe generator of pseudo-random number generators.
Definition: rng.h:138
container_type::size_type size_type
Archipelago size type.
Definition: archipelago.h:65
boost::shared_ptr< base > base_ptr
Alias for shared pointer to base topology.
Definition: topology/base.h:47
std::ostream & operator<<(std::ostream &s, const archipelago &a)
Overload stream operator for pagmo::archipelago.
bool busy() const
Query the status of the archipelago.
This rng returns an unsigned integer in the [0,2**32-1] range.
Definition: rng.h:47
Base topology class.
Definition: topology/base.h:75
topology::base_ptr get_topology() const
Return a copy of the topology.
Base algorithm class.
~archipelago()
Destructor.
virtual base_ptr clone() const =0
Clone method.
Local island class.
Definition: island.h:68
size_type get_size() const
Get the size of the archipelago.
Base problem class.
Definition: problem/base.h:148
distribution_type
Distribution type for migrating individuals.
Definition: archipelago.h:69
bool check_island(const base_island &) const
Check whether an island is compatible with the archipelago.
Immigrants flow is initiated by the destination island.
Definition: archipelago.h:106
void evolve_t(int)
Run the evolution for a minimum amount of time.
base_island_ptr get_island(const size_type &) const
Island getter.
archipelago & operator=(const archipelago &)
Assignment operator.
std::vector< base_island_ptr > get_islands() const
Get vector of islands in the archipelago.
virtual void join() const
Join island.
void push_back(const base_island &)
Add an island to the archipelago.
population::individual_type individual_type
Individual type.
Definition: archipelago.h:67
void set_seeds(unsigned int)
Sets the seed of the random number generators of the archipelago.
void clear_migr_history()
Clears the archipelago migration history.
void join() const
Wait until evolution on each island has terminated.
std::string human_readable() const
Return human readable representation of the archipelago.
Base island class.
Definition: base_island.h:81
Individuals migrate to all the island's neighbours.
Definition: archipelago.h:80
bool is_compatible(const base &) const
Compatibility operator.
void evolve_batch(int, unsigned int, bool=true)
Run the evolution for the given number of iterations in batches.
std::string dump_migr_history() const
Dumps the archipelago migration history.
archipelago * m_archi
Pointer that, if not null, points to the archipelago containing the island.
Definition: base_island.h:163
void set_island(const size_type &, const base_island &)
Island setter.
decision_vector cur_v
Current velocity vector.
Definition: population.h:85
boost::shared_ptr< base_island > base_island_ptr
Alias for the shared pointer to a pagmo::base_island.
Definition: base_island.h:49
void evolve(int=1)
Run the evolution for the given number of iterations.
population m_pop
Population.
Definition: base_island.h:161
distribution_type get_distribution_type() const
Return a copy of the distribution type.
container_type::size_type size_type
Population size type.
Definition: population.h:192
void set_topology(const topology::base &)
Set topology.
Individuals migrate to one of the island's neighbours.
Definition: archipelago.h:75
Immigrants flow is initiated by the source island.
Definition: archipelago.h:98
Archipelago class.
Definition: archipelago.h:57
archipelago(distribution_type=point_to_point, migration_direction=destination)
Default constructor.
Definition: archipelago.cpp:68
void interrupt()
Interrupt ongoing evolution.
void set_algorithm(const size_type &, const algorithm::base &)
Set island algorithm.
void set_distribution_type(const distribution_type &)
Set distribution type.
This rng returns a double in the [0,1[ range.
Definition: rng.h:89