Free cookie consent management tool by TermsFeed Policy Generator

source: branches/FitnessLandscapeAnalysis/HeuristicLab.Analysis.FitnessLandscape/PopDist/PopulationDistributionAnalyzer.cs @ 7128

Last change on this file since 7128 was 7128, checked in by epitzer, 12 years ago

#1696 Integrate fitness landscape analysis plugins from Heureka! repository.

File size: 9.7 KB
Line 
1#region License Information
2/* HeuristicLab
3 * Copyright (C) 2002-2010 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
4 *
5 * This file is part of HeuristicLab.
6 *
7 * HeuristicLab is free software: you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License as published by
9 * the Free Software Foundation, either version 3 of the License, or
10 * (at your option) any later version.
11 *
12 * HeuristicLab is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15 * GNU General Public License for more details.
16 *
17 * You should have received a copy of the GNU General Public License
18 * along with HeuristicLab. If not, see <http://www.gnu.org/licenses/>.
19 */
20#endregion
21
22using System;
23using System.IO;
24using System.Linq;
25using HeuristicLab.Common;
26using HeuristicLab.Core;
27using HeuristicLab.Data;
28using HeuristicLab.Operators;
29using HeuristicLab.Optimization;
30using HeuristicLab.Optimization.Operators;
31using HeuristicLab.Parameters;
32using HeuristicLab.Persistence.Default.CompositeSerializers.Storable;
33
34namespace HeuristicLab.Analysis.FitnessLandscape {
35
36  [Item("PopulationDistributionAnalyzer", "An operator that analyzes the distribution of fitness values")]
37  [StorableClass]
38  public class PopulationDistributionAnalyzer : AlgorithmOperator, IAnalyzer {
39
40    #region Parameters
41    public ScopeTreeLookupParameter<DoubleValue> QualityParameter {
42      get { return (ScopeTreeLookupParameter<DoubleValue>)Parameters["Quality"]; }
43    }
44    public ValueLookupParameter<DataTable> FitnessQuantilesParameter {
45      get { return (ValueLookupParameter<DataTable>)Parameters["Fitness Quantiles"]; }
46    }
47    public ValueLookupParameter<DataTable> PopulationDispersionParameter {
48      get { return (ValueLookupParameter<DataTable>)Parameters["Population Dispersion"]; }
49    }
50    public ValueLookupParameter<DataTable> HigherPopulationMomentsParameter {
51      get { return (ValueLookupParameter<DataTable>)Parameters["Higher Population Moments"]; }
52    }
53    public ValueLookupParameter<DataTable> PopulationNormalityParameter {
54      get { return (ValueLookupParameter<DataTable>)Parameters["Population Normality"]; }
55    }
56    public ValueLookupParameter<VariableCollection> ResultsParameter {
57      get { return (ValueLookupParameter<VariableCollection>)Parameters["Results"]; }
58    }
59    public ValueLookupParameter<ResultCollection> PopulationDistributionResultsParameter {
60      get { return (ValueLookupParameter<ResultCollection>)Parameters["Population Distribution Results"]; }
61    }
62    public OptionalValueParameter<StringValue> PopulationLogFileNameParameter {
63      get { return (OptionalValueParameter<StringValue>)Parameters["Population Log File Name"]; }
64    }
65    public ConstrainedValueParameter<IntValue> NQuantilesParameter {
66      get { return (ConstrainedValueParameter<IntValue>)Parameters["NQuantiles"]; }
67    }
68    #endregion
69
70    [StorableConstructor]
71    protected PopulationDistributionAnalyzer(bool deserializing) : base(deserializing) { }
72    protected PopulationDistributionAnalyzer(PopulationDistributionAnalyzer original, Cloner cloner) : base(original, cloner) { }
73
74    public PopulationDistributionAnalyzer() {
75      Parameters.Add(new ScopeTreeLookupParameter<DoubleValue>("Quality", "The quality of the solution"));
76      Parameters.Add(new ValueLookupParameter<VariableCollection>("Results", "The collection of all results of this algorithm"));
77      Parameters.Add(new ValueLookupParameter<ResultCollection>("Population Distribution Results", "All results from population distribution analysis"));
78      Parameters.Add(new ValueLookupParameter<DataTable>("Fitness Quantiles", "Data table with quantiles of the fitness distribution"));
79      Parameters.Add(new ValueLookupParameter<DataTable>("Population Dispersion", "Data table dispersion statistics"));
80      Parameters.Add(new ValueLookupParameter<DataTable>("Higher Population Moments", "Data table skewness and kurtosis of population's fitness distribution"));
81      Parameters.Add(new ValueLookupParameter<DataTable>("Population Normality", "Jarque-Bera Normality Test p-value and 0.05 threshold"));
82      Parameters.Add(new OptionalValueParameter<StringValue>("Population Log File Name", "File name of a log file where all population fittness values are logged to"));
83      Parameters.Add(new ConstrainedValueParameter<IntValue>("NQuantiles", "Number of quantiles to plot", new ItemSet<IntValue>(Enumerable.Range(1, 50).Select(v => new IntValue(v)))));
84
85      NQuantilesParameter.Value = NQuantilesParameter.ValidValues.Single(v => v.Value == 10);
86
87      var resultsCollector = new ResultsCollector();
88      resultsCollector.ResultsParameter.ActualName = PopulationDistributionResultsParameter.Name;
89      resultsCollector.CollectedValues.Add(new LookupParameter<DataTable>(FitnessQuantilesParameter.Name));
90      resultsCollector.CollectedValues.Add(new LookupParameter<DataTable>(PopulationDispersionParameter.Name));
91      resultsCollector.CollectedValues.Add(new LookupParameter<DataTable>(HigherPopulationMomentsParameter.Name));
92      resultsCollector.CollectedValues.Add(new LookupParameter<DataTable>(PopulationNormalityParameter.Name));
93
94      var globalResultsCollector = new ResultsCollector();
95      globalResultsCollector.CollectedValues.Add(new ValueLookupParameter<ResultCollection>(PopulationDistributionResultsParameter.Name));
96
97      OperatorGraph.InitialOperator = resultsCollector;
98      resultsCollector.Successor = globalResultsCollector;
99      globalResultsCollector.Successor = null;
100    }
101
102    public override IDeepCloneable Clone(Cloner cloner) {
103      return new PopulationDistributionAnalyzer(this, cloner);
104    }
105
106    public override IOperation Apply() {
107      if (PopulationDistributionResultsParameter.ActualValue == null)
108        PopulationDistributionResultsParameter.ActualValue = new ResultCollection();
109      var qualities = QualityParameter.ActualValue.Select(v => v.Value).ToArray();
110      CalculateQuantiles(qualities);
111      CalculateDistributionParameters(qualities);
112      LogPopulationFitnessValues(qualities);
113      return base.Apply();
114    }
115
116    private void CalculateQuantiles(double[] qualities) {
117      DataTable quantiles = FitnessQuantilesParameter.ActualValue;
118      if (quantiles == null) {
119        quantiles = new DataTable("Fitness Quantiles");
120        quantiles.Description = "The population's fitness quantiles";
121        FitnessQuantilesParameter.ActualValue = quantiles;
122        for (int i = 0; i <= NQuantilesParameter.Value.Value; i++)
123          quantiles.Rows.Add(new DataRow((i * 10).ToString()));
124      }
125      int n_quantiles = quantiles.Rows.Count;
126      for (int i = 0; i < n_quantiles; i++) {
127        double v = 0;
128        alglib.basestat.samplepercentile(qualities, qualities.Length, 1.0 * i / n_quantiles, ref v);
129        quantiles.Rows[(i * 10).ToString()].Values.Add(v);
130      }
131    }
132
133    private void CalculateDistributionParameters(double[] qualities) {
134      DataTable populationDispersion = PopulationDispersionParameter.ActualValue;
135      if (populationDispersion == null) {
136        populationDispersion = new DataTable("Population Dispersion");
137        PopulationDispersionParameter.ActualValue = populationDispersion;
138        populationDispersion.Rows.Add(new DataRow("Std. Deviation"));
139        populationDispersion.Rows.Add(new DataRow("Mean Difference"));
140      }
141      DataTable higherPopulationMoments = HigherPopulationMomentsParameter.ActualValue;
142      if (higherPopulationMoments == null) {
143        higherPopulationMoments = new DataTable("Higher Population Moments");
144        HigherPopulationMomentsParameter.ActualValue = higherPopulationMoments;
145        higherPopulationMoments.Rows.Add(new DataRow("Skewness"));
146        higherPopulationMoments.Rows.Add(new DataRow("Kurtosis"));
147      }
148      DataTable populationNormality = PopulationNormalityParameter.ActualValue;
149      if (populationNormality == null) {
150        populationNormality = new DataTable("Population Normality");
151        PopulationNormalityParameter.ActualValue = populationNormality;
152        populationNormality.Rows.Add(new DataRow("Jarque-Bera P-Value"));
153        populationNormality.Rows.Add(new DataRow("0.05"));
154      }
155
156      double mean, variance, skewness, kurtosis, p_value;
157      mean = variance = skewness = kurtosis = p_value = 0;
158      alglib.basestat.samplemoments(qualities, qualities.Length, ref mean, ref variance, ref skewness, ref kurtosis);
159      alglib.jarquebera.jarqueberatest(qualities, qualities.Length, ref p_value);
160      double mean_difference =
161        (from i in Enumerable.Range(0, qualities.Length)
162         from j in Enumerable.Range(0, i)
163         select Math.Abs(qualities[i] - qualities[j])).Sum()
164           * 2 / qualities.Length / (qualities.Length - 1);
165
166      populationDispersion.Rows["Std. Deviation"].Values.Add(Math.Sqrt(variance));
167      populationDispersion.Rows["Mean Difference"].Values.Add(mean_difference);
168      higherPopulationMoments.Rows["Skewness"].Values.Add(skewness);
169      higherPopulationMoments.Rows["Kurtosis"].Values.Add(kurtosis);
170      populationNormality.Rows["Jarque-Bera P-Value"].Values.Add(p_value);
171      populationNormality.Rows["0.05"].Values.Add(0.05);
172    }
173
174    private void LogPopulationFitnessValues(double[] qualities) {
175      if (PopulationLogFileNameParameter.ActualValue == null)
176        return;
177      using (var writer = new StreamWriter(PopulationLogFileNameParameter.Value.Value, true)) {
178        foreach (var q in qualities) {
179          writer.Write(q);
180          writer.Write(";");
181        }
182        writer.WriteLine();
183        writer.Close();
184      }
185    }
186  }
187}
Note: See TracBrowser for help on using the repository browser.