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 * <https://shark-ml.github.io/Shark/>
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
36namespace 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.
60template< typename PointType, class FitnessTypeT, class Chromosome = RealVector >
62public:
63
64 typedef FitnessTypeT FitnessType;
65
66 typedef PointType SearchPointType;
67
68 ///\brief Ordering relation by the ranks of the individuals
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.
92
93 /// \brief Returns a const reference to the search point that is associated with the individual.
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.
112
113 /// \brief Returns the unpenalized fitness of the individual.
116 }
117
118 /// \brief Returns a reference to the penalized fitness of the individual.
122 /// \brief Returns the unpenalized fitness of the individual.
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);
167 }
168
169protected:
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.
181namespace 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>
206 typename Individual::SearchPointType& operator()(Individual& ind)const{
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
227template<class IndividualRange>
228auto penalizedFitness(IndividualRange& range) -> decltype(
229 boost::adaptors::transform(range,detail::IndividualPenalizedFitnessFunctor())
230){
231 return boost::adaptors::transform(range,detail::IndividualPenalizedFitnessFunctor());
232}
233
234template<class IndividualRange>
235auto unpenalizedFitness(IndividualRange& range) -> decltype(
236 boost::adaptors::transform(range,detail::IndividualUnpenalizedFitnessFunctor())
237){
238 return boost::adaptors::transform(range,detail::IndividualUnpenalizedFitnessFunctor());
239}
240
241template<class IndividualRange>
242auto ranks(IndividualRange& range) -> decltype(
243 boost::adaptors::transform(range,detail::IndividualRankFunctor())
244){
245 return boost::adaptors::transform(range,detail::IndividualRankFunctor());
246}
247
248
249template<class IndividualRange>
250auto 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