Free cookie consent management tool by TermsFeed Policy Generator

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

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

#1772: Added base class for the fragment analyzers. Improved analyzers, added SymbolicExpressionTreeRelativeFragmentDepthAnalyzer. Added LineageExplorer.

File size: 12.9 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 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 SymbolicExpressionTreeParameterName = "SymbolicExpressionTree";
46    private const string UpdateIntervalParameterName = "UpdateInterval";
47    private const string UpdateCounterParameterName = "UpdateCounter";
48    private const string ResultsParameterName = "Results";
49    private const string GenerationsParameterName = "Generations";
50    private const string StoreHistoryParameterName = "StoreHistory";
51    // comparer parameters
52    private const string MatchVariablesParameterName = "MatchVariableNames";
53    private const string MatchVariableWeightsParameterName = "MatchVariableWeights";
54    private const string MatchConstantValuesParameterName = "MatchConstantValues";
55    private const string SortSubtreesParameterName = "SortSubtrees";
56    // population graph
57    private const string PopulationGraphParameterName = "PopulationGraph";
58    // clone map
59    private const string GlobalCloneMapParameterName = "GlobalCloneMap";
60    #endregion
61
62    #region Parameters
63    public ValueParameter<IntValue> UpdateIntervalParameter {
64      get { return (ValueParameter<IntValue>)Parameters[UpdateIntervalParameterName]; }
65    }
66    public ValueParameter<IntValue> UpdateCounterParameter {
67      get { return (ValueParameter<IntValue>)Parameters[UpdateCounterParameterName]; }
68    }
69    public LookupParameter<ResultCollection> ResultsParameter {
70      get { return (LookupParameter<ResultCollection>)Parameters[ResultsParameterName]; }
71    }
72    public LookupParameter<IntValue> GenerationsParameter {
73      get { return (LookupParameter<IntValue>)Parameters[GenerationsParameterName]; }
74    }
75    public ValueParameter<BoolValue> StoreHistoryParameter {
76      get { return (ValueParameter<BoolValue>)Parameters[StoreHistoryParameterName]; }
77    }
78    public IScopeTreeLookupParameter<ISymbolicExpressionTree> SymbolicExpressionTreeParameter {
79      get { return (IScopeTreeLookupParameter<ISymbolicExpressionTree>)Parameters[SymbolicExpressionTreeParameterName]; }
80    }
81    public ValueParameter<BoolValue> MatchVariableNamesParameter {
82      get { return (ValueParameter<BoolValue>)Parameters[MatchVariablesParameterName]; }
83    }
84    public ValueParameter<BoolValue> MatchVariableWeightsParameter {
85      get { return (ValueParameter<BoolValue>)Parameters[MatchVariableWeightsParameterName]; }
86    }
87    public ValueParameter<BoolValue> MatchConstantValuesParameter {
88      get { return (ValueParameter<BoolValue>)Parameters[MatchConstantValuesParameterName]; }
89    }
90    public ValueParameter<BoolValue> SortSubtreesParameter {
91      get { return (ValueParameter<BoolValue>)Parameters[SortSubtreesParameterName]; }
92    }
93    public LookupParameter<CloneMapType> GlobalCloneMapParameter {
94      get { return (LookupParameter<CloneMapType>)Parameters[GlobalCloneMapParameterName]; }
95    }
96    #endregion
97
98    #region Parameter properties
99    public IntValue UpdateInterval {
100      get { return UpdateIntervalParameter.Value; }
101    }
102    public IntValue UpdateCounter {
103      get { return UpdateCounterParameter.Value; }
104    }
105    public ResultCollection Results {
106      get { return ResultsParameter.ActualValue; }
107    }
108    public CloneMapType GlobalCloneMap {
109      get { return GlobalCloneMapParameter.ActualValue; }
110    }
111    public IntValue Generations {
112      get { return GenerationsParameter.ActualValue; }
113    }
114    public BoolValue StoreHistory {
115      get { return StoreHistoryParameter.Value; }
116    }
117    #endregion
118
119    [StorableConstructor]
120    private SymbolicExpressionTreePopulationDiversityAnalyzer(bool deserializing) : base(deserializing) { }
121    private SymbolicExpressionTreePopulationDiversityAnalyzer(SymbolicExpressionTreePopulationDiversityAnalyzer original, Cloner cloner) : base(original, cloner) { }
122    public override IDeepCloneable Clone(Cloner cloner) {
123      return new SymbolicExpressionTreePopulationDiversityAnalyzer(this, cloner);
124    }
125    public SymbolicExpressionTreePopulationDiversityAnalyzer() {
126      // add parameters
127      Parameters.Add(new ScopeTreeLookupParameter<ISymbolicExpressionTree>(SymbolicExpressionTreeParameterName, "The symbolic expression trees to analyze."));
128      Parameters.Add(new ValueParameter<IntValue>(UpdateIntervalParameterName, "The interval in which the tree length analysis should be applied.", new IntValue(1)));
129      Parameters.Add(new ValueParameter<IntValue>(UpdateCounterParameterName, "The value which counts how many times the operator was called since the last update", new IntValue(0)));
130      Parameters.Add(new ValueLookupParameter<ResultCollection>(ResultsParameterName, "The results collection where the analysis values should be stored."));
131      Parameters.Add(new LookupParameter<IntValue>(GenerationsParameterName, "The number of generations so far."));
132      Parameters.Add(new ValueParameter<BoolValue>(MatchVariablesParameterName, "Specify if the symbolic expression tree comparer should match variable names."));
133      Parameters.Add(new ValueParameter<BoolValue>(MatchVariableWeightsParameterName, "Specify if the symbolic expression tree comparer should match variable weights."));
134      Parameters.Add(new ValueParameter<BoolValue>(MatchConstantValuesParameterName, "Specify if the symbolic expression tree comparer should match constant values."));
135      Parameters.Add(new ValueParameter<BoolValue>(SortSubtreesParameterName, "Specifies whether the subtrees of a tree should be sorted before comparison."));
136      Parameters.Add(new LookupParameter<CloneMapType>(GlobalCloneMapParameterName, "A global map keeping track of trees and their clones (made during selection)."));
137      Parameters.Add(new ValueParameter<BoolValue>(StoreHistoryParameterName, "True if the tree lengths history of the population should be stored.", new BoolValue(false)));
138      UpdateCounterParameter.Hidden = true;
139      UpdateIntervalParameter.Hidden = true;
140    }
141    [StorableHook(HookType.AfterDeserialization)]
142    private void AfterDeserialization() { }
143
144    #region IStatefulItem members
145    public override void InitializeState() {
146      base.InitializeState();
147      UpdateCounter.Value = 0;
148    }
149
150    public override void ClearState() {
151      base.ClearState();
152      UpdateCounter.Value = 0;
153    }
154    #endregion
155
156    public bool EnabledByDefault { get { return true; } }
157
158    public override IOperation Apply() {
159      UpdateCounter.Value++;
160
161      if (UpdateCounter.Value == UpdateInterval.Value) {
162        UpdateCounter.Value = 0;
163
164        var trees = SymbolicExpressionTreeParameter.ActualValue.ToList();
165        if (SortSubtreesParameter.Value.Value) {
166          var canonicalSorter = new SymbolicExpressionTreeCanonicalSorter();
167          foreach (var t in trees) canonicalSorter.SortSubtrees(t);
168        }
169
170        bool matchConstants = MatchConstantValuesParameter.Value.Value;
171        bool matchVarNames = MatchVariableNamesParameter.Value.Value;
172        bool matchVarWeights = MatchVariableWeightsParameter.Value.Value;
173
174        var comparer = new SymbolicExpressionTreeEqualityComparer {
175          SimilarityComparer = new SymbolicExpressionTreeNodeSimilarityComparer {
176            MatchConstantValues = matchConstants, MatchVariableNames = matchVarNames, MatchVariableWeights = matchVarWeights
177          }
178        };
179        ResultCollection results = ResultsParameter.ActualValue;
180        // population diversity
181        DataTable populationDiversityTable;
182        if (!results.ContainsKey("PopulationDiversity")) {
183          populationDiversityTable = new DataTable("PopulationDiversity") { VisualProperties = { YAxisTitle = "Diversity" } };
184          results.Add(new Result("PopulationDiversity", populationDiversityTable));
185        }
186        populationDiversityTable = (DataTable)results["PopulationDiversity"].Value;
187        if (!populationDiversityTable.Rows.ContainsKey("Diversity"))
188          populationDiversityTable.Rows.Add(new DataRow("Diversity") { VisualProperties = { StartIndexZero = true } });
189        double distinct = trees.Distinct(comparer).Count() / (double)trees.Count;
190        populationDiversityTable.Rows["Diversity"].Values.Add(distinct);
191        // selection diversity
192        if (GlobalCloneMap == null) return base.Apply();
193
194        DataTable relativeSelectionCountsTable;
195        if (!results.ContainsKey("SelectedIndividuals")) {
196          relativeSelectionCountsTable = new DataTable("SelectedIndividuals") { VisualProperties = { YAxisTitle = "% Selected Individuals" } };
197          results.Add(new Result("SelectedIndividuals", relativeSelectionCountsTable));
198        }
199        relativeSelectionCountsTable = (DataTable)Results["SelectedIndividuals"].Value;
200        if (!relativeSelectionCountsTable.Rows.ContainsKey("SelectedIndividuals")) {
201          relativeSelectionCountsTable.Rows.Add(new DataRow("SelectedIndividuals") { VisualProperties = { StartIndexZero = true } });
202        }
203        double relativeSelectionCount = GlobalCloneMap.Values.Distinct().Count() / (double)trees.Count;
204        relativeSelectionCountsTable.Rows["SelectedIndividuals"].Values.Add(relativeSelectionCount);
205
206        // do a histogram of selection frequency for each individual in the population
207        DataTable selectionFrequenciesTable;
208        if (!results.ContainsKey("SelectionFrequencies")) {
209          selectionFrequenciesTable = new DataTable("Selection Frequencies") { VisualProperties = { YAxisTitle = "Selection Count" } };
210          results.Add(new Result("SelectionFrequencies", selectionFrequenciesTable));
211        }
212        selectionFrequenciesTable = (DataTable)results["SelectionFrequencies"].Value;
213        DataRow histoRow;
214        if (!selectionFrequenciesTable.Rows.ContainsKey("SelectionFrequencies")) {
215          histoRow = new DataRow("SelectionFrequencies") { VisualProperties = { StartIndexZero = true } };
216          selectionFrequenciesTable.Rows.Add(histoRow);
217        }
218        histoRow = selectionFrequenciesTable.Rows["SelectionFrequencies"];
219        var frequencies = new double[trees.Count];
220
221        var graph = (SymbolicExpressionTreeGenealogyGraph)results[PopulationGraphParameterName].Value;
222        // get graph nodes corresponding to individuals of the previous generation
223        var prevGen = graph.Nodes.Where(node => node.Rank == Generations.Value - 1).OrderByDescending(n => n.Quality).ToList();
224        for (int i = 0; i != prevGen.Count; ++i) {
225          int selFreq = GlobalCloneMap.Values.Count(t => t == prevGen[i].SymbolicExpressionTree);
226          frequencies[i] = selFreq;
227        }
228        histoRow.Values.Replace(frequencies);
229
230        bool storeHistory = StoreHistory.Value;
231        if (storeHistory) {
232          DataTableHistory selectionFrequenciesHistory;
233          if (!results.ContainsKey("SelectionFrequenciesHistory")) {
234            selectionFrequenciesHistory = new DataTableHistory();
235            results.Add(new Result("SelectionFrequenciesHistory", selectionFrequenciesHistory));
236          }
237          selectionFrequenciesHistory = (DataTableHistory)results["SelectionFrequenciesHistory"].Value;
238          selectionFrequenciesHistory.Add((DataTable)selectionFrequenciesTable.Clone());
239        }
240      }
241      return base.Apply();
242    }
243  }
244}
Note: See TracBrowser for help on using the repository browser.