source: branches/HeuristicLab.EvolutionTracking/HeuristicLab.Problems.DataAnalysis.Symbolic/3.4/Tracking/Analyzers/SymbolicDataAnalysisFragmentLengthAnalyzer.cs @ 13944

Last change on this file since 13944 was 13944, checked in by bburlacu, 4 years ago

#1772: Fix bug in fragment length calculator leading to exception when we try to compute the average out of an empty sequence of fragment lengths.

File size: 9.5 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.Collections.Generic;
23using System.Linq;
24using HeuristicLab.Analysis;
25using HeuristicLab.Common;
26using HeuristicLab.Core;
27using HeuristicLab.Data;
28using HeuristicLab.Encodings.SymbolicExpressionTreeEncoding;
29using HeuristicLab.EvolutionTracking;
30using HeuristicLab.Optimization;
31using HeuristicLab.Parameters;
32using HeuristicLab.Persistence.Default.CompositeSerializers.Storable;
33
34namespace HeuristicLab.Problems.DataAnalysis.Symbolic.Tracking.Analyzers {
35  [Item("SymbolicDataAnalysisFragmentLengthAnalyzer", "An analyzer for fragment length.")]
36  [StorableClass]
37  public class SymbolicDataAnalysisFragmentLengthAnalyzer : EvolutionTrackingAnalyzer<ISymbolicExpressionTree> {
38    private const string StoreHistoryParameterName = "StoryHistory";
39
40    public IFixedValueParameter<BoolValue> StoreHistoryParameter {
41      get { return (IFixedValueParameter<BoolValue>)Parameters[StoreHistoryParameterName]; }
42    }
43
44    public bool StoreHistory {
45      get { return StoreHistoryParameter.Value.Value; }
46      set { StoreHistoryParameter.Value.Value = value; }
47    }
48
49    [StorableConstructor]
50    protected SymbolicDataAnalysisFragmentLengthAnalyzer(bool deserializing) : base(deserializing) { }
51
52    public SymbolicDataAnalysisFragmentLengthAnalyzer() {
53      UpdateCounterParameter.ActualName = "FragmentLengthAnalyzerUpdateCounter";
54
55      Parameters.Add(new FixedValueParameter<BoolValue>(StoreHistoryParameterName, new BoolValue(false)));
56    }
57
58    protected SymbolicDataAnalysisFragmentLengthAnalyzer(SymbolicDataAnalysisFragmentLengthAnalyzer original, Cloner cloner) : base(original, cloner) { }
59
60    public override IDeepCloneable Clone(Cloner cloner) { return new SymbolicDataAnalysisFragmentLengthAnalyzer(this, cloner); }
61
62    public override IOperation Apply() {
63      int updateInterval = UpdateIntervalParameter.Value.Value;
64      IntValue updateCounter = UpdateCounterParameter.ActualValue;
65      // if counter does not yet exist then initialize it with update interval
66      // to make sure the solutions are analyzed on the first application of this operator
67      if (updateCounter == null) {
68        updateCounter = new IntValue(updateInterval);
69        UpdateCounterParameter.ActualValue = updateCounter;
70      }
71      //analyze solutions only every 'updateInterval' times
72      if (updateCounter.Value != updateInterval) {
73        updateCounter.Value++;
74        return base.Apply();
75      }
76      updateCounter.Value = 1;
77
78      if (PopulationGraph == null || Generation.Value == 0)
79        return base.Apply();
80
81      // consider all fragments (including those of the intermediate crossover children)
82      var vertices = PopulationGraph.Vertices.Where(x => x.Rank > Generation.Value - 1);
83      var crossoverFragmentLengthDistribution = new List<double>();
84      var replacedCrossoverFragmentLengthDistribution = new List<double>();
85      var mutationFragmentLengthDistribution = new List<double>();
86      var replacedMutationFragmentLengthDistribution = new List<double>();
87      foreach (var v in vertices) {
88        if (!v.InArcs.Any() || v.InArcs.Last().Data == null)
89          continue;
90        var fragment = (IFragment<ISymbolicExpressionTreeNode>)v.InArcs.Last().Data;
91        if (v.InDegree == 2) {
92          crossoverFragmentLengthDistribution.Add(fragment.Root.GetLength());
93          int index = 0;
94          foreach (var s in v.Parents.First().Data.IterateNodesPrefix()) {
95            if (index == fragment.Index1) {
96              replacedCrossoverFragmentLengthDistribution.Add(s.GetLength());
97              break;
98            }
99            index++;
100          }
101        } else {
102          mutationFragmentLengthDistribution.Add(fragment.Root.GetLength());
103          int index = 0;
104          foreach (var s in v.Parents.First().Data.IterateNodesPrefix()) {
105            if (index == fragment.Index1) {
106              replacedMutationFragmentLengthDistribution.Add(s.GetLength());
107              break;
108            }
109            index++;
110          }
111        }
112      }
113      var avgCXFragmentLength = crossoverFragmentLengthDistribution.Any() ? crossoverFragmentLengthDistribution.Average() : 0;
114      var avgReplacedCXFragmentLength = replacedCrossoverFragmentLengthDistribution.Any() ? replacedCrossoverFragmentLengthDistribution.Average() : 0;
115      var avgMutFragmentLength = mutationFragmentLengthDistribution.Any() ? mutationFragmentLengthDistribution.Average() : 0;
116      var avgReplacedMutFragmentLength = replacedMutationFragmentLengthDistribution.Any() ? replacedMutationFragmentLengthDistribution.Average() : 0;
117      var avgFragmentLength = (avgCXFragmentLength + avgMutFragmentLength) / 2d;
118      DataTable table;
119      if (!Results.ContainsKey("AverageFragmentLength")) {
120        table = new DataTable("Average fragment length");
121        var row = new DataRow("Average fragment length") { VisualProperties = { StartIndexZero = true } };
122        row.Values.Add(avgFragmentLength);
123        table.Rows.Add(row);
124        row = new DataRow("Average crossover fragment length") { VisualProperties = { StartIndexZero = true } };
125        row.Values.Add(avgCXFragmentLength);
126        table.Rows.Add(row);
127        row = new DataRow("Average replaced crossover fragment length") { VisualProperties = { StartIndexZero = true } };
128        row.Values.Add(avgReplacedCXFragmentLength);
129        table.Rows.Add(row);
130        row = new DataRow("Average mutation fragment length") { VisualProperties = { StartIndexZero = true } };
131        row.Values.Add(avgMutFragmentLength);
132        table.Rows.Add(row);
133        row = new DataRow("Average replaced mutation fragment length") { VisualProperties = { StartIndexZero = true } };
134        row.Values.Add(avgReplacedMutFragmentLength);
135        table.Rows.Add(row);
136        Results.Add(new Result("AverageFragmentLength", table));
137      } else {
138        table = (DataTable)Results["AverageFragmentLength"].Value;
139        table.Rows["Average fragment length"].Values.Add(avgFragmentLength);
140        table.Rows["Average crossover fragment length"].Values.Add(avgCXFragmentLength);
141        table.Rows["Average replaced crossover fragment length"].Values.Add(avgReplacedCXFragmentLength);
142        table.Rows["Average mutation fragment length"].Values.Add(avgMutFragmentLength);
143        table.Rows["Average replaced mutation fragment length"].Values.Add(avgReplacedMutFragmentLength);
144      }
145      if (!Results.ContainsKey("FragmentLengthDistribution")) {
146        table = new DataTable("Table length distribution");
147        var row = new DataRow("Crossover fragment length distribution") { VisualProperties = { StartIndexZero = true, ChartType = DataRowVisualProperties.DataRowChartType.Histogram } };
148        row.Values.Replace(crossoverFragmentLengthDistribution);
149        table.Rows.Add(row);
150        row = new DataRow("Replaced crossover fragment length distribution") { VisualProperties = { StartIndexZero = true, ChartType = DataRowVisualProperties.DataRowChartType.Histogram } };
151        row.Values.Replace(replacedCrossoverFragmentLengthDistribution);
152        table.Rows.Add(row);
153        row = new DataRow("Mutation fragment length distribution") { VisualProperties = { StartIndexZero = true, ChartType = DataRowVisualProperties.DataRowChartType.Histogram } };
154        row.Values.Replace(mutationFragmentLengthDistribution);
155        table.Rows.Add(row);
156        row = new DataRow("Replaced mutation fragment length distribution") { VisualProperties = { StartIndexZero = true, ChartType = DataRowVisualProperties.DataRowChartType.Histogram } };
157        row.Values.Replace(replacedMutationFragmentLengthDistribution);
158        table.Rows.Add(row);
159        Results.Add(new Result("FragmentLengthDistribution", table));
160      } else {
161        table = (DataTable)Results["FragmentLengthDistribution"].Value;
162        table.Rows["Crossover fragment length distribution"].Values.Replace(crossoverFragmentLengthDistribution);
163        table.Rows["Mutation fragment length distribution"].Values.Replace(mutationFragmentLengthDistribution);
164        table.Rows["Replaced crossover fragment length distribution"].Values.Replace(replacedCrossoverFragmentLengthDistribution);
165        table.Rows["Replaced mutation fragment length distribution"].Values.Replace(replacedMutationFragmentLengthDistribution);
166      }
167      if (StoreHistory) {
168        if (!Results.ContainsKey("FragmentLengthDistributionHistory")) {
169          var history = new DataTableHistory();
170          history.Add(table);
171          Results.Add(new Result("FragmentLengthDistributionHistory", history));
172        } else {
173          var history = (DataTableHistory)Results["FragmentLengthDistributionHistory"].Value;
174          history.Add(table);
175        }
176      }
177      return base.Apply();
178    }
179  }
180}
Note: See TracBrowser for help on using the repository browser.