25 #include <boost/date_time/posix_time/posix_time.hpp>
26 #include <boost/numeric/conversion/cast.hpp>
27 #include <boost/thread/thread.hpp>
28 #include <boost/random/uniform_int.hpp>
29 #include <boost/random/variate_generator.hpp>
40 #include "algorithm/base.h"
41 #include "archipelago.h"
42 #include "base_island.h"
43 #include "exceptions.h"
44 #include "migration/base_r_policy.h"
45 #include "migration/base_s_policy.h"
46 #include "population.h"
47 #include "problem/base.h"
67 m_algo(a.clone()),m_pop(p,n),m_archi(0),m_evo_time(0),m_s_policy(s_policy.clone()),m_r_policy(r_policy.clone()) { }
99 m_algo(a.clone()),m_pop(pop),m_archi(0),m_evo_time(0),m_s_policy(s_policy.clone()),m_r_policy(r_policy.clone()) { }
145 return typeid(*this).name();
160 std::ostringstream oss;
161 oss <<
"Island type: " <<
get_name() <<
"\n\n";
163 oss <<
"Evolution time: " <<
m_evo_time <<
" milliseconds\n\n";
166 oss <<
m_pop.human_readable_terse() <<
'\n';
182 std::ostringstream oss;
183 oss <<
"Island type: " <<
get_name() <<
"\n\n";
185 oss <<
"Evolution time: " <<
m_evo_time <<
" milliseconds\n\n";
188 oss <<
m_pop.human_readable();
223 struct base_island::raii_thread_hook
227 m_ptr->thread_entry();
231 m_ptr->thread_exit();
237 struct base_island::int_evolver {
238 int_evolver(
base_island *i,
const std::size_t &n):m_i(i),m_n(n) {}
240 void juice_impl(boost::posix_time::ptime &);
242 const std::size_t m_n;
245 void base_island::int_evolver::juice_impl(boost::posix_time::ptime &start)
247 start = boost::posix_time::microsec_clock::local_time();
250 m_i->m_archi->sync_island_start();
252 const raii_thread_hook hook(m_i);
253 for (std::size_t i = 0; i < m_n; ++i) {
256 m_i->m_archi->pre_evolution(*m_i);
258 m_i->m_pop.problem().pre_evolution(m_i->m_pop);
260 m_i->perform_evolution(*m_i->m_algo,m_i->m_pop);
263 m_i->m_archi->post_evolution(*m_i);
265 m_i->m_pop.problem().post_evolution(m_i->m_pop);
267 boost::this_thread::interruption_point();
272 void base_island::int_evolver::operator()()
274 boost::posix_time::ptime start;
277 }
catch (
const boost::thread_interrupted &) {
279 }
catch (
const std::exception &e) {
280 std::cout <<
"Error during island evolution using " << m_i->m_algo->get_name() <<
": " << e.what() << std::endl;
282 std::cout <<
"Error during island evolution using " << m_i->m_algo->get_name() <<
", unknown exception caught. :(" << std::endl;
288 const boost::posix_time::time_duration diff = boost::posix_time::microsec_clock::local_time() - start;
289 if (diff.total_milliseconds() >= 0) {
290 m_i->m_evo_time += boost::numeric_cast<std::size_t>(diff.total_milliseconds());
293 std::cout <<
"Error calculating evolution time.\n";
311 const std::size_t n_evo = boost::numeric_cast<std::size_t>(n);
313 m_evo_thread.reset(
new boost::thread(int_evolver(
this,n_evo)));
315 pagmo_throw(std::runtime_error,
"failed to launch the thread");
320 struct base_island::t_evolver {
321 t_evolver(
base_island *i,
const std::size_t &t):m_i(i),m_t(t) {}
323 void juice_impl(boost::posix_time::ptime &);
325 const std::size_t m_t;
328 void base_island::t_evolver::juice_impl(boost::posix_time::ptime &start)
330 boost::posix_time::time_duration diff;
331 start = boost::posix_time::microsec_clock::local_time();
334 m_i->m_archi->sync_island_start();
336 const raii_thread_hook hook(m_i);
339 m_i->m_archi->pre_evolution(*m_i);
341 m_i->m_pop.problem().pre_evolution(m_i->m_pop);
342 m_i->perform_evolution(*m_i->m_algo,m_i->m_pop);
344 m_i->m_archi->post_evolution(*m_i);
346 m_i->m_pop.problem().post_evolution(m_i->m_pop);
348 boost::this_thread::interruption_point();
349 diff = boost::posix_time::microsec_clock::local_time() - start;
351 }
while (diff.total_milliseconds() < 0 || boost::numeric_cast<std::size_t>(diff.total_milliseconds()) < m_t);
355 void base_island::t_evolver::operator()()
357 boost::posix_time::ptime start;
360 }
catch (
const boost::thread_interrupted &) {
362 }
catch (
const std::exception &e) {
363 std::cout <<
"Error during island evolution using " << m_i->m_algo->get_name() <<
": " << e.what() << std::endl;
365 std::cout <<
"Error during island evolution using " << m_i->m_algo->get_name() <<
", unknown exception caught. :(" << std::endl;
371 const boost::posix_time::time_duration diff = boost::posix_time::microsec_clock::local_time() - start;
372 if (diff.total_milliseconds() >= 0) {
373 m_i->m_evo_time += boost::numeric_cast<std::size_t>(diff.total_milliseconds());
376 std::cout <<
"Error calculating evolution time.\n";
394 const std::size_t t_evo = boost::numeric_cast<std::size_t>(t);
396 m_evo_thread.reset(
new boost::thread(t_evolver(
this,t_evo)));
398 pagmo_throw(std::runtime_error,
"failed to launch the thread");
424 return (!
m_evo_thread->timed_join(boost::posix_time::milliseconds(1)));
548 struct unary_predicate {
549 unary_predicate(std::pair<population::size_type, archipelago::size_type> pair) : m_pair(pair) {};
550 bool operator()(std::pair<population::size_type, archipelago::size_type> x){
551 return (m_pair.second == x.second);
553 std::pair<population::size_type, archipelago::size_type> m_pair;
557 std::vector<std::pair<population::size_type, archipelago::size_type> > base_island::accept_immigrants(std::vector<std::pair<population::size_type, population::individual_type> > &immigrant_pairs)
559 std::vector<std::pair<population::size_type, archipelago::size_type> > retval;
563 boost::uniform_int<int> pop_idx(0,immigrant_pairs.size());
564 boost::variate_generator<boost::mt19937 &, boost::uniform_int<int> > p_idx(
m_pop.m_urng,pop_idx);
565 std::random_shuffle(immigrant_pairs.begin(),immigrant_pairs.end(), p_idx);
567 std::vector<population::individual_type> immigrants;
568 immigrants.reserve(immigrant_pairs.size());
569 for (
size_t i=0;i<immigrant_pairs.size();++i) {
570 immigrants.push_back(immigrant_pairs[i].second);
573 std::vector<std::pair<population::size_type,std::vector<population::individual_type>::size_type> > rep;
575 for (std::vector<std::pair<
population::size_type,std::vector<population::individual_type>::size_type> >::const_iterator
576 rep_it = rep.begin(); rep_it != rep.end(); ++rep_it)
578 pagmo_assert((*rep_it).first <
m_pop.m_container.size() && (*rep_it).second < immigrants.size());
579 m_pop.m_container[(*rep_it).first] = immigrants[(*rep_it).second];
580 m_pop.update_champion((*rep_it).first);
581 m_pop.update_dom((*rep_it).first);
582 std::pair<population::size_type, archipelago::size_type> pair = std::make_pair(1.0, immigrant_pairs[(*rep_it).second].first);
583 std::vector<std::pair<population::size_type, archipelago::size_type> >::iterator where;
584 where = std::find_if(retval.begin(), retval.end(), unary_predicate(pair));
585 if (where == retval.end()) {
586 retval.push_back(pair);
596 std::vector<population::individual_type> base_island::get_emigrants()
boost::shared_ptr< base > base_ptr
Alias for shared pointer to base algorithm.
std::string human_readable_terse() const
Return terse human readable representation of the island.
boost::shared_ptr< base > base_ptr
Alias for shared pointer to base problem.
void evolve_t(int)
Evolve island for a specified minimum amount of time.
std::vector< double > decision_vector
Decision vector type.
virtual std::string get_name() const
Return a string identifying the island's type.
Base class for migration replacement policies.
void interrupt()
Interrupt evolution.
Base class for migration selection policies.
boost::shared_ptr< base_r_policy > base_r_policy_ptr
Shared pointer to base replacement policy.
std::ostream & operator<<(std::ostream &s, const archipelago &a)
Overload stream operator for pagmo::archipelago.
migration::base_s_policy_ptr m_s_policy
Migration selection policy.
migration::base_r_policy_ptr get_r_policy() const
Get a copy of the replacement policy.
migration::base_r_policy_ptr m_r_policy
Migration replacement policy.
virtual ~base_island()
Destructor.
std::size_t get_evolution_time() const
Return the total evolution time in milliseconds.
void evolve(int=1)
Evolve island n times.
std::size_t m_evo_time
Total time spent by the island on evolution (in milliseconds).
virtual base_ptr clone() const =0
Clone method.
std::string human_readable() const
Return human readable representation of the island.
virtual void join() const
Join island.
algorithm::base_ptr get_algorithm() const
Return copy of the internal algorithm.
virtual void thread_entry()
Thread entry hook.
virtual base_ptr clone() const =0
Clone method.
algorithm::base_ptr m_algo
Algorithm.
base_island & operator=(const base_island &)
Assignment operator.
migration::base_s_policy_ptr get_s_policy() const
Get a copy of the selection policy.
void set_algorithm(const algorithm::base &)
Algorithm setter.
archipelago * m_archi
Pointer that, if not null, points to the archipelago containing the island.
void set_v(population::size_type, const decision_vector &)
Sets a velocity vector.
virtual void thread_exit()
Thread exit hook.
problem::base_ptr get_problem() const
Return copy of the internal problem.
void set_population(const population &)
Set internal population.
boost::shared_ptr< base_s_policy > base_s_policy_ptr
Shared pointer to base selection policy.
population m_pop
Population.
container_type::size_type size_type
Population size type.
void set_x(population::size_type, const decision_vector &)
Sets a decision vector.
base_island(const base_island &)
Copy constructor.
population::size_type get_size() const
Size of the internal population.
bool busy() const
Query the status of the island.
boost::scoped_ptr< boost::thread > m_evo_thread
Evolution thread.
population get_population() const
Get a copy of the internal population.