Free cookie consent management tool by TermsFeed Policy Generator

source: branches/2521_ProblemRefactoring/HeuristicLab.Algorithms.MOCMAEvolutionStrategy/3.3/MOCMAEvolutionStrategy.cs @ 17315

Last change on this file since 17315 was 17315, checked in by abeham, 4 years ago

#2521: reverted r17309

File size: 25.4 KB
Line 
1#region License Information
2/* HeuristicLab
3 * Copyright (C) Heuristic and Evolutionary Algorithms Laboratory (HEAL)
4 * and the BEACON Center for the Study of Evolution in Action.
5 *
6 * This file is part of HeuristicLab.
7 *
8 * HeuristicLab is free software: you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License as published by
10 * the Free Software Foundation, either version 3 of the License, or
11 * (at your option) any later version.
12 *
13 * HeuristicLab is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16 * GNU General Public License for more details.
17 *
18 * You should have received a copy of the GNU General Public License
19 * along with HeuristicLab. If not, see <http://www.gnu.org/licenses/>.
20 */
21#endregion
22
23using System;
24using System.Collections.Generic;
25using System.Linq;
26using System.Threading;
27using HEAL.Attic;
28using HeuristicLab.Analysis;
29using HeuristicLab.Common;
30using HeuristicLab.Core;
31using HeuristicLab.Data;
32using HeuristicLab.Encodings.RealVectorEncoding;
33using HeuristicLab.Optimization;
34using HeuristicLab.Parameters;
35using HeuristicLab.Random;
36
37namespace HeuristicLab.Algorithms.MOCMAEvolutionStrategy {
38  [Item("Multi-Objective CMA Evolution Strategy (MOCMAES)", "A multi objective evolution strategy based on covariance matrix adaptation. Code is based on 'Covariance Matrix Adaptation for Multi - objective Optimization' by Igel, Hansen and Roth")]
39  [Creatable(CreatableAttribute.Categories.PopulationBasedAlgorithms, Priority = 210)]
40  [StorableType("C10264E3-E4C6-4735-8E94-0DC116E8908D")]
41  public class MOCMAEvolutionStrategy : BasicAlgorithm {
42    public override Type ProblemType {
43      get { return typeof(MultiObjectiveProblem<RealVectorEncoding, RealVector>); }
44    }
45    public new MultiObjectiveProblem<RealVectorEncoding, RealVector> Problem {
46      get { return (MultiObjectiveProblem<RealVectorEncoding, RealVector>)base.Problem; }
47      set { base.Problem = value; }
48    }
49    public override bool SupportsPause {
50      get { return true; }
51    }
52
53    public RealVectorEncoding Encoding {
54      get { return Problem.Encoding; }
55    }
56
57    #region Storable fields
58    [Storable]
59    private IRandom random = new MersenneTwister();
60    [Storable]
61    private NormalDistributedRandom gauss;
62    [Storable]
63    private Individual[] solutions;
64    [Storable]
65    private double stepSizeLearningRate; //=cp learning rate in [0,1]
66    [Storable]
67    private double stepSizeDampeningFactor; //d
68    [Storable]
69    private double targetSuccessProbability; // p^target_succ
70    [Storable]
71    private double evolutionPathLearningRate; //cc
72    [Storable]
73    private double covarianceMatrixLearningRate; //ccov
74    [Storable]
75    private double covarianceMatrixUnlearningRate;
76    [Storable]
77    private double successThreshold; //ptresh
78    #endregion
79
80    #region ParameterNames
81    private const string MaximumRuntimeName = "Maximum Runtime";
82    private const string SeedName = "Seed";
83    private const string SetSeedRandomlyName = "SetSeedRandomly";
84    private const string PopulationSizeName = "PopulationSize";
85    private const string MaximumGenerationsName = "MaximumGenerations";
86    private const string MaximumEvaluatedSolutionsName = "MaximumEvaluatedSolutions";
87    private const string InitialSigmaName = "InitialSigma";
88    private const string IndicatorName = "Indicator";
89
90    private const string EvaluationsResultName = "Evaluations";
91    private const string IterationsResultName = "Generations";
92    private const string TimetableResultName = "Timetable";
93    private const string HypervolumeResultName = "Hypervolume";
94    private const string GenerationalDistanceResultName = "Generational Distance";
95    private const string InvertedGenerationalDistanceResultName = "Inverted Generational Distance";
96    private const string CrowdingResultName = "Crowding";
97    private const string SpacingResultName = "Spacing";
98    private const string CurrentFrontResultName = "Pareto Front";
99    private const string BestHypervolumeResultName = "Best Hypervolume";
100    private const string BestKnownHypervolumeResultName = "Best known hypervolume";
101    private const string DifferenceToBestKnownHypervolumeResultName = "Absolute Distance to BestKnownHypervolume";
102    private const string ScatterPlotResultName = "ScatterPlot";
103    #endregion
104
105    #region ParameterProperties
106    public IFixedValueParameter<IntValue> MaximumRuntimeParameter {
107      get { return (IFixedValueParameter<IntValue>)Parameters[MaximumRuntimeName]; }
108    }
109    public IFixedValueParameter<IntValue> SeedParameter {
110      get { return (IFixedValueParameter<IntValue>)Parameters[SeedName]; }
111    }
112    public FixedValueParameter<BoolValue> SetSeedRandomlyParameter {
113      get { return (FixedValueParameter<BoolValue>)Parameters[SetSeedRandomlyName]; }
114    }
115    public IFixedValueParameter<IntValue> PopulationSizeParameter {
116      get { return (IFixedValueParameter<IntValue>)Parameters[PopulationSizeName]; }
117    }
118    public IFixedValueParameter<IntValue> MaximumGenerationsParameter {
119      get { return (IFixedValueParameter<IntValue>)Parameters[MaximumGenerationsName]; }
120    }
121    public IFixedValueParameter<IntValue> MaximumEvaluatedSolutionsParameter {
122      get { return (IFixedValueParameter<IntValue>)Parameters[MaximumEvaluatedSolutionsName]; }
123    }
124    public IValueParameter<DoubleArray> InitialSigmaParameter {
125      get { return (IValueParameter<DoubleArray>)Parameters[InitialSigmaName]; }
126    }
127    public IConstrainedValueParameter<IIndicator> IndicatorParameter {
128      get { return (IConstrainedValueParameter<IIndicator>)Parameters[IndicatorName]; }
129    }
130    #endregion
131
132    #region Properties
133    public int MaximumRuntime {
134      get { return MaximumRuntimeParameter.Value.Value; }
135      set { MaximumRuntimeParameter.Value.Value = value; }
136    }
137    public int Seed {
138      get { return SeedParameter.Value.Value; }
139      set { SeedParameter.Value.Value = value; }
140    }
141    public bool SetSeedRandomly {
142      get { return SetSeedRandomlyParameter.Value.Value; }
143      set { SetSeedRandomlyParameter.Value.Value = value; }
144    }
145    public int PopulationSize {
146      get { return PopulationSizeParameter.Value.Value; }
147      set { PopulationSizeParameter.Value.Value = value; }
148    }
149    public int MaximumGenerations {
150      get { return MaximumGenerationsParameter.Value.Value; }
151      set { MaximumGenerationsParameter.Value.Value = value; }
152    }
153    public int MaximumEvaluatedSolutions {
154      get { return MaximumEvaluatedSolutionsParameter.Value.Value; }
155      set { MaximumEvaluatedSolutionsParameter.Value.Value = value; }
156    }
157    public DoubleArray InitialSigma {
158      get { return InitialSigmaParameter.Value; }
159      set { InitialSigmaParameter.Value = value; }
160    }
161    public IIndicator Indicator {
162      get { return IndicatorParameter.Value; }
163      set { IndicatorParameter.Value = value; }
164    }
165
166    public double StepSizeLearningRate {
167      get { return stepSizeLearningRate; }
168    }
169    public double StepSizeDampeningFactor {
170      get { return stepSizeDampeningFactor; }
171    }
172    public double TargetSuccessProbability {
173      get { return targetSuccessProbability; }
174    }
175    public double EvolutionPathLearningRate {
176      get { return evolutionPathLearningRate; }
177    }
178    public double CovarianceMatrixLearningRate {
179      get { return covarianceMatrixLearningRate; }
180    }
181    public double CovarianceMatrixUnlearningRate {
182      get { return covarianceMatrixUnlearningRate; }
183    }
184    public double SuccessThreshold {
185      get { return successThreshold; }
186    }
187    #endregion
188
189    #region ResultsProperties
190    private int ResultsEvaluations {
191      get { return ((IntValue)Results[EvaluationsResultName].Value).Value; }
192      set { ((IntValue)Results[EvaluationsResultName].Value).Value = value; }
193    }
194    private int ResultsIterations {
195      get { return ((IntValue)Results[IterationsResultName].Value).Value; }
196      set { ((IntValue)Results[IterationsResultName].Value).Value = value; }
197    }
198    #region Datatable
199    private DataTable ResultsQualities {
200      get { return (DataTable)Results[TimetableResultName].Value; }
201    }
202    private DataRow ResultsBestHypervolumeDataLine {
203      get { return ResultsQualities.Rows[BestHypervolumeResultName]; }
204    }
205    private DataRow ResultsHypervolumeDataLine {
206      get { return ResultsQualities.Rows[HypervolumeResultName]; }
207    }
208    private DataRow ResultsGenerationalDistanceDataLine {
209      get { return ResultsQualities.Rows[GenerationalDistanceResultName]; }
210    }
211    private DataRow ResultsInvertedGenerationalDistanceDataLine {
212      get { return ResultsQualities.Rows[InvertedGenerationalDistanceResultName]; }
213    }
214    private DataRow ResultsCrowdingDataLine {
215      get { return ResultsQualities.Rows[CrowdingResultName]; }
216    }
217    private DataRow ResultsSpacingDataLine {
218      get { return ResultsQualities.Rows[SpacingResultName]; }
219    }
220    private DataRow ResultsHypervolumeDifferenceDataLine {
221      get { return ResultsQualities.Rows[DifferenceToBestKnownHypervolumeResultName]; }
222    }
223    #endregion
224    //QualityIndicators
225    private double ResultsHypervolume {
226      get { return ((DoubleValue)Results[HypervolumeResultName].Value).Value; }
227      set { ((DoubleValue)Results[HypervolumeResultName].Value).Value = value; }
228    }
229    private double ResultsGenerationalDistance {
230      get { return ((DoubleValue)Results[GenerationalDistanceResultName].Value).Value; }
231      set { ((DoubleValue)Results[GenerationalDistanceResultName].Value).Value = value; }
232    }
233    private double ResultsInvertedGenerationalDistance {
234      get { return ((DoubleValue)Results[InvertedGenerationalDistanceResultName].Value).Value; }
235      set { ((DoubleValue)Results[InvertedGenerationalDistanceResultName].Value).Value = value; }
236    }
237    private double ResultsCrowding {
238      get { return ((DoubleValue)Results[CrowdingResultName].Value).Value; }
239      set { ((DoubleValue)Results[CrowdingResultName].Value).Value = value; }
240    }
241    private double ResultsSpacing {
242      get { return ((DoubleValue)Results[SpacingResultName].Value).Value; }
243      set { ((DoubleValue)Results[SpacingResultName].Value).Value = value; }
244    }
245    private double ResultsBestHypervolume {
246      get { return ((DoubleValue)Results[BestHypervolumeResultName].Value).Value; }
247      set { ((DoubleValue)Results[BestHypervolumeResultName].Value).Value = value; }
248    }
249    private double ResultsBestKnownHypervolume {
250      get { return ((DoubleValue)Results[BestKnownHypervolumeResultName].Value).Value; }
251      set { ((DoubleValue)Results[BestKnownHypervolumeResultName].Value).Value = value; }
252    }
253    private double ResultsDifferenceBestKnownHypervolume {
254      get { return ((DoubleValue)Results[DifferenceToBestKnownHypervolumeResultName].Value).Value; }
255      set { ((DoubleValue)Results[DifferenceToBestKnownHypervolumeResultName].Value).Value = value; }
256    }
257    //Solutions
258    private DoubleMatrix ResultsSolutions {
259      get { return (DoubleMatrix)Results[CurrentFrontResultName].Value; }
260      set { Results[CurrentFrontResultName].Value = value; }
261    }
262    private ParetoFrontScatterPlot ResultsScatterPlot {
263      get { return (ParetoFrontScatterPlot)Results[ScatterPlotResultName].Value; }
264      set { Results[ScatterPlotResultName].Value = value; }
265    }
266    #endregion
267
268    #region Constructors
269    public MOCMAEvolutionStrategy() {
270      Parameters.Add(new FixedValueParameter<IntValue>(MaximumRuntimeName, "The maximum runtime in seconds after which the algorithm stops. Use -1 to specify no limit for the runtime", new IntValue(3600)));
271      Parameters.Add(new FixedValueParameter<IntValue>(SeedName, "The random seed used to initialize the new pseudo random number generator.", new IntValue(0)));
272      Parameters.Add(new FixedValueParameter<BoolValue>(SetSeedRandomlyName, "True if the random seed should be set to a random value, otherwise false.", new BoolValue(true)));
273      Parameters.Add(new FixedValueParameter<IntValue>(PopulationSizeName, "λ (lambda) - the size of the offspring population.", new IntValue(20)));
274      Parameters.Add(new ValueParameter<DoubleArray>(InitialSigmaName, "The initial sigma can be a single value or a value for each dimension. All values need to be > 0.", new DoubleArray(new[] {0.5})));
275      Parameters.Add(new FixedValueParameter<IntValue>(MaximumGenerationsName, "The maximum number of generations which should be processed.", new IntValue(1000)));
276      Parameters.Add(new FixedValueParameter<IntValue>(MaximumEvaluatedSolutionsName, "The maximum number of evaluated solutions that should be computed.", new IntValue(int.MaxValue)));
277      var set = new ItemSet<IIndicator> {new HypervolumeIndicator(), new CrowdingIndicator(), new MinimalDistanceIndicator()};
278      Parameters.Add(new ConstrainedValueParameter<IIndicator>(IndicatorName, "The selection mechanism on non-dominated solutions", set, set.First()));
279    }
280
281    [StorableConstructor]
282    protected MOCMAEvolutionStrategy(StorableConstructorFlag _) : base(_) { }
283
284    protected MOCMAEvolutionStrategy(MOCMAEvolutionStrategy original, Cloner cloner) : base(original, cloner) {
285      random = cloner.Clone(original.random);
286      gauss = cloner.Clone(original.gauss);
287      solutions = original.solutions != null ? original.solutions.Select(cloner.Clone).ToArray() : null;
288      stepSizeLearningRate = original.stepSizeLearningRate;
289      stepSizeDampeningFactor = original.stepSizeDampeningFactor;
290      targetSuccessProbability = original.targetSuccessProbability;
291      evolutionPathLearningRate = original.evolutionPathLearningRate;
292      covarianceMatrixLearningRate = original.covarianceMatrixLearningRate;
293      covarianceMatrixUnlearningRate = original.covarianceMatrixUnlearningRate;
294      successThreshold = original.successThreshold;
295    }
296
297    public override IDeepCloneable Clone(Cloner cloner) {
298      return new MOCMAEvolutionStrategy(this, cloner);
299    }
300    #endregion
301
302    #region Initialization
303    protected override void Initialize(CancellationToken cancellationToken) {
304      if (SetSeedRandomly) Seed = RandomSeedGenerator.GetSeed();
305      random.Reset(Seed);
306      gauss = new NormalDistributedRandom(random, 0, 1);
307
308      InitResults();
309      InitStrategy();
310      InitSolutions();
311      Analyze();
312
313      ResultsIterations = 1;
314    }
315    private Individual InitializeIndividual(RealVector x) {
316      var zeros = new RealVector(x.Length);
317      var c = new double[x.Length, x.Length];
318      var sigma = InitialSigma.Max();
319      for (var i = 0; i < x.Length; i++) {
320        var d = InitialSigma[i % InitialSigma.Length] / sigma;
321        c[i, i] = d * d;
322      }
323      return new Individual(x, targetSuccessProbability, sigma, zeros, c, this);
324    }
325    private void InitSolutions() {
326      solutions = new Individual[PopulationSize];
327      for (var i = 0; i < PopulationSize; i++) {
328        var x = new RealVector(Encoding.Length); // Uniform distribution in all dimensions assumed.
329        var bounds = Encoding.Bounds;
330        for (var j = 0; j < Encoding.Length; j++) {
331          var dim = j % bounds.Rows;
332          x[j] = random.NextDouble() * (bounds[dim, 1] - bounds[dim, 0]) + bounds[dim, 0];
333        }
334        solutions[i] = InitializeIndividual(x);
335        PenalizeEvaluate(solutions[i]);
336      }
337      ResultsEvaluations += solutions.Length;
338    }
339    private void InitStrategy() {
340      const int lambda = 1;
341      double n = Encoding.Length;
342      targetSuccessProbability = 1.0 / (5.0 + Math.Sqrt(lambda) / 2.0);
343      stepSizeDampeningFactor = 1.0 + n / (2.0 * lambda);
344      stepSizeLearningRate = targetSuccessProbability * lambda / (2.0 + targetSuccessProbability * lambda);
345      evolutionPathLearningRate = 2.0 / (n + 2.0);
346      covarianceMatrixLearningRate = 2.0 / (n * n + 6.0);
347      covarianceMatrixUnlearningRate = 0.4 / (Math.Pow(n, 1.6) + 1);
348      successThreshold = 0.44;
349    }
350    private void InitResults() {
351      Results.Add(new Result(IterationsResultName, "The number of generations evaluated", new IntValue(0)));
352      Results.Add(new Result(EvaluationsResultName, "The number of function evaluations performed", new IntValue(0)));
353      Results.Add(new Result(HypervolumeResultName, "The hyper volume of the current front considering the reference point defined in the Problem", new DoubleValue(0.0)));
354      Results.Add(new Result(BestHypervolumeResultName, "The best hyper volume of the current run considering the reference point defined in the Problem", new DoubleValue(0.0)));
355      Results.Add(new Result(BestKnownHypervolumeResultName, "The best known hyper volume considering the reference point defined in the Problem", new DoubleValue(double.NaN)));
356      Results.Add(new Result(DifferenceToBestKnownHypervolumeResultName, "The difference between the current and the best known hyper volume", new DoubleValue(double.NaN)));
357      Results.Add(new Result(GenerationalDistanceResultName, "The generational distance to an optimal Pareto front defined in the Problem", new DoubleValue(double.NaN)));
358      Results.Add(new Result(InvertedGenerationalDistanceResultName, "The inverted generational distance to an optimal Pareto front defined in the Problem", new DoubleValue(double.NaN)));
359      Results.Add(new Result(CrowdingResultName, "The average crowding value for the current front (excluding infinities)", new DoubleValue(0.0)));
360      Results.Add(new Result(SpacingResultName, "The spacing for the current front (excluding infinities)", new DoubleValue(0.0)));
361
362      var table = new DataTable("QualityIndicators");
363      table.Rows.Add(new DataRow(BestHypervolumeResultName));
364      table.Rows.Add(new DataRow(HypervolumeResultName));
365      table.Rows.Add(new DataRow(CrowdingResultName));
366      table.Rows.Add(new DataRow(GenerationalDistanceResultName));
367      table.Rows.Add(new DataRow(InvertedGenerationalDistanceResultName));
368      table.Rows.Add(new DataRow(DifferenceToBestKnownHypervolumeResultName));
369      table.Rows.Add(new DataRow(SpacingResultName));
370      Results.Add(new Result(TimetableResultName, "Different quality measures in a time series", table));
371      Results.Add(new Result(CurrentFrontResultName, "The current front", new DoubleMatrix()));
372      Results.Add(new Result(ScatterPlotResultName, "A scatter plot displaying the evaluated solutions and (if available) the analytically optimal front", new ParetoFrontScatterPlot()));
373
374      var problem = Problem;
375      if (problem == null) return;
376      var bkf = problem.BestKnownFront == null ? null : problem.BestKnownFront.ToArray();
377      if (bkf != null && problem.ReferencePoint != null) {
378        ResultsBestKnownHypervolume = HypervolumeCalculator.CalculateHypervolume(bkf, problem.ReferencePoint, Problem.Maximization);
379        ResultsDifferenceBestKnownHypervolume = ResultsBestKnownHypervolume;
380      }
381      ResultsScatterPlot = new ParetoFrontScatterPlot(new double[0][], new double[0][], bkf, Problem.Objectives, Problem.Encoding.Length);
382    }
383    #endregion
384
385    #region Mainloop
386    protected override void Run(CancellationToken cancellationToken) {
387      while (ResultsIterations < MaximumGenerations && ResultsEvaluations < MaximumEvaluatedSolutions) {
388        try {
389          Iterate();
390          ResultsIterations++;
391          cancellationToken.ThrowIfCancellationRequested();
392        } finally {
393          Analyze();
394        }
395      }
396    }
397    private void Iterate() {
398      var offspring = solutions.Select(i => {
399        var o = new Individual(i);
400        o.Mutate(gauss);
401        PenalizeEvaluate(o);
402        return o;
403      });
404      ResultsEvaluations += solutions.Length;
405      var parents = solutions.Concat(offspring).ToArray();
406      SelectParents(parents, solutions.Length);
407      UpdatePopulation(parents);
408    }
409    protected override void OnExecutionTimeChanged() {
410      base.OnExecutionTimeChanged();
411      if (CancellationTokenSource == null) return;
412      if (MaximumRuntime == -1) return;
413      if (ExecutionTime.TotalSeconds > MaximumRuntime) CancellationTokenSource.Cancel();
414    }
415    #endregion
416
417    #region Evaluation
418    private void PenalizeEvaluate(Individual individual) {
419      if (IsFeasable(individual.Mean)) {
420        individual.Fitness = Evaluate(individual.Mean);
421        individual.PenalizedFitness = individual.Fitness;
422      } else {
423        var t = ClosestFeasible(individual.Mean);
424        individual.Fitness = Evaluate(t);
425        individual.PenalizedFitness = Penalize(individual.Mean, t, individual.Fitness);
426      }
427    }
428    private double[] Evaluate(RealVector x) {
429      var res = Problem.Evaluate(x, random);
430      return res;
431    }
432    private double[] Penalize(RealVector x, RealVector t, IEnumerable<double> fitness) {
433      var penalty = x.Zip(t, (a, b) => (a - b) * (a - b)).Sum() * 1E-6;
434      return fitness.Select((v, i) => Problem.Maximization[i] ? v - penalty : v + penalty).ToArray();
435    }
436    private RealVector ClosestFeasible(RealVector x) {
437      var bounds = Encoding.Bounds;
438      var r = new RealVector(x.Length);
439      for (var i = 0; i < x.Length; i++) {
440        var dim = i % bounds.Rows;
441        r[i] = Math.Min(Math.Max(bounds[dim, 0], x[i]), bounds[dim, 1]);
442      }
443      return r;
444    }
445    private bool IsFeasable(RealVector offspring) {
446      var bounds = Encoding.Bounds;
447      for (var i = 0; i < offspring.Length; i++) {
448        var dim = i % bounds.Rows;
449        if (bounds[dim, 0] > offspring[i] || offspring[i] > bounds[dim, 1]) return false;
450      }
451      return true;
452    }
453    #endregion
454
455    private void SelectParents(IReadOnlyList<Individual> parents, int length) {
456      //perform a non-dominated sort to assign the rank to every element
457      int[] ranks;
458      var fronts = DominationCalculator.CalculateAllParetoFronts(parents.ToArray(), parents.Select(i => i.PenalizedFitness).ToArray(), Problem.Maximization, out ranks);
459
460      //deselect the highest rank fronts until we would end up with less or equal mu elements
461      var rank = fronts.Count - 1;
462      var popSize = parents.Count;
463      while (popSize - fronts[rank].Count >= length) {
464        var front = fronts[rank];
465        foreach (var i in front) i.Item1.Selected = false;
466        popSize -= front.Count;
467        rank--;
468      }
469
470      //now use the indicator to deselect the approximately worst elements of the last selected front
471      var front1 = fronts[rank].OrderBy(x => x.Item1.PenalizedFitness[0]).ToList();
472      for (; popSize > length; popSize--) {
473        var lc = Indicator.LeastContributer(front1.Select(i => i.Item1).ToArray(), Problem);
474        front1[lc].Item1.Selected = false;
475        front1.Swap(lc, front1.Count - 1);
476        front1.RemoveAt(front1.Count - 1);
477      }
478    }
479
480    private void UpdatePopulation(IReadOnlyList<Individual> parents) {
481      foreach (var p in parents.Skip(solutions.Length).Where(i => i.Selected))
482        p.UpdateAsOffspring();
483      for (var i = 0; i < solutions.Length; i++)
484        if (parents[i].Selected)
485          parents[i].UpdateAsParent(parents[i + solutions.Length].Selected);
486      solutions = parents.Where(p => p.Selected).ToArray();
487    }
488
489    private void Analyze() {
490      var qualities = solutions.Select(x => x.Fitness).ToArray();
491
492      //to do check for side effects
493      ResultsScatterPlot = new ParetoFrontScatterPlot(qualities, solutions.Select(x => x.Mean.ToArray()).ToArray(), ResultsScatterPlot.ParetoFront, ResultsScatterPlot.Objectives, ResultsScatterPlot.ProblemSize);
494      ResultsSolutions = solutions.Select(x => x.Mean.ToArray()).ToMatrix();
495
496      var problem = Problem as MultiObjectiveProblem<RealVectorEncoding, RealVector>;
497      if (problem == null) return;
498
499
500      if (qualities.Length == 0) return;
501      ResultsCrowding = CrowdingCalculator.CalculateCrowding(qualities);
502      ResultsSpacing = SpacingAnalyzer.CalculateSpacing(qualities);
503
504
505      ResultsGenerationalDistance = problem.BestKnownFront != null ? GenerationalDistanceAnalyzer.CalculateGenerationalDistance(qualities, problem.BestKnownFront, 1) : double.NaN;
506      ResultsInvertedGenerationalDistance = problem.BestKnownFront != null ? GenerationalDistanceAnalyzer.CalculateInverseGenerationalDistance(qualities, problem.BestKnownFront, 1) : double.NaN;
507      ResultsHypervolume = problem.ReferencePoint != null ? HypervolumeCalculator.CalculateHypervolume(qualities, problem.ReferencePoint, Problem.Maximization) : double.NaN;
508      ResultsBestHypervolume = Math.Max(ResultsHypervolume, ResultsBestHypervolume);
509      ResultsDifferenceBestKnownHypervolume = ResultsBestKnownHypervolume - ResultsBestHypervolume;
510
511      ResultsBestHypervolumeDataLine.Values.Add(ResultsBestHypervolume);
512      ResultsHypervolumeDataLine.Values.Add(ResultsHypervolume);
513      ResultsCrowdingDataLine.Values.Add(ResultsCrowding);
514      ResultsGenerationalDistanceDataLine.Values.Add(ResultsGenerationalDistance);
515      ResultsInvertedGenerationalDistanceDataLine.Values.Add(ResultsInvertedGenerationalDistance);
516      ResultsSpacingDataLine.Values.Add(ResultsSpacing);
517      ResultsHypervolumeDifferenceDataLine.Values.Add(ResultsDifferenceBestKnownHypervolume);
518
519      Problem.Analyze(solutions.Select(x => x.Mean).ToArray(),
520        solutions.Select(x => x.Fitness).ToArray(),
521        Results,
522        random);
523    }
524  }
525}
Note: See TracBrowser for help on using the repository browser.