CMA.h
Go to the documentation of this file.
1 //===========================================================================
2 /*!
3  *
4  *
5  * \brief Implements the most recent version of the non-elitist CMA-ES.
6  *
7  * Hansen, N. The CMA Evolution Startegy: A Tutorial, June 28, 2011
8  * and the eqation numbers refer to this publication (retrieved April 2014).
9  *
10  *
11  * \author Thomas Voss and Christian Igel
12  * \date April 2014
13  *
14  * \par Copyright 1995-2017 Shark Development Team
15  *
16  * <BR><HR>
17  * This file is part of Shark.
18  * <http://shark-ml.org/>
19  *
20  * Shark is free software: you can redistribute it and/or modify
21  * it under the terms of the GNU Lesser General Public License as published
22  * by the Free Software Foundation, either version 3 of the License, or
23  * (at your option) any later version.
24  *
25  * Shark is distributed in the hope that it will be useful,
26  * but WITHOUT ANY WARRANTY; without even the implied warranty of
27  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
28  * GNU Lesser General Public License for more details.
29  *
30  * You should have received a copy of the GNU Lesser General Public License
31  * along with Shark. If not, see <http://www.gnu.org/licenses/>.
32  *
33  */
34 //===========================================================================
35 
36 
37 #ifndef SHARK_ALGORITHMS_DIRECT_SEARCH_CMA_H
38 #define SHARK_ALGORITHMS_DIRECT_SEARCH_CMA_H
39 
40 #include <shark/Core/DLLSupport.h>
44 
45 
46 namespace shark {
47 /// \brief Implements the CMA-ES.
48 ///
49 /// The algorithm is described in
50 ///
51 /// Hansen, N., S. Kern (2004). Evaluating the CMA Evolution Strategy
52 /// on Multimodal Test Functions. In Proceedings of the Eighth
53 /// International Conference on Parallel Problem Solving from Nature
54 /// (PPSN VIII), pp. 282-291, LNCS, Springer-Verlag
55 ///
56 /// For noisy function, noise handling is supported using the
57 /// noise level detection algorithm described in
58 /// Hansen, N., et al. "A method for handling uncertainty in evolutionary
59 /// optimization with an application to feedback control of combustion."
60 /// IEEE Transactions on Evolutionary Computation 13.1 (2009): 180-197.
61 /// Our implementation varies in small details, e.g. instead of the average rank
62 /// the rank of the average function value is used for updating the strategy parameters
63 /// which ensures asymptotic unbiasedness. We further do not have an upper bound on
64 /// the number of reevaluations for the same reason.
65 class CMA : public AbstractSingleObjectiveOptimizer<RealVector >
66 {
67 public:
68  /// \brief Models the recombination type.
70  EQUAL = 0,
71  LINEAR = 1,
73  };
74 
75  /// \brief Default c'tor.
76  SHARK_EXPORT_SYMBOL CMA(random::rng_type& rng = random::globalRng);
77 
78  /// \brief From INameable: return the class name.
79  std::string name() const
80  { return "CMA-ES"; }
81 
82  /// \brief Calculates lambda for the supplied dimensionality n.
83  SHARK_EXPORT_SYMBOL static std::size_t suggestLambda( std::size_t dimension ) ;
84 
85  /// \brief Calculates mu for the supplied lambda and the recombination strategy.
86  SHARK_EXPORT_SYMBOL static std::size_t suggestMu( std::size_t lambda, RecombinationType recomb = SUPERLINEAR ) ;
87 
88  SHARK_EXPORT_SYMBOL void read( InArchive & archive );
89  SHARK_EXPORT_SYMBOL void write( OutArchive & archive ) const;
90 
92  /// \brief Initializes the algorithm for the supplied objective function.
93  SHARK_EXPORT_SYMBOL void init( ObjectiveFunctionType const& function, SearchPointType const& p);
94 
95  /// \brief Initializes the algorithm for the supplied objective function.
97  ObjectiveFunctionType const& function,
98  SearchPointType const& initialSearchPoint,
99  std::size_t lambda,
100  std::size_t mu,
101  double initialSigma,
102  const boost::optional< RealMatrix > & initialCovarianceMatrix = boost::optional< RealMatrix >()
103  );
104 
105  /// \brief Executes one iteration of the algorithm.
106  SHARK_EXPORT_SYMBOL void step(ObjectiveFunctionType const& function);
107 
108  /// \brief sets the initial step length sigma
109  ///
110  /// It is by default <=0 which means that sigma =1/sqrt(numVariables)
111  void setInitialSigma(double initSigma){
112  m_initSigma = initSigma;
113  }
114 
115  /// \brief Accesses the current step size.
116  double sigma() const {
117  return m_sigma;
118  }
119 
120  /// \brief Accesses the current population mean.
121  RealVector const& mean() const {
122  return m_mean;
123  }
124 
125  /// \brief Accesses the current weighting vector.
126  RealVector const& weights() const {
127  return m_weights;
128  }
129 
130  /// \brief Accesses the evolution path for the covariance matrix update.
131  RealVector const& evolutionPath() const {
132  return m_evolutionPathC;
133  }
134 
135  /// \brief Accesses the evolution path for the step size update.
136  RealVector const& evolutionPathSigma() const {
137  return m_evolutionPathSigma;
138  }
139 
140  /// \brief Accesses the covariance matrix of the normal distribution used for generating offspring individuals.
141  RealMatrix const& covarianceMatrix() const {
142  return m_mutationDistribution.covarianceMatrix();
143  }
144 
145  /// \brief Accesses the recombination type.
147  return m_recombinationType;
148  }
149 
150  ///\brief Returns a mutable reference to the recombination type.
152  return m_recombinationType;
153  }
154 
155  ///\brief Returns a const reference to the lower bound on sigma times smalles eigenvalue.
156  const double & lowerBound() const {
157  return m_lowerBound;
158  }
159 
160  ///\brief Set the lower bound on sigma times smalles eigenvalue.
161  void setLowerBound(double lowerBound) {
162  m_lowerBound = lowerBound;
163  }
164 
165  /// \brief Returns the size of the parent population \f$\mu\f$.
166  std::size_t mu() const {
167  return m_mu;
168  }
169 
170  /// \brief Sets the number of selected samples
171  void setMu(std::size_t mu){
172  m_mu = mu;
173  m_userSetMu = true;
174  }
175  /// \brief Sets the number of sampled points
176  void setLambda(std::size_t lambda){
177  m_lambda = lambda;
178  m_userSetLambda = true;
179  }
180 
181  ///\brief Returns a immutable reference to the size of the offspring population \f$\mu\f$.
182  std::size_t lambda()const{
183  return m_lambda;
184  }
185 
186  /// \brief Returns eigenvectors of covariance matrix (not considering step size)
187  RealMatrix const& eigenVectors() const {
188  return m_mutationDistribution.eigenVectors();
189  }
190 
191  ///\brief Returns a eigenvectors of covariance matrix (not considering step size)
192  RealVector const& eigenValues() const {
193  return m_mutationDistribution.eigenValues();
194  }
195 
196  ///\brief Returns condition of covariance matrix
197  double condition() const {
198  RealVector const& eigenValues = m_mutationDistribution.eigenValues();
199  return max(eigenValues)/min(eigenValues);
200  }
201 
202  ///\brief Returns how often a point is evaluated
203  std::size_t numberOfEvaluations()const{
204  return m_numEvaluations;
205  }
206 
207 
208 protected:
209  /// \brief The type of individual used for the CMA
211 
212  /// \brief Samples lambda individuals from the search distribution
213  SHARK_EXPORT_SYMBOL std::vector<IndividualType> generateOffspring( ) const;
214 
215  /// \brief Updates the strategy parameters based on the supplied offspring population.
216  SHARK_EXPORT_SYMBOL void updatePopulation( std::vector<IndividualType > const& offspring ) ;
217 
219  std::vector<SearchPointType> const& points,
220  std::vector<ResultType> const& functionValues,
221  std::size_t lambda,
222  std::size_t mu,
223  double initialSigma
224  );
225 private:
226 
227  std::size_t m_numberOfVariables; ///< Stores the dimensionality of the search space.
228  std::size_t m_mu; ///< The size of the parent population.
229  std::size_t m_lambda; ///< The size of the offspring population, needs to be larger than mu.
230 
231  bool m_userSetMu; /// <The user set a value via setMu, do not overwrite with default
232  bool m_userSetLambda; /// <The user set a value via setMu, do not overwrite with default
233  double m_initSigma; ///< use provided initial value of sigma<=0 =>algorithm chooses
234 
235  RecombinationType m_recombinationType; ///< Stores the recombination type.
236 
237 
238  double m_sigma;
239  double m_cC;
240  double m_c1;
241  double m_cMu;
242  double m_cSigma;
243  double m_dSigma;
244  double m_muEff;
245 
246  double m_lowerBound;
247 
248  RealVector m_mean;
249  RealVector m_weights;
250 
251  RealVector m_evolutionPathC;
252  RealVector m_evolutionPathSigma;
253 
254  std::size_t m_counter; ///< counter for generations
255 
256  std::size_t m_numEvaluations;
257  double m_numEvalIncreaseFactor;
258  double m_rLambda;
259  double m_rankChangeQuantile;
260 
261  MultiVariateNormalDistribution m_mutationDistribution;
262  random::rng_type* mpe_rng;
263 };
264 }
265 
266 #endif