Free cookie consent management tool by TermsFeed Policy Generator

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

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

#1772: Refactoring of directed graph components, added code for correctly serializing vertices and edges. Added specific building blocks analyzers and new population diversity analyzer which correctly integrates with the parallel engine.

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