28 #ifndef SHARK_ALGORITHMS_DIRECT_SEARCH_VD_CMA_H 29 #define SHARK_ALGORITHMS_DIRECT_SEARCH_VD_CMA_H 54 double chi( std::size_t n ) {
55 return( std::sqrt( static_cast<double>( n ) )*(1. - 1./(4.*n) + 1./(21.*n*n)) );
66 {
return "VDCMA-ES"; }
70 return unsigned( 4. + ::floor( 3. * ::log( static_cast<double>( dimension ) ) ) );
85 double sigma = m_initialSigma;
86 if(m_initialSigma == 0)
87 sigma = 1.0/std::sqrt(
double(p.size()));
106 m_numberOfVariables =
function.numberOfVariables();
109 m_sigma = initialSigma;
111 m_mean = blas::repeat(0.0,m_numberOfVariables);
112 m_vn.resize(m_numberOfVariables);
113 for(std::size_t i = 0; i != m_numberOfVariables;++i){
114 m_vn(i) =
random::uni(*mpe_rng,0,1.0/m_numberOfVariables);
116 m_normv = norm_2(m_vn);
119 m_D = blas::repeat(1.0,m_numberOfVariables);
120 m_evolutionPathC = blas::repeat(0.0,m_numberOfVariables);
121 m_evolutionPathSigma = blas::repeat(0.0,m_numberOfVariables);
124 m_mean = initialSearchPoint;
131 m_weights.resize(m_mu);
132 for (std::size_t i = 0; i < m_mu; i++){
133 m_weights(i) = ::log(mu + 0.5) - ::log(1. + i);
135 m_weights /= sum(m_weights);
138 m_muEff = 1. / sum(
sqr(m_weights));
139 m_cSigma = 0.5/(1+std::sqrt(m_numberOfVariables/m_muEff));
140 m_dSigma = 1. + 2. * std::max(0., std::sqrt((m_muEff-1.)/(m_numberOfVariables+1)) - 1.) + m_cSigma;
142 m_cC = (4. + m_muEff / m_numberOfVariables) / (m_numberOfVariables + 4. + 2 * m_muEff / m_numberOfVariables);
143 double correction = (m_numberOfVariables - 5.0)/6.0;
144 m_c1 = correction*2 / (
sqr(m_numberOfVariables + 1.3) + m_muEff);
145 m_cMu = std::min(1. - m_c1, correction* 2 * (m_muEff - 2. + 1./m_muEff) / (
sqr(m_numberOfVariables + 2) + m_muEff));
151 std::vector< IndividualType > offspring( m_lambda );
154 for( std::size_t i = 0; i < offspring.size(); i++ ) {
155 createSample(offspring[i].
searchPoint(),offspring[i].chromosome());
157 penalizingEvaluator(
function, offspring.begin(), offspring.end() );
160 std::vector< IndividualType > parents( m_mu );
162 selection(offspring.begin(),offspring.end(),parents.begin(), parents.end());
165 updateStrategyParameters( parents );
189 m_initialSigma = initialSigma;
194 RealVector
const&
mean()
const {
205 return m_evolutionPathC;
210 return m_evolutionPathSigma;
214 std::size_t
mu()
const {
238 RealVector m( m_numberOfVariables, 0. );
239 RealVector z( m_numberOfVariables, 0. );
241 for( std::size_t j = 0; j < offspring.size(); j++ ){
242 noalias(m) += m_weights( j ) * offspring[j].searchPoint();
243 noalias(z) += m_weights( j ) * offspring[j].chromosome();
247 double b=(1/std::sqrt(1+
sqr(m_normv))-1);
248 noalias(z)+= b*inner_prod(z,m_vn)*m_vn;
251 noalias(m_evolutionPathSigma) = (1. - m_cSigma)*m_evolutionPathSigma + std::sqrt( m_cSigma * (2. - m_cSigma) * m_muEff ) * z;
253 double hSigLHS = norm_2( m_evolutionPathSigma ) / std::sqrt(1. - pow((1 - m_cSigma), 2.*(m_counter+1)));
254 double hSigRHS = (1.4 + 2 / (m_numberOfVariables+1.)) * chi( m_numberOfVariables );
256 if(hSigLHS < hSigRHS) hSig = 1.;
257 noalias(m_evolutionPathC) = (1. - m_cC ) * m_evolutionPathC + hSig * std::sqrt( m_cC * (2. - m_cC) * m_muEff ) * (m - m_mean) / m_sigma;
266 RealVector meanS(m_numberOfVariables,0.0);
267 RealVector meanT(m_numberOfVariables,0.0);
268 for(std::size_t j = 0; j !=
mu(); ++j){
269 computeSAndTFirst(offspring[j].chromosome(),meanS,meanT,m_cMu*m_weights(j));
271 computeSAndTFirst(m_evolutionPathC/m_D,meanS,meanT,hSig*m_c1);
274 computeSAndTSecond(meanS,meanT);
277 noalias(m_D) += m_D*meanS;
278 noalias(m_vn) = m_vn*m_normv+meanT/m_normv;
280 m_normv = norm_2(m_vn);
284 m_sigma *= std::exp( (m_cSigma / m_dSigma) * (norm_2(m_evolutionPathSigma)/ chi( m_numberOfVariables ) - 1.) );
292 void createSample(RealVector& x,RealVector& y)
const{
293 x.resize(m_numberOfVariables);
294 y.resize(m_numberOfVariables);
295 for(std::size_t i = 0; i != m_numberOfVariables; ++i){
298 double a = std::sqrt(1+
sqr(m_normv))-1;
299 a *= inner_prod(y,m_vn);
301 noalias(x) = m_mean+ m_sigma*m_D*y;
307 void computeSAndTFirst(RealVector
const& y, RealVector& s,RealVector& t,
double weight )
const{
308 if(weight == 0)
return;
309 double yvn = inner_prod(y,m_vn);
310 double normv2 =
sqr(m_normv);
311 double gammav = 1+normv2;
313 noalias(s) += weight*(
sqr(y) - (normv2/gammav*yvn)*(y*m_vn)- 1.0);
315 noalias(t) += weight*(yvn*y - 0.5*(
sqr(yvn)+gammav)*m_vn);
319 void computeSAndTSecond(RealVector& s,RealVector& t)
const{
320 RealVector vn2 = m_vn*m_vn;
321 double normv2 =
sqr(m_normv);
322 double gammav = 1+normv2;
324 double alpha =
sqr(normv2)+(2*gammav - std::sqrt(gammav))/max(vn2);
325 alpha=std::sqrt(alpha);
327 alpha = std::min(alpha,1.0);
329 double b=-(1-
sqr(alpha))*
sqr(normv2)/gammav+2*
sqr(alpha);
330 RealVector A= 2.0 - (b+2*
sqr(alpha))*vn2;
331 RealVector invAvn2= vn2/A;
334 noalias(s) -= alpha/gammav*((2+normv2)*(m_vn*t)-normv2*inner_prod(m_vn,t)*vn2);
336 noalias(s) = s/A -b*inner_prod(s,invAvn2)/(1+b*inner_prod(vn2,invAvn2))*invAvn2;
338 noalias(t) -= alpha*((2+normv2)*(m_vn*s)-inner_prod(s,vn2)*m_vn);
341 std::size_t m_numberOfVariables;
343 std::size_t m_lambda;
345 double m_initialSigma;
355 RealVector m_weights;
357 RealVector m_evolutionPathC;
358 RealVector m_evolutionPathSigma;
369 random::rng_type* mpe_rng;