source: branches/HeuristicLab.BottomUpTreeDistance/HeuristicLab.Problems.DataAnalysis.Symbolic/3.4/Analyzers/SymbolicDataAnalysisInternalDiversityAnalyzer.cs @ 11224

Last change on this file since 11224 was 11224, checked in by bburlacu, 7 years ago

#2215: Added checks for debugging purposes in the BottomUpSimilarityCalculator and refactored the SymbolicDataAnalysisInternalDiversityAnalyzer.

File size: 5.9 KB
Line 
1#region License Information
2/* HeuristicLab
3 * Copyright (C) 2002-2014 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.Collections.Generic;
24using System.Linq;
25using HeuristicLab.Analysis;
26using HeuristicLab.Common;
27using HeuristicLab.Core;
28using HeuristicLab.Data;
29using HeuristicLab.Encodings.SymbolicExpressionTreeEncoding;
30using HeuristicLab.Operators;
31using HeuristicLab.Optimization;
32using HeuristicLab.Parameters;
33using HeuristicLab.Persistence.Default.CompositeSerializers.Storable;
34
35namespace HeuristicLab.Problems.DataAnalysis.Symbolic.Analyzers {
36  [StorableClass]
37  [Item("SymbolicDataAnalysisInternalDiversityAnalyzer", "An analyzer that determines the average diversity of symbolic expression trees.")]
38  public class SymbolicDataAnalysisInternalDiversityAnalyzer : SingleSuccessorOperator, ISymbolicDataAnalysisAnalyzer {
39    private const string SymbolicExpressionTreeParameterName = "SymbolicExpressionTree";
40    private const string QualityParameterName = "Quality";
41    private const string PercentageOfBestSolutionsParameterName = "PercentageOfBestSolutions";
42
43    private const string ResultCollectionParameterName = "Results";
44    private readonly BottomUpSimilarityCalculator busCalculator;
45
46    public SymbolicDataAnalysisInternalDiversityAnalyzer() {
47      busCalculator = new BottomUpSimilarityCalculator();
48
49      Parameters.Add(new ScopeTreeLookupParameter<ISymbolicExpressionTree>(SymbolicExpressionTreeParameterName));
50      Parameters.Add(new ScopeTreeLookupParameter<DoubleValue>(QualityParameterName));
51      Parameters.Add(new LookupParameter<ResultCollection>(ResultCollectionParameterName));
52      Parameters.Add(new FixedValueParameter<PercentValue>(PercentageOfBestSolutionsParameterName));
53    }
54
55    protected SymbolicDataAnalysisInternalDiversityAnalyzer(SymbolicDataAnalysisInternalDiversityAnalyzer original, Cloner cloner)
56      : base(original, cloner) {
57    }
58
59    public override IDeepCloneable Clone(Cloner cloner) {
60      return new SymbolicDataAnalysisInternalDiversityAnalyzer(this, cloner);
61    }
62
63    #region parameter properties
64    public IScopeTreeLookupParameter<ISymbolicExpressionTree> SymbolicExpressionTreeParameter {
65      get { return (IScopeTreeLookupParameter<ISymbolicExpressionTree>)Parameters[SymbolicExpressionTreeParameterName]; }
66    }
67
68    public IScopeTreeLookupParameter<DoubleValue> QualityParameter {
69      get { return (IScopeTreeLookupParameter<DoubleValue>)Parameters[QualityParameterName]; }
70    }
71
72    public ILookupParameter<ResultCollection> ResultCollectionParameter {
73      get { return (ILookupParameter<ResultCollection>)Parameters[ResultCollectionParameterName]; }
74    }
75
76    public IFixedValueParameter<PercentValue> PercentageOfBestSolutionsParameter {
77      get { return (IFixedValueParameter<PercentValue>)Parameters[PercentageOfBestSolutionsParameterName]; }
78    }
79    #endregion
80
81    public double PercentageOfBestSolutions {
82      get { return PercentageOfBestSolutionsParameter.Value.Value; }
83      set { PercentageOfBestSolutionsParameter.Value.Value = value; }
84    }
85
86    public bool EnabledByDefault { get { return true; } }
87
88    public override IOperation Apply() {
89
90      var results = ResultCollectionParameter.ActualValue;
91
92      DataTable table;
93      if (!results.ContainsKey("Avg. Internal Diversity")) {
94        table = new DataTable("Internal Diversity") { VisualProperties = { YAxisTitle = "Internal Diversity" } };
95        var row = new DataRow("Avg. Internal Diversity") { VisualProperties = { StartIndexZero = true } };
96        table.Rows.Add(row);
97        results.Add(new Result("Avg. Internal Diversity", table));
98      } else {
99        table = (DataTable)results["Avg. Internal Diversity"].Value;
100      }
101
102      var trees = SymbolicExpressionTreeParameter.ActualValue.ToArray();
103      var qualities = QualityParameter.ActualValue.ToArray();
104
105      Array.Sort(qualities, trees, new ReverseComparer());
106      int n = (int)Math.Floor(trees.Length * PercentageOfBestSolutions);
107
108      double avgInternalDiversity = trees.Take(n).Average(tree => CalculateInternalDiversity(tree));
109
110      table.Rows["Avg. Internal Diversity"].Values.Add(avgInternalDiversity);
111      return base.Apply();
112    }
113
114    private double CalculateInternalDiversity(ISymbolicExpressionTree tree) {
115      var branchPoint = tree.IterateNodesPrefix().FirstOrDefault(x => x.SubtreeCount == 2);
116      if (branchPoint == null)
117        return 1;
118
119      var s1 = branchPoint.GetSubtree(0);
120      var s2 = branchPoint.GetSubtree(1);
121
122      // set parents to null because otherwise the bottom-up calculator will throw an exception
123      var p1 = s1.Parent;
124      s1.Parent = null;
125      var p2 = s2.Parent;
126      s2.Parent = null;
127
128      var m = busCalculator.ComputeBottomUpMapping(s1, s2);
129      var diversity = 1 - 2.0 * m.Count / (s1.GetLength() + s2.GetLength());
130
131      // restore parents
132      s1.Parent = p1;
133      s2.Parent = p2;
134
135      return diversity;
136    }
137  }
138
139  internal class ReverseComparer : IComparer<DoubleValue> {
140    public int Compare(DoubleValue x, DoubleValue y) {
141      return y.CompareTo(x);
142    }
143  }
144}
Note: See TracBrowser for help on using the repository browser.