ReferenceVectorGuidedSelection.h
Go to the documentation of this file.
1 //===========================================================================
2 /*!
3  *
4  *
5  * \brief Implements the reference vector selection for RVEA
6  *
7  * \author Bjoern Bugge Grathwohl
8  * \date March 2017
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 //===========================================================================
31 
32 #ifndef SHARK_ALGORITHMS_DIRECT_SEARCH_OPERATORS_SELECTION_REFERENCE_VECTOR_GUIDED_SELECTION_H
33 #define SHARK_ALGORITHMS_DIRECT_SEARCH_OPERATORS_SELECTION_REFERENCE_VECTOR_GUIDED_SELECTION_H
34 
35 #include <shark/LinAlg/Base.h>
37 
38 namespace shark {
39 
40 /**
41  * \brief Implements the reference vector selection for the RVEA algorithm.
42  *
43  * This selector uses a set of unit reference vectors to partition the search
44  * space by assigning to each reference vector the individual that is "closest"
45  * to it, as measured by the angle-penalized distance.
46  * See below paper for details:
47  * R. Cheng, Y. Jin, M. Olhofer, and B. Sendhoff, “A reference vector guided
48  * evolutionary algorithm for many-objective optimization,” IEEE Transactions on
49  * Evolutionary Computation, Vol 20, Issue 5, October 2016
50  * http://dx.doi.org/10.1109/TEVC.2016.2519378
51  */
52 template <typename IndividualType>
54 {
55  typedef std::set<std::size_t> bag_t;
56 
57  /**
58  * \brief Select individuals by marking them as "selected".
59  *
60  * The selection operator requires the set of reference vectors, the set of
61  * least angles between reference vectors (the gammas), as well as the
62  * current iteration number.
63  */
64  void operator()(
65  std::vector<IndividualType> & population,
66  RealMatrix const & referenceVectors,
67  RealVector const & gammas,
68  std::size_t const curIteration)
69  {
70  if(population.empty())
71  {
72  return;
73  }
74  RealMatrix fitness = extractPopulationFitness(population);
75  SIZE_CHECK(fitness.size2() == referenceVectors.size2());
76  const std::size_t groupCount = referenceVectors.size1();
77  // Objective value translation
78  // line 4
79  const RealVector minFitness = minCol(fitness);
80  // line 5-7
81  fitness -= repeat(minFitness, fitness.size1());
82 
83  // Population partition
84  // line 9-13
85  const RealMatrix cosA = cosAngles(fitness, referenceVectors);
86  const RealMatrix angles = acos(cosA);
87  // line 14-17
88  const std::vector<bag_t> subGroups = populationPartition(cosA);
89  SIZE_CHECK(subGroups.size() == groupCount);
90  // Elitism selection
91  for(auto & p : population)
92  {
93  p.selected() = false;
94  }
95  const double theta = fitness.size2()
96  * std::pow(static_cast<double>(curIteration) /
97  static_cast<double>(m_maxIters), m_alpha);
98  // line 25-28
99  for(std::size_t j = 0; j < groupCount; ++j)
100  {
101  if(subGroups[j].size() == 0)
102  {
103  continue;
104  }
105  std::size_t selected_idx = 0;
106  double min = 1e5;
107  for(std::size_t i : subGroups[j])
108  {
109  // Angle-penalized distance (APD) calculation
110  double apd = 1 + theta * angles(i, j) / gammas[j];
111  apd *= norm_2(row(fitness, i));
112  if(apd < min)
113  {
114  selected_idx = i;
115  min = apd;
116  }
117  }
118  population[selected_idx].selected() = true;
119  }
120  }
121 
122  /**
123  * \brief Associates a population to a set of reference vectors.
124  *
125  * The parameter is an N-by-M matrix where N is the population size and M is
126  * the number of reference vectors. Entry (i,j) is the cosine of the angle
127  * between population i and reference vector j.
128  */
129  static std::vector<bag_t> populationPartition(
130  RealMatrix const & cosAngles)
131  {
132  std::vector<std::set<std::size_t>> subGroups(cosAngles.size2());
133  for(std::size_t i = 0; i < cosAngles.size1(); ++i)
134  {
135  const std::size_t k = std::distance(
136  row(cosAngles, i).begin(),
137  std::max_element(row(cosAngles, i).begin(),
138  row(cosAngles, i).end()));
139  subGroups[k].insert(i);
140  }
141  return subGroups;
142  }
143 
144  static RealMatrix extractPopulationFitness(
145  std::vector<IndividualType> const & population)
146  {
147  RealMatrix fitness(population.size(),
148  population[0].unpenalizedFitness().size());
149  for(std::size_t i = 0; i < population.size(); ++i)
150  {
151  row(fitness, i) = population[i].unpenalizedFitness();
152  }
153  return fitness;
154  }
155 
156  static RealVector minCol(RealMatrix const & m)
157  {
158  RealVector minColumns(m.size2());
159  for(std::size_t i = 0; i < m.size2(); ++i)
160  {
161  minColumns[i] = min(column(m, i));
162  }
163  return minColumns;
164  }
165 
166  /**
167  * \brief Compute cosine of angles between all row vectors in two matrices.
168  */
169  static RealMatrix cosAngles(RealMatrix const & m1, RealMatrix const & m2)
170  {
171  RealMatrix c = prod(m1, trans(m2));
172  for(std::size_t i = 0; i < c.size1(); ++i)
173  {
174  row(c, i) /= norm_2(row(m1, i));
175  }
176  return c;
177  }
178 
179  template <typename Archive>
180  void serialize(Archive & archive)
181  {
182  archive & BOOST_SERIALIZATION_NVP(m_alpha);
183  archive & BOOST_SERIALIZATION_NVP(m_maxIters);
184  }
185 
186  double m_alpha;
187  std::size_t m_maxIters;
188 };
189 
190 } // namespace shark
191 
192 #endif // SHARK_ALGORITHMS_DIRECT_SEARCH_OPERATORS_SELECTION_REFERENCE_VECTOR_GUIDED_SELECTION_H