IndicatorBasedSelection.h
Go to the documentation of this file.
1/*!
2 *
3 *
4 * \brief Indicator-based selection strategy for multi-objective selection.
5 *
6 *
7 *
8 * \author T.Voss
9 * \date 2010
10 *
11 *
12 * \par Copyright 1995-2017 Shark Development Team
13 *
14 * <BR><HR>
15 * This file is part of Shark.
16 * <https://shark-ml.github.io/Shark/>
17 *
18 * Shark is free software: you can redistribute it and/or modify
19 * it under the terms of the GNU Lesser General Public License as published
20 * by the Free Software Foundation, either version 3 of the License, or
21 * (at your option) any later version.
22 *
23 * Shark is distributed in the hope that it will be useful,
24 * but WITHOUT ANY WARRANTY; without even the implied warranty of
25 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
26 * GNU Lesser General Public License for more details.
27 *
28 * You should have received a copy of the GNU Lesser General Public License
29 * along with Shark. If not, see <http://www.gnu.org/licenses/>.
30 *
31 */
32#ifndef SHARK_ALGORITHMS_DIRECT_SEARCH_OPERATORS_SELECTION_INDICATOR_BASED_SELECTION_H
33#define SHARK_ALGORITHMS_DIRECT_SEARCH_OPERATORS_SELECTION_INDICATOR_BASED_SELECTION_H
34
36
37#include <map>
38#include <vector>
39
40namespace shark {
41
42/**
43* \brief Implements the well-known indicator-based selection strategy.
44*
45* See
46* Kalyanmoy Deb and Amrit Pratap and Sameer Agarwal and T. Meyarivan,
47* A Fast Elitist Multi-Objective Genetic Algorithm: NSGA-II,
48* IEEE Transactions on Evolutionary Computation
49* Year 2000, Volume 6, p. 182-197
50*
51* \tparam Indicator The second-level sorting criterion.
52*/
53template<typename Indicator>
55 /**
56 * \brief Executes the algorithm and assigns each member of the population
57 * its level non-dominance (rank) and its individual contribution to the front
58 * it belongs to (share).
59 *
60 * \param [in,out] population The population to be ranked.
61 * \param [in,out] mu the number of individuals to select
62 */
63 template<typename PopulationType>
64 void operator()( PopulationType & population, std::size_t mu ){
65 if(population.empty()) return;
66
67 //perform a nondominated sort to assign the rank to every element
68 nonDominatedSort(penalizedFitness(population), ranks(population));
69
70 typedef std::vector< view_reference<typename PopulationType::value_type > > View;
71
72 unsigned int maxRank = 0;
73 std::map< unsigned int, View > fronts;
74
75 for( unsigned int i = 0; i < population.size(); i++ ) {
76 maxRank = std::max( maxRank, population[i].rank());
77 fronts[population[i].rank()].push_back( population[i] );
78 population[i].selected() = true;
79 }
80
81 //deselect the highest rank fronts until we would end up with less or equal mu elements
82 unsigned int rank = maxRank;
83 std::size_t popSize = population.size();
84
85 while(popSize-fronts[rank].size() >= mu){
86 //deselect all elements in this front
87 View & front = fronts[rank];
88 for(std::size_t i = 0; i != front.size(); ++i){
89 front[i].selected() = false;
90 }
91 popSize -= front.size();
92 --rank;
93 }
94 //now use the indicator to deselect the worst approximating elements of the last selected front
95 View& front = fronts[rank];
96
97 //create an archive of points which are surely selected because of their domination rank
98 View archive;
99 archive.reserve(popSize - front.size());
100 for(unsigned int r = 1; r != rank; ++r){
101 archive.insert(archive.end(),fronts[r].begin(), fronts[r].end());
102 }
103 //deselect
104 std::vector<std::size_t> deselected = m_indicator.leastContributors(penalizedFitness(front),penalizedFitness(archive), popSize - mu);
105 for(auto lc:deselected){
106 front[lc].selected() = false;
107 }
108 }
109
110 /**
111 * \brief Stores/restores the serializer's state.
112 * \tparam Archive Type of the archive.
113 * \param [in,out] archive The archive to serialize to.
114 * \param [in] version number, currently unused.
115 */
116 template<typename Archive>
117 void serialize( Archive & archive, const unsigned int version )
118 {
119 archive & BOOST_SERIALIZATION_NVP( m_indicator );
120 }
121 Indicator& indicator(){
122 return m_indicator;
123 }
124 Indicator const& indicator()const{
125 return m_indicator;
126 }
127private:
128 Indicator m_indicator; ///< Instance of the second level sorting criterion.
129
130 /** \cond */
131 template<typename T>
132 struct view_reference {
133 T * mep_value;
134 public:
135 typedef RealVector FitnessType;
136
137 view_reference() : mep_value( NULL ){}
138 view_reference(T & value) : mep_value( &value ){}
139
140 operator T & ()
141 {
142 return( *mep_value );
143 }
144
145 operator const T & () const
146 {
147 return( *mep_value );
148 }
149
150 view_reference<T> operator=( const T & rhs )
151 {
152 *mep_value = rhs;
153 return *this;
154 }
155
156 RealVector& penalizedFitness() {
157 return mep_value->penalizedFitness();
158 }
159
160 RealVector& unpenalizedFitness(){
161 return mep_value->unpenalizedFitness();
162 }
163
164 RealVector const& penalizedFitness() const{
165 return mep_value->penalizedFitness();
166 }
167
168 RealVector const& unpenalizedFitness() const{
169 return mep_value->unpenalizedFitness();
170 }
171
172 bool& selected(){
173 return mep_value->selected();
174 }
175 };
176 /** \endcond */
177};
178}
179
180#endif