Free cookie consent management tool by TermsFeed Policy Generator

source: branches/MOCMAEvolutionStrategy/HeuristicLab.Algorithms.MOCMAEvolutionStrategy/3.3/MocmaesIndividual.cs @ 14404

Last change on this file since 14404 was 14404, checked in by bwerth, 7 years ago

#2592 several fixes and cleanups to adapt a more HeuristicLab-Code-Style + renaming of folders and Plugin

File size: 6.4 KB
Line 
1using System;
2using System.Linq;
3using HeuristicLab.Algorithms.MOCMAEvolutionStrategy;
4using HeuristicLab.Common;
5using HeuristicLab.Encodings.RealVectorEncoding;
6using HeuristicLab.Random;
7
8namespace HeuristicLab.Algorithms.CMAEvolutionStrategy {
9  internal class MOCMAESIndividual {
10    public const int Success = 1;
11    public const int NoSuccess = 2;
12    public const int Failure = 3;
13
14    //MOCMAES-Params
15    private readonly MOCMAESParameters strategy;
16
17    //Chromosome
18    public RealVector Mean { get; private set; }
19    private double sigma;//stepsize
20    private RealVector evolutionPath; // pc
21    private RealVector lastStep;
22    private RealVector lastZ;
23    private double[,] lowerCholesky;
24
25
26    //Phenotype
27    public double[] Fitness { get; set; }
28    public double[] PenalizedFitness { get; set; }
29    public bool Selected { get; set; }
30    public double Rank { get; set; }
31    public double SuccessProbability { get; set; }
32
33    /// <summary>
34    ///
35    /// </summary>
36    /// <param name="mean">has to be 0-vector with correct lenght</param>
37    /// <param name="pSucc">has to be ptargetsucc</param>
38    /// <param name="sigma">initialSigma</param>
39    /// <param name="pc">has to be 0-vector with correct lenght</param>
40    /// <param name="c">has to be a symmetric positive definit Covariance matrix</param>
41    public MOCMAESIndividual(RealVector mean, double pSucc, double sigma, RealVector pc, double[,] c, MOCMAESParameters strategy) {
42      Mean = mean;
43      SuccessProbability = pSucc;
44      this.sigma = sigma;
45      evolutionPath = pc;
46      CholeskyDecomposition(c);
47      Selected = true;
48      this.strategy = strategy;
49    }
50
51    private void CholeskyDecomposition(double[,] c) {
52      if (!alglib.spdmatrixcholesky(ref c, c.GetLength(0), false))
53        throw new ArgumentException("Covariancematrix is not symmetric positiv definit");
54      lowerCholesky = (double[,])c.Clone();
55    }
56
57    public MOCMAESIndividual(MOCMAESIndividual other) {
58      SuccessProbability = other.SuccessProbability;
59      sigma = other.sigma;
60      evolutionPath = (RealVector)other.evolutionPath.Clone();
61      Mean = (RealVector)other.Mean.Clone();
62      lowerCholesky = (double[,])other.lowerCholesky.Clone();
63      Selected = true;
64      strategy = other.strategy;
65    }
66
67    public void UpdateEvolutionPath(double learningRate, double updateWeight) {
68      updateWeight = Math.Sqrt(updateWeight);
69      for (var i = 0; i < evolutionPath.Length; i++) {
70        evolutionPath[i] *= learningRate;
71        evolutionPath[i] += updateWeight * lastStep[i];
72      }
73    }
74
75    public double GetNormSqr() {
76      return lastZ.Sum(d => d * d);
77    }
78
79    private void CholeskyUpdate(RealVector v, double alpha, double beta) {
80      var n = v.Length;
81      var temp = new double[n];
82      for (var i = 0; i < n; i++) temp[i] = v[i];
83      double betaPrime = 1;
84      var a = Math.Sqrt(alpha);
85      for (var j = 0; j < n; j++) {
86        var ljj = a * lowerCholesky[j, j];
87        var dj = ljj * ljj;
88        var wj = temp[j];
89        var swj2 = beta * wj * wj;
90        var gamma = dj * betaPrime + swj2;
91        var x1 = dj + swj2 / betaPrime;
92        if (x1 < 0.0) throw new ArgumentException("Update makes Covariancematrix indefinite");
93        var nLjj = Math.Sqrt(x1);
94        lowerCholesky[j, j] = nLjj;
95        betaPrime += swj2 / dj;
96        if (j + 1 >= n) continue;
97        for (var i = j + 1; i < n; i++) lowerCholesky[i, j] *= a;
98        for (var i = j + 1; i < n; i++) temp[i] = wj / ljj * lowerCholesky[i, j];
99        if (gamma.IsAlmost(0)) continue;
100        for (var i = j + 1; i < n; i++) lowerCholesky[i, j] *= nLjj / ljj;
101        for (var i = j + 1; i < n; i++) lowerCholesky[i, j] += nLjj * beta * wj / gamma * temp[i];
102
103      }
104
105    }
106
107    public void Mutate(NormalDistributedRandom gauss) {
108      //sampling a random z from N(0,I) where I is the Identity matrix;
109      lastZ = new RealVector(Mean.Length);
110      var n = lastZ.Length;
111      for (var i = 0; i < n; i++) lastZ[i] = gauss.NextDouble();
112      //Matrixmultiplication: lastStep = lowerCholesky * lastZ;
113      lastStep = new RealVector(Mean.Length);
114      for (var i = 0; i < n; i++) {
115        double sum = 0;
116        for (var j = 0; j <= i; j++) sum += lowerCholesky[i, j] * lastZ[j];
117        lastStep[i] = sum;
118      }
119      //add the step to x weighted by stepsize;
120      for (var i = 0; i < Mean.Length; i++) Mean[i] += sigma * lastStep[i];
121    }
122
123    public void UpdateAsParent(int v) {
124      SuccessProbability = (1 - strategy.StepSizeLearningRate) * SuccessProbability + strategy.StepSizeLearningRate * (v == Success ? 1 : 0);
125      sigma *= Math.Exp(1 / strategy.StepSizeDampeningFactor * (SuccessProbability - strategy.TargetSuccessProbability) / (1 - strategy.TargetSuccessProbability));
126      if (v != Failure) return;
127      if (SuccessProbability < strategy.SuccessThreshold) {
128        var stepNormSqr = GetNormSqr();
129        var rate = strategy.CovarianceMatrixUnlearningRate;
130        if (stepNormSqr > 1 && 1 < strategy.CovarianceMatrixUnlearningRate * (2 * stepNormSqr - 1)) {
131          rate = 1 / (2 * stepNormSqr - 1);
132        }
133        CholeskyUpdate(lastStep, 1 + rate, -rate);
134      } else {
135        RoundUpdate();
136      }
137
138    }
139
140    public void UpdateAsOffspring() {
141      SuccessProbability = (1 - strategy.StepSizeLearningRate) * SuccessProbability + strategy.StepSizeLearningRate;
142      sigma *= Math.Exp(1 / strategy.StepSizeDampeningFactor * (SuccessProbability - strategy.TargetSuccessProbability) / (1 - strategy.TargetSuccessProbability));
143      var evolutionpathUpdateWeight = strategy.EvolutionPathLearningRate * (2.0 - strategy.EvolutionPathLearningRate);
144      if (SuccessProbability < strategy.SuccessThreshold) {
145        UpdateEvolutionPath(1 - strategy.EvolutionPathLearningRate, evolutionpathUpdateWeight);
146        CholeskyUpdate(evolutionPath, 1 - strategy.CovarianceMatrixLearningRate, strategy.CovarianceMatrixLearningRate);
147      } else {
148        RoundUpdate();
149      }
150    }
151
152    private void RoundUpdate() {
153      var evolutionPathUpdateWeight = strategy.EvolutionPathLearningRate * (2.0 - strategy.EvolutionPathLearningRate);
154      UpdateEvolutionPath(1 - strategy.EvolutionPathLearningRate, 0);
155      CholeskyUpdate(evolutionPath, 1 - strategy.CovarianceMatrixLearningRate + evolutionPathUpdateWeight, strategy.CovarianceMatrixLearningRate);
156    }
157
158  }
159
160}
Note: See TracBrowser for help on using the repository browser.