Free cookie consent management tool by TermsFeed Policy Generator

source: branches/HeuristicLab.EvolutionTracking/HeuristicLab.Problems.DataAnalysis.Symbolic/3.4/Analyzers/SymbolicDataAnalysisGeneticOperatorImprovementAnalyzer.cs @ 12940

Last change on this file since 12940 was 12894, checked in by bburlacu, 9 years ago

#1772: Small updates to SelectionSchemeAnalyzer and SymbolicDataAnalysisGeneticOperatorImprovementAnalyzer.

File size: 9.7 KB
Line 
1#region License Information
2/* HeuristicLab
3 * Copyright (C) 2002-2015 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.Linq;
23using HeuristicLab.Analysis;
24using HeuristicLab.Common;
25using HeuristicLab.Core;
26using HeuristicLab.Data;
27using HeuristicLab.Encodings.SymbolicExpressionTreeEncoding;
28using HeuristicLab.EvolutionTracking;
29using HeuristicLab.Optimization;
30using HeuristicLab.Parameters;
31using HeuristicLab.Persistence.Default.CompositeSerializers.Storable;
32
33namespace HeuristicLab.Problems.DataAnalysis.Symbolic.Analyzers {
34  [StorableClass]
35  [Item("SymbolicDataAnalysisGeneticOperatorImprovementAnalyzer", "An analyzer which records the best and average genetic operator improvement")]
36  public class SymbolicDataAnalysisGeneticOperatorImprovementAnalyzer : EvolutionTrackingAnalyzer<ISymbolicExpressionTree> {
37    public const string QualityParameterName = "Quality";
38    public const string PopulationParameterName = "SymbolicExpressionTree";
39    public const string CountIntermediateChildrenParameterName = "CountIntermediateChildren";
40
41    public IScopeTreeLookupParameter<DoubleValue> QualityParameter {
42      get { return (IScopeTreeLookupParameter<DoubleValue>)Parameters[QualityParameterName]; }
43    }
44
45    public IScopeTreeLookupParameter<ISymbolicExpressionTree> PopulationParameter {
46      get { return (IScopeTreeLookupParameter<ISymbolicExpressionTree>)Parameters[PopulationParameterName]; }
47    }
48
49    public IFixedValueParameter<BoolValue> CountIntermediateChildrenParameter {
50      get { return (IFixedValueParameter<BoolValue>)Parameters[CountIntermediateChildrenParameterName]; }
51    }
52
53    public bool CountIntermediateChildren {
54      get { return CountIntermediateChildrenParameter.Value.Value; }
55      set { CountIntermediateChildrenParameter.Value.Value = value; }
56    }
57
58    public SymbolicDataAnalysisGeneticOperatorImprovementAnalyzer() {
59      Parameters.Add(new ScopeTreeLookupParameter<ISymbolicExpressionTree>(PopulationParameterName, "The population of individuals."));
60      Parameters.Add(new ScopeTreeLookupParameter<DoubleValue>(QualityParameterName, "The individual qualities."));
61      Parameters.Add(new FixedValueParameter<BoolValue>(CountIntermediateChildrenParameterName, "Specifies whether to consider intermediate children (when crossover was followed by mutation). This should be set to false for offspring selection.", new BoolValue(true)));
62
63      CountIntermediateChildrenParameter.Hidden = true;
64    }
65
66    public SymbolicDataAnalysisGeneticOperatorImprovementAnalyzer(
67    SymbolicDataAnalysisGeneticOperatorImprovementAnalyzer original, Cloner cloner) : base(original, cloner) {
68      CountIntermediateChildren = original.CountIntermediateChildren;
69    }
70
71    public override IDeepCloneable Clone(Cloner cloner) {
72      return new SymbolicDataAnalysisGeneticOperatorImprovementAnalyzer(this, cloner);
73    }
74
75    [StorableHook(HookType.AfterDeserialization)]
76    private void AfterDeserialization() {
77      if (!Parameters.ContainsKey(CountIntermediateChildrenParameterName))
78        Parameters.Add(new FixedValueParameter<BoolValue>(CountIntermediateChildrenParameterName, "Specifies whether to consider intermediate children (when crossover was followed by mutation", new BoolValue(true)));
79      CountIntermediateChildrenParameter.Hidden = true;
80    }
81
82    public override IOperation Apply() {
83      IntValue updateCounter = UpdateCounterParameter.ActualValue;
84      if (updateCounter == null) {
85        updateCounter = new IntValue(0);
86        UpdateCounterParameter.ActualValue = updateCounter;
87      }
88      updateCounter.Value++;
89      if (updateCounter.Value != UpdateInterval.Value) return base.Apply();
90      updateCounter.Value = 0;
91
92      var graph = PopulationGraph;
93      if (graph == null || Generation.Value == 0)
94        return base.Apply();
95
96      var generation = Generation.Value;
97      var averageQuality = QualityParameter.ActualValue.Average(x => x.Value);
98      var population = PopulationParameter.ActualValue;
99      var populationSize = population.Length;
100
101      var vertices = population.Select(graph.GetByContent).ToList();
102      DataTable table;
103      double aac = 0; // ratio of above average children produced
104      double aacp = 0; // ratio of above average children from above average parents
105      #region crossover improvement
106      if (!Results.ContainsKey("Crossover improvement")) {
107        table = new DataTable("Crossover improvement");
108        Results.Add(new Result("Crossover improvement", table));
109        table.Rows.AddRange(new[]
110          {
111              new DataRow("Average crossover improvement (root parent)") { VisualProperties = { StartIndexZero = true } },
112              new DataRow("Average crossover improvement (non-root parent)") { VisualProperties = { StartIndexZero = true } },
113              new DataRow("Average child-parents quality difference") { VisualProperties = { StartIndexZero = true } },
114              new DataRow("Best crossover improvement (root parent)") { VisualProperties = { StartIndexZero = true } },
115              new DataRow("Best crossover improvement (non-root parent)") { VisualProperties = { StartIndexZero = true }},
116              new DataRow("Above average children") { VisualProperties = { StartIndexZero = true }},
117              new DataRow("Above average children from above average parents") { VisualProperties = { StartIndexZero = true } },
118            });
119      } else {
120        table = (DataTable)Results["Crossover improvement"].Value;
121      }
122      var crossoverChildren = vertices.Where(x => x.InDegree == 2).ToList();
123      if (CountIntermediateChildren)
124        crossoverChildren.AddRange(vertices.Where(x => x.InDegree == 1).Select(v => v.Parents.First()).Where(p => p.Rank.IsAlmost(generation - 0.5))); // add intermediate children
125
126      foreach (var c in crossoverChildren) {
127        if (c.Quality > averageQuality) {
128          aac++;
129          if (c.Parents.All(x => x.Quality > averageQuality))
130            aacp++;
131        }
132      }
133      var avgRootParentQualityImprovement = crossoverChildren.Average(x => x.Quality - x.Parents.First().Quality);
134      var avgNonRootParentQualityImprovement = crossoverChildren.Average(x => x.Quality - x.Parents.Last().Quality);
135      var avgChildParentQuality = crossoverChildren.Average(x => x.Quality - x.Parents.Average(p => p.Quality));
136      var bestRootParentQualityImprovement = crossoverChildren.Max(x => x.Quality - x.Parents.First().Quality);
137      var bestNonRootParentQualityImprovement = crossoverChildren.Max(x => x.Quality - x.Parents.Last().Quality);
138      table.Rows["Average crossover improvement (root parent)"].Values.Add(avgRootParentQualityImprovement);
139      table.Rows["Average crossover improvement (non-root parent)"].Values.Add(avgNonRootParentQualityImprovement);
140      table.Rows["Best crossover improvement (root parent)"].Values.Add(bestRootParentQualityImprovement);
141      table.Rows["Best crossover improvement (non-root parent)"].Values.Add(bestNonRootParentQualityImprovement);
142      table.Rows["Average child-parents quality difference"].Values.Add(avgChildParentQuality);
143      table.Rows["Above average children"].Values.Add(aac / populationSize);
144      table.Rows["Above average children from above average parents"].Values.Add(aacp / populationSize);
145      #endregion
146
147      #region mutation improvement
148      if (!Results.ContainsKey("Mutation improvement")) {
149        table = new DataTable("Mutation improvement");
150        Results.Add(new Result("Mutation improvement", table));
151        table.Rows.AddRange(new[]
152          {
153              new DataRow("Average mutation improvement") { VisualProperties = { StartIndexZero = true } },
154              new DataRow("Best mutation improvement") { VisualProperties = { StartIndexZero = true } },
155              new DataRow("Above average children") { VisualProperties = { StartIndexZero = true } },
156              new DataRow("Above average children from above average parents") { VisualProperties = { StartIndexZero = true } },
157            });
158      } else {
159        table = (DataTable)Results["Mutation improvement"].Value;
160      }
161
162      aac = 0;
163      aacp = 0;
164      var mutationChildren = vertices.Where(x => x.InDegree == 1).ToList();
165
166      foreach (var c in mutationChildren) {
167        if (c.Quality > averageQuality) {
168          aac++;
169          if (c.Parents.All(x => x.Quality > averageQuality))
170            aacp++;
171        }
172      }
173      var avgMutationImprovement = mutationChildren.Average(x => x.Quality - x.Parents.First().Quality);
174      var bestMutationImprovement = mutationChildren.Max(x => x.Quality - x.Parents.First().Quality);
175
176      table.Rows["Average mutation improvement"].Values.Add(avgMutationImprovement);
177      table.Rows["Best mutation improvement"].Values.Add(bestMutationImprovement);
178      table.Rows["Above average children"].Values.Add(aac / populationSize);
179      table.Rows["Above average children from above average parents"].Values.Add(aacp / populationSize);
180      #endregion
181      return base.Apply();
182    }
183  }
184}
Note: See TracBrowser for help on using the repository browser.