PaGMO  1.1.5
fair_r_policy.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 <algorithm>
26 #include <boost/numeric/conversion/cast.hpp>
27 #include <utility>
28 #include <vector>
29 
30 #include "../population.h"
31 #include "base.h"
32 #include "base_r_policy.h"
33 #include "fair_r_policy.h"
34 
35 namespace pagmo { namespace migration {
36 
38 
44 fair_r_policy::fair_r_policy(const double &rate, rate_type type):base_r_policy(rate,type) {}
45 
47 {
48  return base_r_policy_ptr(new fair_r_policy(*this));
49 }
50 
51 // Helper object used to sort arrays of indices of object placed in another container.
52 template <class Container>
53 struct indirect_individual_sorter
54 {
55  indirect_individual_sorter(const Container &container, const population &pop):
56  m_container(container),m_pop(pop) {}
57  template <class Idx>
58  bool operator()(const Idx &idx1, const Idx &idx2) const
59  {
60  typedef typename Container::const_iterator::difference_type diff_type;
61  return m_pop.n_dominated(*(m_container.begin() + boost::numeric_cast<diff_type>(idx1))) >
62  m_pop.n_dominated(*(m_container.begin() + boost::numeric_cast<diff_type>(idx2)));
63  }
64  // The original container.
65  const Container &m_container;
66  const population &m_pop;
67 };
68 
69 // Selection implementation.
70 std::vector<std::pair<population::size_type,std::vector<population::individual_type>::size_type> >
71  fair_r_policy::select(const std::vector<population::individual_type> &immigrants, const population &dest) const
72 {
73  // Computes the number of immigrants to be selected (accounting for the destination pop size)
74  const population::size_type rate_limit = std::min<population::size_type>(get_n_individuals(dest),boost::numeric_cast<population::size_type>(immigrants.size()));
75 
76  // Defines the retvalue
77  std::vector<std::pair<population::size_type,std::vector<population::individual_type>::size_type> > result;
78 
79  // Makes a copy of the destination population
80  population pop_copy(dest);
81 
82  // Creates a population combining all (INEFFICIENT: not-needed function evaluations are performed here)
83  for (population::size_type i = 0; i < rate_limit; ++i) {
84  pop_copy.push_back(immigrants[i].cur_x);
85  }
86 
87  // Extracts the best of the combined population
88  std::vector<population::size_type> best_idx(pop_copy.get_best_idx(pop_copy.size()));
89 
90  std::vector<population::size_type>::iterator left = best_idx.begin();
91  std::vector<population::size_type>::iterator right = best_idx.end() - 1;
92 
93  // Best idx now contains, sorted, all indexes of the augmented pop. Indexes from 0 to pop.size()
94  // belong to the original population, the others are immigrants
95  while (left < right) {
96  // If the index belongs to one of the immigrants
97  if (*left >= dest.size()) {
98  // Move the right iterator up to when it points to the worst of the natives
99  while (*right >= dest.size()) {
100  --right;
101  };
102  if (right>left) {
103  result.push_back(std::make_pair(*right,*left-dest.size()));
104  --right;
105  }
106  }
107  ++left;
108  }
109 
110 
111  // Temporary vectors to store sorted indices of the populations.
112 // std::vector<population::size_type> immigrants_idx(boost::numeric_cast<std::vector<population::size_type>::size_type>(immigrants.size()));
113 // std::vector<population::size_type> dest_idx(boost::numeric_cast<std::vector<population::size_type>::size_type>(dest.size()));
114  // Fill in the arrays of indices.
115 // iota(immigrants_idx.begin(),immigrants_idx.end(),population::size_type(0));
116 // iota(dest_idx.begin(),dest_idx.end(),population::size_type(0));
117  // Sort the arrays of indices.
118  // From best to worst.
119 // std::sort(immigrants_idx.begin(),immigrants_idx.end(),indirect_individual_sorter<std::vector<population::individual_type> >(immigrants,dest));
120  // From worst to best.
121 // std::sort(dest_idx.begin(),dest_idx.end(),indirect_individual_sorter<population>(dest,dest));
122 // std::reverse(dest_idx.begin(),dest_idx.end());
123  // Create the result.
124 // std::vector<std::pair<population::size_type,std::vector<population::individual_type>::size_type> > result;
125 // for (population::size_type i = 0; i < rate_limit; ++i) {
126 // if (dest.n_dominated(immigrants[immigrants_idx[boost::numeric_cast<std::vector<population::size_type>::size_type>(i)]]) >
127 // dest.n_dominated(*(dest.begin() + dest_idx[boost::numeric_cast<std::vector<population::size_type>::size_type>(i)])))
128 // {
129 // result.push_back(std::make_pair(dest_idx[i],immigrants_idx[i]));
130 // }
131 // }
132  return result;
133 }
134 
135 }}
136 
137 BOOST_CLASS_EXPORT_IMPLEMENT(pagmo::migration::fair_r_policy)
Root PaGMO namespace.
Base class for migration replacement policies.
Definition: base_r_policy.h:57
boost::shared_ptr< base_r_policy > base_r_policy_ptr
Shared pointer to base replacement policy.
Definition: base_r_policy.h:40
std::vector< std::pair< population::size_type, std::vector< population::individual_type >::size_type > > select(const std::vector< population::individual_type > &, const population &) const
Assign pairs of individuals for replacement during migration.
Population class.
Definition: population.h:70
Fair replacement policy.
Definition: fair_r_policy.h:49
population::size_type get_n_individuals(const population &) const
Get number of individuals to migrate from/to input population.
fair_r_policy(const double &rate=1, rate_type type=absolute)
Constructor from rate and rate type.
container_type::size_type size_type
Population size type.
Definition: population.h:192
base_r_policy_ptr clone() const
Clone method.
rate_type
Type of migration rate.