Free cookie consent management tool by TermsFeed Policy Generator

source: branches/HeuristicLab.EvolutionaryTracking/HeuristicLab.EvolutionaryTracking/3.4/Analyzers/SymbolicExpressionTreeFragmentsAnalyzer.cs @ 8213

Last change on this file since 8213 was 8213, checked in by bburlacu, 12 years ago

#1772: Performance improvements for the GenealogyGraph. Minor refactoring to VisualGenealogyGraphArc and VisualGenealogyGraphNode classes. Added new functionality to the SymbolicExpressionTreeFragmentsAnalyzer, minor refactoring in the other two analyzers. Refactored View code. Updated project references and plugin dependencies and added HeuristicLab.Problems.DataAnalysis.Symbolic to the branch.

File size: 27.4 KB
Line 
1#region License Information
2/* HeuristicLab
3 * Copyright (C) 2002-2012 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.Operators;
30using HeuristicLab.Optimization;
31using HeuristicLab.Parameters;
32using HeuristicLab.Persistence.Default.CompositeSerializers.Storable;
33using HeuristicLab.Problems.DataAnalysis;
34using HeuristicLab.Problems.DataAnalysis.Symbolic;
35using HeuristicLab.Problems.DataAnalysis.Symbolic.Regression;
36// type definitions for convenience
37using CloneMapType = HeuristicLab.Core.ItemDictionary<HeuristicLab.Core.IItem, HeuristicLab.Core.IItem>;
38using SymbolicExpressionTreeNodeItem = HeuristicLab.EvolutionaryTracking.GenericWrapper<HeuristicLab.Encodings.SymbolicExpressionTreeEncoding.SymbolicExpressionTreeNode>;
39using TraceMapType = HeuristicLab.Core.ItemDictionary<HeuristicLab.Core.IItem, HeuristicLab.Core.IItemList<HeuristicLab.Core.IItem>>;
40
41namespace HeuristicLab.EvolutionaryTracking {
42  /// <summary>
43  /// An operator that gathers information on tree fragments that get passed from one generation to the next via genetic operators
44  /// (Tracking of genetic variance and heredity)
45  /// </summary>
46  [Item("SymbolicExpressionTreeFragmentsAnalyzer", "An operator that provides statistics about crossover fragments")]
47  [StorableClass]
48  public sealed class SymbolicExpressionTreeFragmentsAnalyzer : SingleSuccessorOperator, IAnalyzer {
49    private const string UpdateIntervalParameterName = "UpdateInterval";
50    private const string UpdateCounterParameterName = "UpdateCounter";
51    private const string ResultsParameterName = "Results";
52    private const string SecondaryTraceMapParameterName = "SecondaryTraceMap";
53    private const string SecondaryFragmentMapParameterName = "SecondaryFragmentMap";
54    private const string SecondaryCloneMapParameterName = "SecondaryCloneMap";
55    private const string GlobalTraceMapParameterName = "GlobalTraceMap";
56    private const string GlobalCloneMapParameterName = "GlobalCloneMap";
57    private const string GlobalFragmentMapParameterName = "GlobalFragmentMap";
58    private const string GenerationsParameterName = "Generations";
59    private const string SymbolicExpressionInterpreterParameterName = "SymbolicExpressionTreeInterpreter";
60    private const string SymbolicRegressionProblemDataParameterName = "ProblemData";
61    private const string FragmentStatisticsParameterName = "FragmentStatistics";
62    private const string FragmentLengthsDistributionParametersName = "FragmentLengths";
63    private const string FragmentFrequenciesParameterName = "FragmentFrequencies";
64
65    // impact values calculator
66    private SymbolicRegressionSolutionValuesCalculator _calculator = new SymbolicRegressionSolutionValuesCalculator();
67
68    #region Parameter properties
69    public ValueParameter<IntValue> UpdateIntervalParameter {
70      get { return (ValueParameter<IntValue>)Parameters[UpdateIntervalParameterName]; }
71    }
72    public ValueParameter<IntValue> UpdateCounterParameter {
73      get { return (ValueParameter<IntValue>)Parameters[UpdateCounterParameterName]; }
74    }
75    public LookupParameter<ResultCollection> ResultsParameter {
76      get { return (LookupParameter<ResultCollection>)Parameters[ResultsParameterName]; }
77    }
78    public LookupParameter<IntValue> GenerationsParameter {
79      get { return (LookupParameter<IntValue>)Parameters[GenerationsParameterName]; }
80    }
81    // tracking structures
82    public LookupParameter<TraceMapType> GlobalTraceMapParameter {
83      get { return (LookupParameter<TraceMapType>)Parameters[GlobalTraceMapParameterName]; }
84    }
85    public LookupParameter<CloneMapType> GlobalCloneMapParameter {
86      get { return (LookupParameter<CloneMapType>)Parameters[GlobalCloneMapParameterName]; }
87    }
88    public LookupParameter<CloneMapType> GlobalFragmentMapParameter {
89      get { return (LookupParameter<CloneMapType>)Parameters[GlobalFragmentMapParameterName]; }
90    }
91    public LookupParameter<DataTable> FragmentFrequenciesParameter {
92      get { return (LookupParameter<DataTable>)Parameters[FragmentFrequenciesParameterName]; }
93    }
94    public LookupParameter<DataTable> FragmentStatisticsParameter {
95      get { return (LookupParameter<DataTable>)Parameters[FragmentStatisticsParameterName]; }
96    }
97    public LookupParameter<DataTable> FragmentLengthsParameter {
98      get { return (LookupParameter<DataTable>)Parameters[FragmentLengthsDistributionParametersName]; }
99    }
100    // auxiliary structures for tracking fragments and individuals from the previous generation
101    // (this is needed because tracking is done in connection to the current generation, i.e., for
102    // counting "successful" offspring and fragments
103    public LookupParameter<TraceMapType> SecondaryTraceMapParameter {
104      get { return (LookupParameter<TraceMapType>)Parameters[SecondaryTraceMapParameterName]; }
105    }
106    public LookupParameter<CloneMapType> SecondaryFragmentMapParameter {
107      get { return (LookupParameter<CloneMapType>)Parameters[SecondaryFragmentMapParameterName]; }
108    }
109    public LookupParameter<CloneMapType> SecondaryCloneMapParameter {
110      get { return (LookupParameter<CloneMapType>)Parameters[SecondaryCloneMapParameterName]; }
111    }
112    // problem data, interpreter and evaluator
113    public LookupParameter<SymbolicDataAnalysisExpressionTreeInterpreter> SymbolicExpressionInterpreterParameter {
114      get { return (LookupParameter<SymbolicDataAnalysisExpressionTreeInterpreter>)Parameters[SymbolicExpressionInterpreterParameterName]; }
115    }
116    public LookupParameter<RegressionProblemData> SymbolicRegressionProblemDataParameter {
117      get { return (LookupParameter<RegressionProblemData>)Parameters[SymbolicRegressionProblemDataParameterName]; }
118    }
119    #endregion
120
121    #region Parameters
122    public bool EnabledByDefault {
123      get { return true; }
124    }
125    public IntValue UpdateInterval {
126      get { return UpdateIntervalParameter.Value; }
127    }
128    public IntValue UpdateCounter {
129      get { return UpdateCounterParameter.Value; }
130    }
131    public ResultCollection Results {
132      get { return ResultsParameter.ActualValue; }
133    }
134    public CloneMapType GlobalCloneMap {
135      get { return GlobalCloneMapParameter.ActualValue; }
136    }
137    public TraceMapType GlobalTraceMap {
138      get { return GlobalTraceMapParameter.ActualValue; }
139    }
140    public TraceMapType SecondaryTraceMap {
141      get { return SecondaryTraceMapParameter.ActualValue; }
142      set { SecondaryTraceMapParameter.ActualValue = value; }
143    }
144    public CloneMapType SecondaryFragmentMap {
145      get { return SecondaryFragmentMapParameter.ActualValue; }
146      set { SecondaryFragmentMapParameter.ActualValue = value; }
147    }
148    public CloneMapType SecondaryCloneMap {
149      get { return SecondaryCloneMapParameter.ActualValue; }
150      set { SecondaryCloneMapParameter.ActualValue = value; }
151    }
152    public CloneMapType GlobalFragmentMap {
153      get { return GlobalFragmentMapParameter.ActualValue; }
154    }
155    public IntValue Generations {
156      get { return GenerationsParameter.ActualValue; }
157    }
158    public DataTable FragmentStatistics {
159      get { return FragmentStatisticsParameter.ActualValue; }
160    }
161    public DataTable FragmentLengths {
162      get { return FragmentLengthsParameter.ActualValue; }
163    }
164    public DataTable FragmentFrequencies {
165      get { return FragmentFrequenciesParameter.ActualValue; }
166    }
167    public SymbolicDataAnalysisExpressionTreeInterpreter SymbolicExpressionInterpreter {
168      get { return SymbolicExpressionInterpreterParameter.ActualValue; }
169    }
170    public RegressionProblemData SymbolicRegressionProblemData {
171      get { return SymbolicRegressionProblemDataParameter.ActualValue; }
172    }
173    #endregion
174
175    [StorableConstructor]
176    private SymbolicExpressionTreeFragmentsAnalyzer(bool deserializing)
177      : base() {
178    }
179    private SymbolicExpressionTreeFragmentsAnalyzer(SymbolicExpressionTreeFragmentsAnalyzer original, Cloner cloner)
180      : base(original, cloner) {
181    }
182    public override IDeepCloneable Clone(Cloner cloner) {
183      return new SymbolicExpressionTreeFragmentsAnalyzer(this, cloner);
184    }
185    public SymbolicExpressionTreeFragmentsAnalyzer()
186      : base() {
187      // analyzer update counter and update interval
188      Parameters.Add(new ValueParameter<IntValue>(UpdateIntervalParameterName, "The interval in which the tree length analysis should be applied.", new IntValue(1)));
189      Parameters.Add(new ValueParameter<IntValue>(UpdateCounterParameterName, "The value which counts how many times the operator was called since the last update", new IntValue(0)));
190      // tracking
191      Parameters.Add(new LookupParameter<TraceMapType>(GlobalTraceMapParameterName, "A global cache containing the whole genealogy."));
192      Parameters.Add(new LookupParameter<CloneMapType>(GlobalCloneMapParameterName, "A global map keeping track of trees and their clones (made during selection)."));
193      Parameters.Add(new LookupParameter<CloneMapType>(GlobalFragmentMapParameterName, "A global map keeping track of tree fragments received via crossover."));
194      // secondary tracking
195      Parameters.Add(new LookupParameter<TraceMapType>(SecondaryTraceMapParameterName, "Parameter to store the trace map from the previous generation"));
196      Parameters.Add(new LookupParameter<CloneMapType>(SecondaryCloneMapParameterName, "Parameter to store the clone map from the previous generation"));
197      Parameters.Add(new LookupParameter<CloneMapType>(SecondaryFragmentMapParameterName, "Parameter to store the fragment map from the previous generation"));
198      // other params
199      Parameters.Add(new ValueLookupParameter<ResultCollection>(ResultsParameterName, "The results collection where the analysis values should be stored."));
200      Parameters.Add(new LookupParameter<IntValue>(GenerationsParameterName, "The number of generations so far."));
201      Parameters.Add(new LookupParameter<DataTable>(FragmentStatisticsParameterName, "The data table to store the fragment statistics."));
202      Parameters.Add(new LookupParameter<DataTable>(FragmentLengthsDistributionParametersName, "The data table to store the distribution of fragment lengths."));
203      Parameters.Add(new LookupParameter<DataTable>(FragmentFrequenciesParameterName, "A data structure for fragment frequencies"));
204      // impact calculation
205      Parameters.Add(new LookupParameter<SymbolicDataAnalysisExpressionTreeInterpreter>(SymbolicExpressionInterpreterParameterName, "Interpreter for symbolic expression trees"));
206      Parameters.Add(new LookupParameter<RegressionProblemData>(SymbolicRegressionProblemDataParameterName, "The symbolic data analysis problem."));
207      UpdateCounterParameter.Hidden = true;
208      UpdateIntervalParameter.Hidden = true;
209
210      //_calculator = new SymbolicRegressionSolutionValuesCalculator();
211    }
212    #region After deserialization code
213    [StorableHook(HookType.AfterDeserialization)]
214    private void AfterDeserialization() {
215      // check if all the parameters are present and accounted for
216      if (!Parameters.ContainsKey(UpdateIntervalParameterName)) {
217        Parameters.Add(new ValueParameter<IntValue>(UpdateIntervalParameterName, "The interval in which the tree length analysis should be applied.", new IntValue(1)));
218      }
219      if (!Parameters.ContainsKey(UpdateCounterParameterName)) {
220        Parameters.Add(new ValueParameter<IntValue>(UpdateCounterParameterName, "The value which counts how many times the operator was called since the last update", new IntValue(0)));
221        UpdateCounterParameter.Hidden = true;
222      }
223      if (!Parameters.ContainsKey(FragmentStatisticsParameterName)) {
224        Parameters.Add(new LookupParameter<DataTable>(FragmentStatisticsParameterName, "The data table to store the fragment statistics."));
225      }
226      if (!Parameters.ContainsKey(FragmentLengthsDistributionParametersName)) {
227        Parameters.Add(new LookupParameter<DataTable>(FragmentLengthsDistributionParametersName, "The data table to store the distribution of fragment lengths."));
228      }
229      if (!Parameters.ContainsKey(FragmentFrequenciesParameterName)) {
230        Parameters.Add(new LookupParameter<ItemList<ItemList<IItem>>>(FragmentFrequenciesParameterName, "A data structure for fragment frequencies"));
231      }
232    }
233    #endregion
234    #region IStatefulItem members
235    public override void InitializeState() {
236      base.InitializeState();
237      UpdateCounter.Value = 0;
238    }
239
240    public override void ClearState() {
241      base.ClearState();
242      UpdateCounter.Value = 0;
243    }
244    #endregion
245
246    public override IOperation Apply() {
247      if (Generations.Value == 0) return base.Apply();
248      UpdateCounter.Value++;
249      if (UpdateCounter.Value == UpdateInterval.Value) {
250        ResultCollection results = ResultsParameter.ActualValue;
251        if (FragmentStatistics == null) {
252          FragmentStatisticsParameter.ActualValue = new DataTable("Fragment Statistics", "Statistical measurements of fragments aggregated over the whole population");
253          FragmentStatistics.VisualProperties.YAxisTitle = "Fragment length/Similarities";
254          results.Add(new Result("Fragment Statistics", FragmentStatistics));
255        }
256        if (FragmentLengths == null) {
257          FragmentLengthsParameter.ActualValue = new DataTable("Fragment Lengths", "Histograms for the distribution of fragment and individual lengths");
258          FragmentLengths.VisualProperties.YAxisTitle = "Frequency";
259          results.Add(new Result("Fragment Lengths", FragmentLengths));
260        }
261        if (FragmentFrequencies == null) {
262          FragmentFrequenciesParameter.ActualValue = new DataTable("Fragment Frequencies", "Frequencies of good and high impact fragments");
263          FragmentFrequencies.VisualProperties.YAxisTitle = "Frequency";
264          results.Add(new Result("Fragment Frequencies", FragmentFrequencies));
265        }
266        if (SecondaryTraceMap == null) {
267          SecondaryTraceMap = new TraceMapType();
268        }
269        if (SecondaryCloneMap == null) {
270          SecondaryCloneMap = new CloneMapType();
271        }
272        if (SecondaryFragmentMap == null) {
273          SecondaryFragmentMap = new CloneMapType();
274        }
275
276        UpdateCounter.Value = 0; // reset counter
277        var gScope = ExecutionContext.Scope;
278        while (gScope.Parent != null) gScope = gScope.Parent;
279
280        // for this kind of tracking/analysis, we need at least 2 successive generations of crossover
281        if (Generations.Value > 1) {
282          #region Fragment Statistics
283          InitializeRows();
284          // create a dictionary for fast lookup of parents (to see which children from the previous generation become parents, and count their fragments)
285          var parentsLookup = new Dictionary<ISymbolicExpressionTree, bool>();
286          foreach (var parent in GlobalTraceMap.Values.SelectMany(x => x.Cast<ISymbolicExpressionTree>())) {
287            if (!parentsLookup.ContainsKey(parent)) {
288              parentsLookup.Add(parent, true);
289            }
290          }
291          // the same, for fast lookup of clones (might not be needed after all)
292          var clonesLookup = new Dictionary<ISymbolicExpressionTree, bool>();
293          foreach (var original in GlobalCloneMap.Values.Cast<ISymbolicExpressionTree>()) {
294            if (!clonesLookup.ContainsKey(original)) {
295              clonesLookup.Add(original, true);
296            }
297          }
298          var goodFragments = new List<ISymbolicExpressionTreeNode>();
299          var goodParents = new List<ISymbolicExpressionTree>();
300          var goodChildren = new List<ISymbolicExpressionTree>();
301          // take all individuals that have received a fragment in the previous generation
302          foreach (var m in SecondaryFragmentMap) {
303            var individual = m.Key as ISymbolicExpressionTree;
304            // check if the individual became a parent in the current generation,
305            // by checking if it appears among the parents from the current generation trace map
306            if (parentsLookup.ContainsKey(individual)) {
307              var fragmentItem = m.Value as SymbolicExpressionTreeNodeItem;
308              var fragment = fragmentItem.Content;
309              if (fragment != null) {
310                goodFragments.Add(fragmentItem.Content);
311                goodParents.AddRange(SecondaryTraceMap[individual].Cast<ISymbolicExpressionTree>());
312                goodChildren.Add(individual);
313              }
314            }
315          }
316          var allFragments = SecondaryFragmentMap.Values.Where(x => ((SymbolicExpressionTreeNodeItem)x).Content != null).Select(x => ((SymbolicExpressionTreeNodeItem)x).Content as ISymbolicExpressionTreeNode).ToList();
317          var highImpactFragments = new List<ISymbolicExpressionTreeNode>();
318          var allParents = SecondaryTraceMap.Values.SelectMany(x => x.Cast<ISymbolicExpressionTree>()).ToList();
319          var allChildren = SecondaryFragmentMap.Keys.Select(x => x as ISymbolicExpressionTree).ToList();
320          // high impact fragments
321          //foreach (var c in goodChildren) {
322          //  var impactValues = _calculator.CalculateImpactValues(c, SymbolicExpressionInterpreter, SymbolicRegressionProblemData, 0, 0);
323          //  var fragmentItem = SecondaryFragmentMap[c] as SymbolicExpressionTreeNodeItem;
324          //  var fragment = fragmentItem.Content;
325          //  if (fragment != null && impactValues[fragment] > 0.1)
326          //    highImpactFragments.Add(fragment);
327          //}
328          FragmentFrequencies.Rows["Frequency of useful fragments"].Values.Add(goodFragments.Count);
329          FragmentFrequencies.Rows["Frequency of high impact fragments"].Values.Add(highImpactFragments.Count);
330          FragmentStatistics.Rows["Fragment lengths (good)"].Values.Add(goodFragments.Average(x => x.GetLength()));
331          FragmentStatistics.Rows["Fragment lengths (all)"].Values.Add(allFragments.Average(x => x.GetLength()));
332          //double avg = highImpactFragments.Count > 0 ? highImpactFragments.Average(x => x.GetLength()) : 0;
333          //FragmentStatistics.Rows["Fragment lengths (high impact)"].Values.Add(avg);
334          FragmentStatistics.Rows["Parent lengths (good)"].Values.Add(goodParents.Average(x => x.Length));
335          FragmentStatistics.Rows["Parent lengths (all)"].Values.Add(allParents.Average(x => x.Length));
336          FragmentStatistics.Rows["Child lengths (good)"].Values.Add(goodChildren.Average(x => x.Length));
337          FragmentStatistics.Rows["Child lengths (all)"].Values.Add(allChildren.Average(x => x.Length));
338          FragmentStatistics.Rows["Avg visitation length (all children)"].Values.Add(allChildren.Average(x => VisitationLength(x)));
339          FragmentStatistics.Rows["Avg visitation length (good children)"].Values.Add(goodChildren.Average(x => VisitationLength(x)));
340          //FragmentStatistics.Rows["Exact similarity (good fragments)"].Values.Add(CalculateSimilarity(allFragments, (int)SymbolicExpressionTreeMatching.SimilarityLevel.Exact));
341          //foreach (var f in allFragments) f.SortSubtrees();
342          //FragmentStatistics.Rows["Exact similarity (all fragments)"].Values.Add(CalculateSimilarity(allFragments, (int)SymbolicExpressionTreeMatching.SimilarityLevel.Exact));
343
344          FragmentLengths.Rows["All fragments length distribution"].Values.Replace(allFragments.Select(x => (double)x.GetLength()));
345          FragmentLengths.Rows["Useful fragments length distribution"].Values.Replace(goodFragments.Select(x => (double)x.GetLength()));
346          FragmentLengths.Rows["All children length distribution"].Values.Replace(allChildren.Select(x => (double)x.Length));
347          FragmentLengths.Rows["Useful children length distribution"].Values.Replace(goodChildren.Select(x => (double)x.Length));
348          #endregion
349        }
350        // save the current generation so it can be compared to the following one, next time the analyzer is applied
351        SecondaryTraceMap.Clear();
352        foreach (var m in GlobalTraceMap)
353          SecondaryTraceMap.Add(m.Key, m.Value);
354
355        SecondaryCloneMap.Clear();
356        foreach (var m in GlobalCloneMap)
357          SecondaryCloneMap.Add(m.Key, m.Value);
358
359        SecondaryFragmentMap.Clear();
360        foreach (var m in GlobalFragmentMap)
361          SecondaryFragmentMap.Add(m.Key, m.Value);
362
363        // clear the global maps to save memory
364        if (this.Successor == null || !(this.Successor is SymbolicExpressionTreeGenealogyAnalyzer)) {
365          GlobalCloneMap.Clear();
366          GlobalTraceMap.Clear();
367          GlobalFragmentMap.Clear();
368        }
369      }
370      return base.Apply();
371    }
372
373    private void InitializeRows() {
374      if (!FragmentStatistics.Rows.ContainsKey("Parent lengths (good)")) {
375        FragmentStatistics.Rows.Add(new DataRow("Parent lengths (good)") {
376          VisualProperties = { StartIndexZero = true }
377        });
378      }
379      if (!FragmentStatistics.Rows.ContainsKey("Parent lengths (all)")) {
380        FragmentStatistics.Rows.Add(new DataRow("Parent lengths (all)") {
381          VisualProperties = { StartIndexZero = true }
382        });
383      }
384      if (!FragmentStatistics.Rows.ContainsKey("Child lengths (good)")) {
385        FragmentStatistics.Rows.Add(new DataRow("Child lengths (good)") {
386          VisualProperties = { StartIndexZero = true }
387        });
388      }
389      if (!FragmentStatistics.Rows.ContainsKey("Child lengths (all)")) {
390        FragmentStatistics.Rows.Add(new DataRow("Child lengths (all)") {
391          VisualProperties = { StartIndexZero = true }
392        });
393      }
394      if (!FragmentStatistics.Rows.ContainsKey("Fragment lengths (good)")) {
395        FragmentStatistics.Rows.Add(new DataRow("Fragment lengths (good)") {
396          VisualProperties = { StartIndexZero = true }
397        });
398      }
399      if (!FragmentStatistics.Rows.ContainsKey("Fragment lengths (all)")) {
400        FragmentStatistics.Rows.Add(new DataRow("Fragment lengths (all)") {
401          VisualProperties = { StartIndexZero = true }
402        });
403      }
404      if (!FragmentStatistics.Rows.ContainsKey("Fragment lengths (high impact)")) {
405        FragmentStatistics.Rows.Add(new DataRow("Fragment lengths (high impact)") {
406          VisualProperties = { StartIndexZero = true }
407        });
408      }
409      if (!FragmentStatistics.Rows.ContainsKey("Avg visitation length (all children)")) {
410        FragmentStatistics.Rows.Add(new DataRow("Avg visitation length (all children)") {
411          VisualProperties = { StartIndexZero = true }
412        });
413      }
414      if (!FragmentStatistics.Rows.ContainsKey("Avg visitation length (good children)")) {
415        FragmentStatistics.Rows.Add(new DataRow("Avg visitation length (good children)") {
416          VisualProperties = { StartIndexZero = true }
417        });
418      }
419      // exact similarity
420      if (!FragmentStatistics.Rows.ContainsKey("Exact similarity (good fragments)")) {
421        FragmentStatistics.Rows.Add(new DataRow("Exact similarity (good fragments)") {
422          VisualProperties = { StartIndexZero = true }
423        });
424      }
425      if (!FragmentStatistics.Rows.ContainsKey("Exact similarity (all fragments)")) {
426        FragmentStatistics.Rows.Add(new DataRow("Exact similarity (all fragments)") {
427          VisualProperties = { StartIndexZero = true }
428        });
429      }
430      if (!FragmentFrequencies.Rows.ContainsKey("Frequency of useful fragments")) {
431        FragmentFrequencies.Rows.Add(new DataRow("Frequency of useful fragments") {
432          VisualProperties = { StartIndexZero = true }
433        });
434      }
435      if (!FragmentFrequencies.Rows.ContainsKey("Frequency of high impact fragments")) {
436        FragmentFrequencies.Rows.Add(new DataRow("Frequency of high impact fragments") {
437          VisualProperties = { StartIndexZero = true }
438        });
439      }
440      double scaleFactor = 1.0;
441      if (!FragmentLengths.Rows.ContainsKey("All fragments length distribution"))
442        FragmentLengths.Rows.Add(new DataRow("All fragments length distribution") {
443          VisualProperties = {
444            StartIndexZero = true,
445            ChartType = DataRowVisualProperties.DataRowChartType.Histogram,
446            ScaleFactor = scaleFactor
447          }
448        });
449      if (!FragmentLengths.Rows.ContainsKey("Useful fragments length distribution"))
450        FragmentLengths.Rows.Add(new DataRow("Useful fragments length distribution") {
451          VisualProperties = {
452            StartIndexZero = true,
453            ChartType = DataRowVisualProperties.DataRowChartType.Histogram,
454            ScaleFactor = scaleFactor
455          }
456        });
457      if (!FragmentLengths.Rows.ContainsKey("All children length distribution"))
458        FragmentLengths.Rows.Add(new DataRow("All children length distribution") {
459          VisualProperties = {
460            StartIndexZero = true,
461            ChartType = DataRowVisualProperties.DataRowChartType.Histogram,
462            ScaleFactor = scaleFactor
463          }
464        });
465      if (!FragmentLengths.Rows.ContainsKey("Useful children length distribution"))
466        FragmentLengths.Rows.Add(new DataRow("Useful children length distribution") {
467          VisualProperties = {
468            StartIndexZero = true,
469            ChartType = DataRowVisualProperties.DataRowChartType.Histogram,
470            ScaleFactor = scaleFactor
471          }
472        });
473    }
474
475    private static int VisitationLength(ISymbolicExpressionTree tree) {
476      return VisitationLength(tree.Root);
477    }
478
479    private static int VisitationLength(ISymbolicExpressionTreeNode node) {
480      int sum = 0;
481      foreach (var n in node.IterateNodesBreadth())
482        sum += n.GetLength();
483      return sum;
484    }
485
486    #region Similarity computations
487    /// <summary>
488    /// Provide a measure of how similar the fragments that get passed by crossover from one generation to the next are.
489    /// </summary>
490    /// <param name="fragments">The symbolic expression tree fragments</param>
491    /// <param name="mode">The similarity mode (0 - exact, 1 - high, 2 - relaxed)</param>
492    /// <returns>The average number of similar fragments</returns>
493    private static double CalculateSimilarity(IList<ISymbolicExpressionTreeNode> fragments, int mode) {
494      var visited = new bool[fragments.Count];
495      int groups = 0;
496      for (int i = 0; i != fragments.Count - 1; ++i) {
497        if (visited[i]) continue;
498        for (int j = i + 1; j != fragments.Count; ++j) {
499          if (visited[j]) continue;
500          if (fragments[i].IsSimilarTo(fragments[j], mode)) visited[j] = true;
501        }
502        ++groups;
503      }
504      return (double)fragments.Count / groups;
505    }
506    #endregion
507  } //SymbolicExpressionTreeFragmentsAnalyzer
508}
Note: See TracBrowser for help on using the repository browser.