Individual.h
Go to the documentation of this file.
1 /*!
2  *
3  *
4  * \brief TypedIndividual
5  *
6  * \author T.Voss, T. Glasmachers, O.Krause
7  * \date 2010-2014
8  *
9  *
10  * \par Copyright 1995-2017 Shark Development Team
11  *
12  * <BR><HR>
13  * This file is part of Shark.
14  * <http://shark-ml.org/>
15  *
16  * Shark is free software: you can redistribute it and/or modify
17  * it under the terms of the GNU Lesser General Public License as published
18  * by the Free Software Foundation, either version 3 of the License, or
19  * (at your option) any later version.
20  *
21  * Shark is distributed in the hope that it will be useful,
22  * but WITHOUT ANY WARRANTY; without even the implied warranty of
23  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
24  * GNU Lesser General Public License for more details.
25  *
26  * You should have received a copy of the GNU Lesser General Public License
27  * along with Shark. If not, see <http://www.gnu.org/licenses/>.
28  *
29  */
30 #ifndef SHARK_ALGORITHMS_DIRECT_SEARCH_TYPED_INDIVIDUAL_H
31 #define SHARK_ALGORITHMS_DIRECT_SEARCH_TYPED_INDIVIDUAL_H
32 
33 #include <shark/LinAlg/Base.h>
34 #include <boost/range/adaptor/transformed.hpp>
35 
36 namespace shark {
37 
38 /// \brief Individual is a simple templated class modelling
39 /// an individual that acts as a candidate solution in an evolutionary algorithm.
40 ///
41 /// The class holds the current search point as well as the penalized and unpenalized fitness,
42 /// its domination rank with respect to the population, its age, a boolean variable determining
43 /// whether the individual is selected for the next parent generation and some payload chromosome
44 /// which is by default a RealVector.
45 ///
46 /// The states mean the following:
47 /// - the search point is the point in search space the individual represents.
48 /// - the penalized and unpenailzed fitness are related by:
49 /// if the search point is in the search region of the optimization region, penalized and unpenalized
50 /// fitness are the same. otherwise the unpenalized fitness is the value of the closest feasible point
51 /// to the search point. The penalized fitness is the same value plus an penalty term. Usually this
52 /// is ||s-closestFeasible(s)||^2, the squared distance between the search point and the closest
53 /// feasible point.
54 /// - the domination rank indicates in which front the individual is. a nondominated individual has rank
55 /// 1, individuals that are only dominated by individuals with rank one have rank 2 and so on.
56 /// In single objective optimization, the rank is simply the number of individuals with better fitness+1.
57 /// - the age is the number of generations the individual has survived.
58 /// - selection: survival selection schemes never delete or move points, instead they indicate which points
59 /// are to be deleted.
60 template< typename PointType, class FitnessTypeT, class Chromosome = RealVector >
61 class Individual {
62 public:
63 
64  typedef FitnessTypeT FitnessType;
65 
66  typedef PointType SearchPointType;
67 
68  ///\brief Ordering relation by the ranks of the individuals
69  struct RankOrdering{
70  bool operator()(Individual const& individual1, Individual const& individual2){
71  return individual1.rank() < individual2.rank();
72  }
73  };
74 
75  ///\brief Ordering relation by the fitness of the individuals(only single objective)
77  bool operator()(Individual const& individual1, Individual const& individual2){
78  return individual1.unpenalizedFitness() < individual2.unpenalizedFitness() ;
79  }
80  };
81 
82  /// \brief Default constructor that initializes the individual's attributes to default values.
84  : m_rank(0)
85  , m_selected(false)
86  {}
87 
88  /// \brief Returns a reference to the search point that is associated with the individual.
89  SearchPointType& searchPoint() {
90  return m_searchPoint;
91  }
92 
93  /// \brief Returns a const reference to the search point that is associated with the individual.
94  SearchPointType const& searchPoint() const {
95  return m_searchPoint;
96  }
97 
98  /// \brief Returns a reference to the chromosome that is associated with the individual.
99  Chromosome& chromosome() {
100  return m_chromosome;
101  }
102 
103  /// \brief Returns a const reference to the chromosome that is associated with the individual.
104  Chromosome const& chromosome() const{
105  return m_chromosome;
106  }
107 
108  /// \brief Returns a reference to the unpenalized fitness of the individual.
109  FitnessType& unpenalizedFitness() {
110  return m_unpenalizedFitness;
111  }
112 
113  /// \brief Returns the unpenalized fitness of the individual.
114  FitnessType const& unpenalizedFitness() const {
115  return m_unpenalizedFitness;
116  }
117 
118  /// \brief Returns a reference to the penalized fitness of the individual.
119  FitnessType& penalizedFitness() {
120  return m_penalizedFitness;
121  }
122  /// \brief Returns the unpenalized fitness of the individual.
123  FitnessType const& penalizedFitness() const {
124  return m_penalizedFitness;
125  }
126 
127  /// \brief Returns the level of non-dominance of the individual.
128  unsigned int rank() const {
129  return m_rank;
130  }
131 
132  /// \brief Returns a reference to the level of non-dominance of the individual. Allows for lvalue()-semantic.
133  unsigned int& rank() {
134  return m_rank;
135  }
136 
137  /// \brief Returns true if the individual is selected for the next parent generation
138  bool selected() const {
139  return m_selected;
140  }
141 
142  /// \brief Returns true if the individual is selected for the next parent generation
143  bool& selected() {
144  return m_selected;
145  }
146 
147  /// \brief Stores the individual and all of its chromosomes in an archive.
148  template<typename Archive>
149  void serialize(Archive & archive, const unsigned int version) {
150  archive & BOOST_SERIALIZATION_NVP(m_searchPoint);
151  archive & BOOST_SERIALIZATION_NVP(m_chromosome);
152  archive & BOOST_SERIALIZATION_NVP(m_penalizedFitness);
153  archive & BOOST_SERIALIZATION_NVP(m_unpenalizedFitness);
154  archive & BOOST_SERIALIZATION_NVP(m_rank);
155  archive & BOOST_SERIALIZATION_NVP(m_selected);
156 
157  }
158 
159  friend void swap(Individual& i1, Individual& i2){
160  using std::swap;
163  swap(i1.m_rank,i2.m_rank);
164  swap(i1.m_selected,i2.m_selected);
167  }
168 
169 protected:
170  SearchPointType m_searchPoint; ///< The search point associated with the individual.
171  Chromosome m_chromosome; ///< The search point associated with the individual.
172 
173  unsigned int m_rank; ///< The level of non-dominance of the individual. The lower the better.
174  bool m_selected; ///< Is the individual selected for the next parent set?
175 
176  FitnessType m_penalizedFitness; ///< Penalized fitness of the individual.
177  FitnessType m_unpenalizedFitness; ///< Unpenalized fitness of the individual.
178 };
179 
180 //TODO: pre C++14, this is too hard to implement using lambdas only.
181 namespace detail{
182  struct IndividualPenalizedFitnessFunctor{
183  template<class Individual>
184  typename Individual::FitnessType& operator()(Individual& ind)const{
185  return ind.penalizedFitness();
186  }
187  template<class Individual>
188  typename Individual::FitnessType const& operator()(Individual const& ind)const{
189  return ind.penalizedFitness();
190  }
191  };
192 
193  struct IndividualUnpenalizedFitnessFunctor{
194  template<class Individual>
195  typename Individual::FitnessType& operator()(Individual& ind)const{
196  return ind.unpenalizedFitness();
197  }
198  template<class Individual>
199  typename Individual::FitnessType const& operator()(Individual const& ind)const{
200  return ind.unpenalizedFitness();
201  }
202  };
203 
204  struct IndividualSearchPointFunctor{
205  template<class Individual>
207  return ind.unpenalizedFitness();
208  }
209  template<class Individual>
210  typename Individual::SearchPointType const& operator()(Individual const& ind)const{
211  return ind.searchPoint();
212  }
213  };
214 
215  struct IndividualRankFunctor{
216  template<class Individual>
217  unsigned int& operator()(Individual& ind)const{
218  return ind.rank();
219  }
220  template<class Individual>
221  unsigned int operator()(Individual const& ind)const{
222  return ind.rank();
223  }
224  };
225 }
226 
227 template<class IndividualRange>
228 auto penalizedFitness(IndividualRange& range) -> decltype(
229  boost::adaptors::transform(range,detail::IndividualPenalizedFitnessFunctor())
230 ){
231  return boost::adaptors::transform(range,detail::IndividualPenalizedFitnessFunctor());
232 }
233 
234 template<class IndividualRange>
235 auto unpenalizedFitness(IndividualRange& range) -> decltype(
236  boost::adaptors::transform(range,detail::IndividualUnpenalizedFitnessFunctor())
237 ){
238  return boost::adaptors::transform(range,detail::IndividualUnpenalizedFitnessFunctor());
239 }
240 
241 template<class IndividualRange>
242 auto ranks(IndividualRange& range) -> decltype(
243  boost::adaptors::transform(range,detail::IndividualRankFunctor())
244 ){
245  return boost::adaptors::transform(range,detail::IndividualRankFunctor());
246 }
247 
248 
249 template<class IndividualRange>
250 auto searchPoint(IndividualRange& range) -> decltype(
251  boost::adaptors::transform(range,detail::IndividualSearchPointFunctor())
252 ){
253  return boost::adaptors::transform(range,detail::IndividualSearchPointFunctor());
254 }
255 
256 }
257 #endif