RVEA.h
Go to the documentation of this file.
1 //===========================================================================
2 /*!
3  *
4  *
5  * \brief Implements the RVEA algorithm.
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_RVEA
33 #define SHARK_ALGORITHMS_DIRECT_SEARCH_RVEA
34 
35 #include <shark/Core/DLLSupport.h>
43 
44 namespace shark {
45 
46 /**
47  * \brief Implements the RVEA algorithm.
48  *
49  * Implementation of the RVEA algorithm from the following paper:
50  * R. Cheng, Y. Jin, M. Olhofer, and B. Sendhoff, “A reference vector guided
51  * evolutionary algorithm for many-objective optimization,” IEEE Transactions on
52  * Evolutionary Computation, Vol 20, Issue 5, October 2016
53  * http://dx.doi.org/10.1109/TEVC.2016.2519378
54  */
55 class RVEA : public AbstractMultiObjectiveOptimizer<RealVector>
56 {
57 public:
58  SHARK_EXPORT_SYMBOL RVEA(random::rng_type & rng = random::globalRng);
59 
60  std::string name() const{
61  return "RVEA";
62  }
63 
64  double crossoverProbability() const{
65  return m_crossoverProbability;
66  }
67 
69  return m_crossoverProbability;
70  }
71 
72  double nm() const{
73  return m_mutation.m_nm;
74  }
75 
76  double & nm(){
77  return m_mutation.m_nm;
78  }
79 
80  double nc() const{
81  return m_crossover.m_nc;
82  }
83 
84  double & nc(){
85  return m_crossover.m_nc;
86  }
87 
88  double alpha() const{
89  return m_selection.m_alpha;
90  }
91 
92  double & alpha(){
93  return m_selection.m_alpha;
94  }
95 
96  double adaptationFrequency() const{
97  return m_adaptParam;
98  }
99 
101  return m_adaptParam;
102  }
103 
104  /// \brief Size of parent population and number of reference vectors.
105  ///
106  /// In the RVEA algorithm, the exact mu value is determined by the
107  /// simplex-lattice design (Lattice.h), so the user cannot set it directly.
108  /// Instead, one must set the approxMu() value, which will be used as a
109  /// parameter in the lattice. If one wants to know the exact mu value, set
110  /// approxMu() to RVEA::suggestMu(n, m) where n is the objective dimension
111  /// and m is the approximate mu. Then the actual mu value will not be
112  /// changed in the initialization.
113  std::size_t mu() const{
114  return m_mu;
115  }
116 
117  std::size_t numInitPoints() const{
118  return m_mu;
119  }
120 
121  std::size_t approxMu() const{
122  return m_approxMu;
123  }
124 
125  std::size_t & approxMu(){
126  return m_approxMu;
127  }
128 
129  RealMatrix referenceVectors() const{
130  return m_referenceVectors;
131  }
132 
133  RealMatrix & referenceVectors(){
134  return m_referenceVectors;
135  }
136 
137  RealMatrix initialReferenceVectors() const{
138  return m_adaptation.m_initVecs;
139  }
140 
141  std::size_t maxIterations() const{
142  return m_selection.m_maxIters;
143  }
144 
145  std::size_t & maxIterations(){
146  return m_selection.m_maxIters;
147  }
148 
149  /// \brief True if the reference vectors will be adapted.
150  ///
151  /// Returns true if the algorithm will adapt the unit reference vectors in
152  /// the current iteration. This is controlled by the adaptationFreqency()
153  /// parameter; a value of, e.g., 0.2 will make the algorithm readapt
154  /// reference vectors every 20% of the iteration. Running the algorithm for
155  /// 1000 iterations will then make it readapt on iteration 0, 200, 400, etc.
157  return m_curIteration % static_cast<std::size_t>(
158  std::ceil(adaptationFrequency() * m_selection.m_maxIters)
159  ) == 0;
160  }
161 
162  template <typename Archive>
163  void serialize(Archive & archive){
164 #define S(var) archive & BOOST_SERIALIZATION_NVP(var)
165  S(m_crossoverProbability);
166  S(m_mu);
167  S(m_approxMu);
168  S(m_parents);
169  S(m_best);
170  S(m_crossover);
171  S(m_mutation);
172  S(m_adaptParam);
173  S(m_curIteration);
174  S(m_referenceVectors);
175  S(m_referenceVectorMinAngles);
176  S(m_selection);
177  S(m_adaptation);
178 #undef S
179  }
180 
183  ObjectiveFunctionType const& function,
184  std::vector<SearchPointType> const & initialSearchPoints
185  );
187  ObjectiveFunctionType const & function
188  );
189  SHARK_EXPORT_SYMBOL static std::size_t suggestMu(
190  std::size_t n, std::size_t const approx_mu);
191 protected:
194  std::vector<SearchPointType> const & initialSearchPoints,
195  std::vector<ResultType> const & functionValues,
196  RealVector const & lowerBounds,
197  RealVector const & upperBounds,
198  std::size_t const approx_mu,
199  double const nm,
200  double const nc,
201  double const crossover_prob,
202  double const alph,
203  double const fr,
204  std::size_t const max_iterations,
205  std::vector<Preference> const & referenceVectorsPreferences = std::vector<Preference>()
206  );
207 
208  SHARK_EXPORT_SYMBOL std::vector<IndividualType> generateOffspring() const;
210  std::vector<IndividualType> const & offspringvec
211  );
212 
213  std::vector<IndividualType> m_parents;
214 
215 private:
216  random::rng_type * m_rng;
217  double m_crossoverProbability; ///< Probability of crossover happening.
218  /// \brief Size of parent population
219  ///
220  /// It is also the number of reference vectors.
221  std::size_t m_mu;
222  /// \brief The "approximate" value of mu that the user asked for.
223  ///
224  /// The actual value of mu is determined via the simplex-lattice design for
225  /// the unit reference vectors. It will always be the same as
226  /// RVEA::suggestMu(n, m_approxMu) where n is the number of objectives.
227  std::size_t m_approxMu;
229  PolynomialMutator m_mutation;
230  /// \brief Hyperparameter controlling reference vector adaptation rate.
231  ///
232  /// A value of 0.2 makes the algorithm adapt the reference vectors every 20%
233  /// of the iterations. If the algorithm runs for a total of 1000 iterations,
234  /// they will be readjusted on iteration 0, 200, 400, etc. Is is called
235  /// "f_r" in the paper.
236  double m_adaptParam;
237  /// \brief Current iteration of the algorithm.
238  ///
239  /// The algorithm maintains knowledge of how long it has been running as
240  /// this is required by parts of the RVEA algorithm.
241  std::size_t m_curIteration;
242 
243  /// \brief The active set of unit reference vectors.
244  RealMatrix m_referenceVectors;
245  /// \brief Contains the minimum angles between reference vectors.
246  ///
247  /// For each reference vector i, position i in this vector is the smallest
248  /// angle between reference vector i and all the other reference vectors.
249  RealVector m_referenceVectorMinAngles;
252 };
253 
254 } // namespace shark
255 
256 #endif // SHARK_ALGORITHMS_DIRECT_SEARCH_RVEA