Free cookie consent management tool by TermsFeed Policy Generator

source: branches/HeuristicLab.EvolutionTracking/HeuristicLab.EvolutionaryTracking/3.4/Analyzers/SymbolicExpressionTreePopulationDiversityAnalyzer.cs @ 10264

Last change on this file since 10264 was 10264, checked in by bburlacu, 11 years ago

#1772: Created new branch for the redesigned version of the tracking plugin

File size: 12.9 KB
RevLine 
[10264]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.Linq;
23using HeuristicLab.Analysis;
24using HeuristicLab.Common;
25using HeuristicLab.Core;
26using HeuristicLab.Data;
27using HeuristicLab.Encodings.SymbolicExpressionTreeEncoding;
28using HeuristicLab.Operators;
29using HeuristicLab.Optimization;
30using HeuristicLab.Parameters;
31using HeuristicLab.Persistence.Default.CompositeSerializers.Storable;
32using HeuristicLab.Problems.DataAnalysis.Symbolic;
33
34// type definitions for ease of use
35using CloneMapType = HeuristicLab.Core.ItemDictionary<HeuristicLab.Core.IItem, HeuristicLab.Core.IItem>;
36
37namespace HeuristicLab.EvolutionaryTracking {
38  /// <summary>
39  /// Population diversity analyzer
40  /// </summary>
41  [Item("SymbolicExpressionTreePopulationDiversityAnalyzer", "An operator that tracks population diversity")]
42  [StorableClass]
43  public sealed class SymbolicExpressionTreePopulationDiversityAnalyzer : SingleSuccessorOperator, IAnalyzer {
44    #region Parameter names
45    private const string MaximumSymbolicExpressionTreeDepthParameterName = "MaximumSymbolicExpressionTreeDepth";
46    private const string SymbolicExpressionTreeParameterName = "SymbolicExpressionTree";
47    private const string UpdateIntervalParameterName = "UpdateInterval";
48    private const string UpdateCounterParameterName = "UpdateCounter";
49    private const string ResultsParameterName = "Results";
50    private const string GenerationsParameterName = "Generations";
51    private const string StoreHistoryParameterName = "StoreHistory";
52    // comparer parameters
53    private const string MatchVariablesParameterName = "MatchVariableNames";
54    private const string MatchVariableWeightsParameterName = "MatchVariableWeights";
55    private const string MatchConstantValuesParameterName = "MatchConstantValues";
56    private const string SortSubtreesParameterName = "SortSubtrees";
57    private const string SimilarityValuesParmeterName = "Similarity";
58    // clone map
59    private const string GlobalCloneMapParameterName = "GlobalCloneMap";
60
61    #endregion
62
63    #region Parameters
64    public IValueLookupParameter<IntValue> MaximumSymbolicExpressionTreeDepthParameter {
65      get { return (IValueLookupParameter<IntValue>)Parameters[MaximumSymbolicExpressionTreeDepthParameterName]; }
66    }
67    public ValueParameter<IntValue> UpdateIntervalParameter {
68      get { return (ValueParameter<IntValue>)Parameters[UpdateIntervalParameterName]; }
69    }
70    public ValueParameter<IntValue> UpdateCounterParameter {
71      get { return (ValueParameter<IntValue>)Parameters[UpdateCounterParameterName]; }
72    }
73    public LookupParameter<ResultCollection> ResultsParameter {
74      get { return (LookupParameter<ResultCollection>)Parameters[ResultsParameterName]; }
75    }
76    public LookupParameter<IntValue> GenerationsParameter {
77      get { return (LookupParameter<IntValue>)Parameters[GenerationsParameterName]; }
78    }
79    public ValueParameter<BoolValue> StoreHistoryParameter {
80      get { return (ValueParameter<BoolValue>)Parameters[StoreHistoryParameterName]; }
81    }
82    public IScopeTreeLookupParameter<ISymbolicExpressionTree> SymbolicExpressionTreeParameter {
83      get { return (IScopeTreeLookupParameter<ISymbolicExpressionTree>)Parameters[SymbolicExpressionTreeParameterName]; }
84    }
85    public ValueParameter<BoolValue> MatchVariableNamesParameter {
86      get { return (ValueParameter<BoolValue>)Parameters[MatchVariablesParameterName]; }
87    }
88    public ValueParameter<BoolValue> MatchVariableWeightsParameter {
89      get { return (ValueParameter<BoolValue>)Parameters[MatchVariableWeightsParameterName]; }
90    }
91    public ValueParameter<BoolValue> MatchConstantValuesParameter {
92      get { return (ValueParameter<BoolValue>)Parameters[MatchConstantValuesParameterName]; }
93    }
94    public ValueParameter<BoolValue> SortSubtreesParameter {
95      get { return (ValueParameter<BoolValue>)Parameters[SortSubtreesParameterName]; }
96    }
97    public LookupParameter<CloneMapType> GlobalCloneMapParameter {
98      get { return (LookupParameter<CloneMapType>)Parameters[GlobalCloneMapParameterName]; }
99    }
100    public ILookupParameter<DoubleValue> SimilarityParameter {
101      get { return (ILookupParameter<DoubleValue>)Parameters[SimilarityValuesParmeterName]; }
102    }
103    #endregion
104
105    #region Parameter properties
106    public IntValue MaximumSymbolicExpressionTreeDepth { get { return MaximumSymbolicExpressionTreeDepthParameter.ActualValue; } }
107    public IntValue UpdateInterval { get { return UpdateIntervalParameter.Value; } }
108    public IntValue UpdateCounter { get { return UpdateCounterParameter.Value; } }
109    public ResultCollection Results { get { return ResultsParameter.ActualValue; } }
110    public CloneMapType GlobalCloneMap { get { return GlobalCloneMapParameter.ActualValue; } }
111    public IntValue Generations { get { return GenerationsParameter.ActualValue; } }
112    public BoolValue StoreHistory { get { return StoreHistoryParameter.Value; } }
113    #endregion
114
115    [StorableConstructor]
116    private SymbolicExpressionTreePopulationDiversityAnalyzer(bool deserializing)
117      : base(deserializing) {
118    }
119
120    private SymbolicExpressionTreePopulationDiversityAnalyzer(
121      SymbolicExpressionTreePopulationDiversityAnalyzer original, Cloner cloner)
122      : base(original, cloner) {
123    }
124
125    public override IDeepCloneable Clone(Cloner cloner) {
126      return new SymbolicExpressionTreePopulationDiversityAnalyzer(this, cloner);
127    }
128
129    public SymbolicExpressionTreePopulationDiversityAnalyzer() {
130      // add parameters
131      Parameters.Add(new ScopeTreeLookupParameter<ISymbolicExpressionTree>(SymbolicExpressionTreeParameterName, "The symbolic expression trees to analyze."));
132      Parameters.Add(new ValueParameter<IntValue>(UpdateIntervalParameterName, "The interval in which the tree length analysis should be applied.", new IntValue(1)));
133      Parameters.Add(new ValueParameter<IntValue>(UpdateCounterParameterName, "The value which counts how many times the operator was called since the last update", new IntValue(0)));
134      Parameters.Add(new ValueLookupParameter<ResultCollection>(ResultsParameterName, "The results collection where the analysis values should be stored."));
135      Parameters.Add(new LookupParameter<IntValue>(GenerationsParameterName, "The number of generations so far."));
136      Parameters.Add(new ValueParameter<BoolValue>(MatchVariablesParameterName, "Specify if the symbolic expression tree comparer should match variable names.", new BoolValue(true)));
137      Parameters.Add(new ValueParameter<BoolValue>(MatchVariableWeightsParameterName, "Specify if the symbolic expression tree comparer should match variable weights.", new BoolValue(true)));
138      Parameters.Add(new ValueParameter<BoolValue>(MatchConstantValuesParameterName, "Specify if the symbolic expression tree comparer should match constant values.", new BoolValue(true)));
139      Parameters.Add(new ValueParameter<BoolValue>(SortSubtreesParameterName, "Specifies whether the subtrees of a tree should be sorted before comparison."));
140      Parameters.Add(new LookupParameter<CloneMapType>(GlobalCloneMapParameterName, "A global map keeping track of trees and their clones (made during selection)."));
141      Parameters.Add(new ValueParameter<BoolValue>(StoreHistoryParameterName, "True if the tree lengths history of the population should be stored.", new BoolValue(false)));
142      Parameters.Add(new LookupParameter<DoubleValue>(SimilarityValuesParmeterName, ""));
143      Parameters.Add(new ValueLookupParameter<IntValue>(MaximumSymbolicExpressionTreeDepthParameterName, "The maximal depth of the symbolic expression tree (a tree with one node has depth = 0)."));
144      UpdateCounterParameter.Hidden = true;
145      UpdateIntervalParameter.Hidden = true;
146    }
147
148    [StorableHook(HookType.AfterDeserialization)]
149    private void AfterDeserialization() {
150      if (!Parameters.ContainsKey(MaximumSymbolicExpressionTreeDepthParameterName)) {
151        Parameters.Add(new ValueLookupParameter<IntValue>(MaximumSymbolicExpressionTreeDepthParameterName, "The maximal depth of the symbolic expression tree (a tree with one node has depth = 0)."));
152      }
153    }
154
155    #region IStatefulItem members
156    public override void InitializeState() {
157      UpdateCounter.Value = 0;
158      base.InitializeState();
159    }
160    #endregion
161
162    public bool EnabledByDefault {
163      get { return true; }
164    }
165
166    public override IOperation Apply() {
167      if (SimilarityParameter.ActualValue == null || SimilarityParameter.ActualValue.Value.IsAlmost(-1.0)) {
168        UpdateCounter.Value++;
169        if (UpdateCounter.Value != UpdateInterval.Value) return base.Apply();
170        UpdateCounter.Value = 0;
171        var trees = SymbolicExpressionTreeParameter.ActualValue.ToList();
172        if (SortSubtreesParameter.Value.Value) {
173          var canonicalSorter = new SymbolicExpressionTreeCanonicalSorter();
174          foreach (var t in trees) canonicalSorter.SortSubtrees(t);
175        }
176
177        SimilarityParameter.ActualValue = new DoubleValue();
178        // needed only with the old (and inefficient) geneticitem-based similarity measure
179        //        var geneticItems = trees.ToDictionary(tree => tree, tree => tree.GetGeneticItems(1, MaximumSymbolicExpressionTreeDepth.Value - 2).ToArray());
180
181        var comp = new SymbolicExpressionTreeNodeSimilarityComparer {
182          MatchConstantValues = MatchConstantValuesParameter.Value.Value,
183          MatchVariableNames = MatchVariableNamesParameter.Value.Value,
184          MatchVariableWeights = MatchVariableWeightsParameter.Value.Value
185        };
186
187        var operations = new OperationCollection { Parallel = true };
188        foreach (var tree in trees) {
189          var op = new SymbolicDataAnalysisExpressionTreeSimilarityCalculator { CurrentSymbolicExpressionTree = tree, SimilarityComparer = comp, MaximumTreeDepth = MaximumSymbolicExpressionTreeDepth.Value };
190          var operation = ExecutionContext.CreateChildOperation(op, ExecutionContext.Scope);
191          operations.Add(operation);
192        }
193        return new OperationCollection { operations, ExecutionContext.CreateOperation(this) };
194      }
195
196      ResultCollection results = ResultsParameter.ActualValue;
197      // population diversity
198      DataTable populationDiversityTable;
199      if (!results.ContainsKey("PopulationDiversity")) {
200        populationDiversityTable = new DataTable("PopulationDiversity") { VisualProperties = { YAxisTitle = "Diversity" } };
201        results.Add(new Result("PopulationDiversity", populationDiversityTable));
202      }
203      populationDiversityTable = (DataTable)results["PopulationDiversity"].Value;
204      if (!populationDiversityTable.Rows.ContainsKey("Diversity"))
205        populationDiversityTable.Rows.Add(new DataRow("Diversity") { VisualProperties = { StartIndexZero = true } });
206
207      int length = SymbolicExpressionTreeParameter.ActualValue.Length;
208      var similarity = SimilarityParameter.ActualValue.Value / (length * (length - 1) / 2.0);
209      var diversity = 1 - similarity;
210      SimilarityParameter.ActualValue.Value = -1.0;
211
212      populationDiversityTable.Rows["Diversity"].Values.Add(diversity);
213
214      // selection diversity
215      if (GlobalCloneMap == null) return base.Apply();
216      DataTable relativeSelectionCountsTable;
217      if (!results.ContainsKey("SelectedIndividuals")) {
218        relativeSelectionCountsTable = new DataTable("SelectedIndividuals") { VisualProperties = { YAxisTitle = "% Selected Individuals" } };
219        results.Add(new Result("SelectedIndividuals", relativeSelectionCountsTable));
220      }
221      relativeSelectionCountsTable = (DataTable)Results["SelectedIndividuals"].Value;
222      if (!relativeSelectionCountsTable.Rows.ContainsKey("SelectedIndividuals")) {
223        relativeSelectionCountsTable.Rows.Add(new DataRow("SelectedIndividuals") { VisualProperties = { StartIndexZero = true } });
224      }
225      double relativeSelectionCount = GlobalCloneMap.Values.Distinct().Count() / (double)SymbolicExpressionTreeParameter.ActualValue.Length;
226      relativeSelectionCountsTable.Rows["SelectedIndividuals"].Values.Add(relativeSelectionCount);
227
228      return base.Apply();
229    }
230  }
231}
Note: See TracBrowser for help on using the repository browser.