Free cookie consent management tool by TermsFeed Policy Generator

source: branches/HeuristicLab.EvolutionaryTracking/HeuristicLab.EvolutionaryTracking/3.4/Operators/SymbolicExpressionTreeGenealogyGraphBuilder.cs @ 9082

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

#1772: Renamed and refactored genealogy graph components. Added SymbolGraph and FPGraph (frequent pattern graph). Added evolvability and genetic operator average improvement analyzer.

File size: 13.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;
23using System.Collections.Generic;
24using System.Linq;
25using System.Threading;
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;
34using HeuristicLab.Problems.DataAnalysis;
35using HeuristicLab.Problems.DataAnalysis.Symbolic;
36// type definitions for ease of use
37using CloneMapType = HeuristicLab.Core.ItemDictionary<HeuristicLab.Core.IItem, HeuristicLab.Core.IItem>;
38using TraceMapType = HeuristicLab.Core.ItemDictionary<HeuristicLab.Core.IItem, HeuristicLab.Core.IItemList<HeuristicLab.Core.IItem>>;
39
40namespace HeuristicLab.EvolutionaryTracking {
41  /// <summary>
42  /// Builds a genealogy graph of the algorithms population.
43  /// </summary>
44  [Item("SymbolicExpressionTreeGenealogyGraphBuilder", "An operator that tracks the genealogy of tree individuals")]
45  [StorableClass]
46  public sealed class SymbolicExpressionTreeGenealogyGraphBuilder : SingleSuccessorOperator {
47    #region Parameter names
48    private const string ResultsParameterName = "Results";
49    private const string ElitesParameterName = "Elites";
50    private const string GenerationsParameterName = "Generations";
51    private const string MaximumGenerationsParameterName = "MaximumGenerations";
52    private const string MaximumSelectionPressureParameterName = "MaximumSelectionPressure";
53    private const string SelectionPressureParameterName = "SelectionPressure";
54    private const string GlobalTraceMapParameterName = "GlobalTraceMap";
55    private const string GlobalCloneMapParameterName = "GlobalCloneMap";
56    private const string GlobalFragmentMapParameterName = "GlobalFragmentMap";
57    private const string PopulationGraphParameterName = "PopulationGraph";
58    private const string PopulationGraphParameterDescription = "Individual lineages";
59    private const string SymbolicExpressionInterpreterParameterName = "SymbolicExpressionTreeInterpreter";
60    private const string SymbolicRegressionProblemDataParameterName = "ProblemData";
61    private const string SymbolicDataAnalysisProblemEvaluatorParameterName = "Evaluator";
62    private const string SymbolicExpressionTreeParameterName = "SymbolicExpressionTree";
63    private const string SymbolicExpressionTreeQualityParameterName = "Quality";
64    #endregion
65    #region Parameter properties
66    public IScopeTreeLookupParameter<ISymbolicExpressionTree> SymbolicExpressionTreeParameter {
67      get { return (IScopeTreeLookupParameter<ISymbolicExpressionTree>)Parameters[SymbolicExpressionTreeParameterName]; }
68    }
69    public IScopeTreeLookupParameter<DoubleValue> SymbolicExpressionTreeQualityParameter {
70      get { return (IScopeTreeLookupParameter<DoubleValue>)Parameters[SymbolicExpressionTreeQualityParameterName]; }
71    }
72    public LookupParameter<ResultCollection> ResultsParameter {
73      get { return (LookupParameter<ResultCollection>)Parameters[ResultsParameterName]; }
74    }
75    public LookupParameter<IntValue> ElitesParameter {
76      get { return (LookupParameter<IntValue>)Parameters[ElitesParameterName]; }
77    }
78    public LookupParameter<IntValue> GenerationsParameter {
79      get { return (LookupParameter<IntValue>)Parameters[GenerationsParameterName]; }
80    }
81    public LookupParameter<IntValue> MaximumGenerationsParameter {
82      get { return (LookupParameter<IntValue>)Parameters[MaximumGenerationsParameterName]; }
83    }
84    public LookupParameter<DoubleValue> SelectionPressureParameter {
85      get { return (LookupParameter<DoubleValue>)Parameters[SelectionPressureParameterName]; }
86    }
87    public LookupParameter<DoubleValue> MaximumSelectionPressureParameter {
88      get { return (LookupParameter<DoubleValue>)Parameters[MaximumSelectionPressureParameterName]; }
89    }
90    // problem data, interpreter and evaluator
91    public LookupParameter<SymbolicDataAnalysisExpressionTreeInterpreter> SymbolicExpressionInterpreterParameter {
92      get { return (LookupParameter<SymbolicDataAnalysisExpressionTreeInterpreter>)Parameters[SymbolicExpressionInterpreterParameterName]; }
93    }
94    public LookupParameter<RegressionProblemData> SymbolicRegressionProblemDataParameter {
95      get { return (LookupParameter<RegressionProblemData>)Parameters[SymbolicRegressionProblemDataParameterName]; }
96    }
97    public LookupParameter<IEvaluator> SymbolicDataAnalysisProblemEvaluatorParameter {
98      get { return (LookupParameter<IEvaluator>)Parameters[SymbolicDataAnalysisProblemEvaluatorParameterName]; }
99    }
100    // genealogy global parameters
101    public LookupParameter<TraceMapType> GlobalTraceMapParameter {
102      get { return (LookupParameter<TraceMapType>)Parameters[GlobalTraceMapParameterName]; }
103    }
104    public LookupParameter<CloneMapType> GlobalCloneMapParameter {
105      get { return (LookupParameter<CloneMapType>)Parameters[GlobalCloneMapParameterName]; }
106    }
107    public LookupParameter<CloneMapType> GlobalFragmentMapParameter {
108      get { return (LookupParameter<CloneMapType>)Parameters[GlobalFragmentMapParameterName]; }
109    }
110    #endregion
111    #region Properties
112    public bool EnabledByDefault {
113      get { return true; }
114    }
115    public ResultCollection Results {
116      get { return ResultsParameter.ActualValue; }
117    }
118    public IntValue Elites {
119      get { return ElitesParameter.ActualValue; }
120    }
121    public IntValue Generations {
122      get { return GenerationsParameter.ActualValue; }
123    }
124    public IntValue MaximumGenerations {
125      get { return MaximumGenerationsParameter.ActualValue; }
126    }
127    public DoubleValue SelectionPressure {
128      get { return SelectionPressureParameter.ActualValue; }
129    }
130    public DoubleValue MaximumSelectionPressure {
131      get { return MaximumSelectionPressureParameter.ActualValue; }
132    }
133    public CloneMapType GlobalCloneMap {
134      get { return GlobalCloneMapParameter.ActualValue; }
135    }
136    public TraceMapType GlobalTraceMap {
137      get { return GlobalTraceMapParameter.ActualValue; }
138    }
139    public CloneMapType GlobalFragmentMap {
140      get { return GlobalFragmentMapParameter.ActualValue; }
141    }
142    public SymbolicDataAnalysisExpressionTreeInterpreter SymbolicExpressionInterpreter {
143      get { return SymbolicExpressionInterpreterParameter.ActualValue; }
144    }
145    public RegressionProblemData SymbolicRegressionProblemData {
146      get { return SymbolicRegressionProblemDataParameter.ActualValue; }
147    }
148    public IEvaluator SymbolicDataAnalysisEvaluator {
149      get { return SymbolicDataAnalysisProblemEvaluatorParameter.ActualValue; }
150    }
151    #endregion
152
153    [StorableConstructor]
154    private SymbolicExpressionTreeGenealogyGraphBuilder(bool deserializing) : base(deserializing) { }
155    private SymbolicExpressionTreeGenealogyGraphBuilder(SymbolicExpressionTreeGenealogyGraphBuilder original, Cloner cloner) : base(original, cloner) { }
156    public override IDeepCloneable Clone(Cloner cloner) { return new SymbolicExpressionTreeGenealogyGraphBuilder(this, cloner); }
157    public SymbolicExpressionTreeGenealogyGraphBuilder()
158      : base() {
159      #region Add parameters
160      Parameters.Add(new LookupParameter<IntValue>(ElitesParameterName, "The number of elites."));
161      Parameters.Add(new LookupParameter<IntValue>(GenerationsParameterName, "The number of generations so far."));
162      Parameters.Add(new LookupParameter<IntValue>(MaximumGenerationsParameterName, "The maximum number of generations"));
163      Parameters.Add(new LookupParameter<DoubleValue>(SelectionPressureParameterName, "The current selection (ony for OSGA)"));
164      Parameters.Add(new LookupParameter<DoubleValue>(MaximumSelectionPressureParameterName, "Maximum allowed value of selection pressure."));
165      Parameters.Add(new LookupParameter<TraceMapType>(GlobalTraceMapParameterName, "A global cache containing the whole genealogy."));
166      Parameters.Add(new LookupParameter<CloneMapType>(GlobalCloneMapParameterName, "A global map keeping track of trees and their clones (made during selection)."));
167      Parameters.Add(new LookupParameter<CloneMapType>(GlobalFragmentMapParameterName, "A global map keeping track of tree fragments received via crossover."));
168      Parameters.Add(new ValueLookupParameter<ResultCollection>(ResultsParameterName, "The results collection where the analysis values should be stored."));
169      Parameters.Add(new LookupParameter<SymbolicDataAnalysisExpressionTreeInterpreter>(SymbolicExpressionInterpreterParameterName, "Interpreter for symbolic expression trees"));
170      Parameters.Add(new LookupParameter<RegressionProblemData>(SymbolicRegressionProblemDataParameterName, "The symbolic data analysis problem."));
171      Parameters.Add(new LookupParameter<IEvaluator>(SymbolicDataAnalysisProblemEvaluatorParameterName, "The fitness evaluator"));
172      Parameters.Add(new ScopeTreeLookupParameter<ISymbolicExpressionTree>(SymbolicExpressionTreeParameterName, "The symbolic expression trees to analyze"));
173      Parameters.Add(new ScopeTreeLookupParameter<DoubleValue>(SymbolicExpressionTreeQualityParameterName, "The qualities of the symbolic expression trees"));
174      #endregion
175    }
176
177    [StorableHook(HookType.AfterDeserialization)]
178    private void AfterDeserialization() { }
179
180    #region IStatefulItem members
181    public override void InitializeState() {
182      base.InitializeState();
183    }
184
185    public override void ClearState() {
186      base.ClearState();
187    }
188    #endregion
189
190    public override IOperation Apply() {
191      if (GlobalTraceMap == null) return base.Apply(); // no trace map, no genealogy graph
192
193      if (!Parameters.ContainsKey("Results")) return base.Apply();
194
195      SymbolicExpressionTreeGenealogyGraph graph;
196      if (Results.ContainsKey(PopulationGraphParameterName)) {
197        graph = (SymbolicExpressionTreeGenealogyGraph)(Results[PopulationGraphParameterName].Value);
198      } else {
199        graph = new SymbolicExpressionTreeGenealogyGraph();
200        Results.Add(new Result(PopulationGraphParameterName, PopulationGraphParameterDescription, graph));
201      }
202
203      var trees = SymbolicExpressionTreeParameter.ActualValue.ToArray();
204      var qualities = SymbolicExpressionTreeQualityParameter.ActualValue.ToArray();
205
206      if (trees.Length != qualities.Length) throw new Exception("Error: trees and qualities array sizes do not match!");
207
208      // add all individuals to the evolutionary graph
209      int generation = Generations.Value;
210
211      var pairs = trees.Zip(qualities, (t, q) => new { Tree = t, Quality = q.Value }).OrderByDescending(x => x.Quality).ToList();
212
213      var graphNodes = new List<SymbolicExpressionGenealogyGraphNode>(
214        (from i in Enumerable.Range(0, trees.Length)
215         let tree = pairs[i].Tree
216         let quality = pairs[i].Quality
217         select new SymbolicExpressionGenealogyGraphNode { SymbolicExpressionTree = tree, Quality = quality, Rank = generation, IsElite = i < Elites.Value }
218        ).Concat
219        (from t in trees
220         where GlobalTraceMap.ContainsKey(t)
221         let parents = GlobalTraceMap[t]
222         where parents.Count == 1 // 1 parent means mutation
223         let p = (ISymbolicExpressionTree)parents[0]
224         select new SymbolicExpressionGenealogyGraphNode { SymbolicExpressionTree = p, Quality = Evaluate(p), Rank = generation - 0.5 }
225        )).ToList();
226
227      foreach (var node in graphNodes) {
228        graph.AddNode(node);
229      }
230
231      foreach (var node in graphNodes) {
232        var tree = node.SymbolicExpressionTree;
233        if (!GlobalTraceMap.ContainsKey(tree)) continue;
234        var parents = GlobalTraceMap[tree].Cast<ISymbolicExpressionTree>();
235        foreach (var p in parents) {
236          var nodes = graph.GetGraphNodes(p);
237          if (nodes == null) continue;
238          var sourceNode = nodes.LastOrDefault(n => n.Rank < node.Rank);
239          if (sourceNode == null) continue;
240          var arc = new Arc { Source = sourceNode, Target = node, Data = GlobalFragmentMap[tree] };
241          sourceNode.AddForwardArc(arc);
242          node.AddReverseArc(arc);
243        }
244      }
245      return base.Apply();
246    }
247
248    /// <summary>
249    /// Evaluate a symbolic expression tree. We perform evaluation by adding a temporary subscope with the tree in it, and calling evaluator.Apply()
250    /// </summary>
251    /// <param name="tree"></param>
252    /// <returns></returns>
253    private double Evaluate(IItem tree) {
254      var subScope = new Scope();
255      subScope.Variables.Add(new Core.Variable("SymbolicExpressionTree", tree)); // inject expected variables into the subscope
256      ExecutionContext.Scope.SubScopes.Add(subScope);
257      var context = new Core.ExecutionContext(ExecutionContext, SymbolicDataAnalysisEvaluator, subScope);
258      SymbolicDataAnalysisEvaluator.Execute(context, new CancellationToken()); // call evaluator.Apply()
259      double quality = ((DoubleValue)subScope.Variables["Quality"].Value).Value; // get the quality
260      ExecutionContext.Scope.SubScopes.Remove(subScope); // remove the subscope
261      return quality;
262    }
263  }
264}
Note: See TracBrowser for help on using the repository browser.