Free cookie consent management tool by TermsFeed Policy Generator

source: branches/HeuristicLab.EvolutionaryTracking/HeuristicLab.Encodings.SymbolicExpressionTreeEncoding/3.4/Crossovers/TracingSymbolicExpressionTreeCrossover.cs @ 7792

Last change on this file since 7792 was 7792, checked in by bburlacu, 12 years ago

#1772: Changelog:

  • Removed GetCutIndex method, and corresponding index field in the GenealogyGraphNode.
  • Implemented tracking for mutated fragments.
  • Improved FindMatch method.
  • Added IterateNodesBreadth functionality to symbolic expression trees and nodes.
  • Added check conditions for clearing global tracking structures so that the 2 analyzers are not mutually exclusive anymore.
File size: 7.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;
23using System.Collections.Generic;
24using System.Linq;
25using HeuristicLab.Common;
26using HeuristicLab.Core;
27using HeuristicLab.Data;
28using HeuristicLab.Parameters;
29using HeuristicLab.Persistence.Default.CompositeSerializers.Storable;
30
31using CloneMapType = HeuristicLab.Core.ItemDictionary<HeuristicLab.Core.IItem, HeuristicLab.Core.IItem>;
32using TraceMapType = HeuristicLab.Core.ItemDictionary<HeuristicLab.Core.IItem, HeuristicLab.Core.IItemList<HeuristicLab.Core.IItem>>;
33
34namespace HeuristicLab.Encodings.SymbolicExpressionTreeEncoding {
35  /// <summary>
36  /// A base class for operators that perform a crossover of symbolic expression trees.
37  /// </summary>
38  [Item("SymbolicExpressionTreeCrossover", "A base class for operators that perform a crossover of symbolic expression trees.")]
39  [StorableClass]
40  public abstract class TracingSymbolicExpressionTreeCrossover : SymbolicExpressionTreeOperator, ISymbolicExpressionTreeCrossover {
41    private const string ParentsParameterName = "Parents";
42    private const string ChildParameterName = "Child";
43    private const string GlobalTraceMapParameterName = "GlobalTraceMap";
44    private const string GlobalCloneMapParameterName = "GlobalCloneMap";
45    private const string GlobalFragmentMapParameterName = "GlobalFragmentMap";
46
47    #region Parameter Properties
48    public ILookupParameter<ItemArray<ISymbolicExpressionTree>> ParentsParameter {
49      get { return (ScopeTreeLookupParameter<ISymbolicExpressionTree>)Parameters[ParentsParameterName]; }
50    }
51    public ILookupParameter<ISymbolicExpressionTree> ChildParameter {
52      get { return (ILookupParameter<ISymbolicExpressionTree>)Parameters[ChildParameterName]; }
53    }
54    public LookupParameter<CloneMapType> GlobalCloneMapParameter {
55      get { return (LookupParameter<CloneMapType>)Parameters[GlobalCloneMapParameterName]; }
56    }
57    public LookupParameter<TraceMapType> GlobalTraceMapParameter {
58      get { return (LookupParameter<TraceMapType>)Parameters[GlobalTraceMapParameterName]; }
59    }
60    public LookupParameter<CloneMapType> GlobalFragmentMapParameter {
61      get { return (LookupParameter<CloneMapType>)Parameters[GlobalFragmentMapParameterName]; }
62    }
63    #endregion
64
65    #region Properties
66    public ItemArray<ISymbolicExpressionTree> Parents {
67      get { return ParentsParameter.ActualValue; }
68    }
69    public ISymbolicExpressionTree Child {
70      get { return ChildParameter.ActualValue; }
71      set { ChildParameter.ActualValue = value; }
72    }
73    public CloneMapType GlobalCloneMap {
74      get { return GlobalCloneMapParameter.ActualValue; }
75    }
76    public TraceMapType GlobalTraceMap {
77      get { return GlobalTraceMapParameter.ActualValue; }
78    }
79    public CloneMapType GlobalFragmentMap {
80      get { return GlobalFragmentMapParameter.ActualValue; }
81    }
82    #endregion
83
84    [StorableConstructor]
85    protected TracingSymbolicExpressionTreeCrossover(bool deserializing)
86      : base(deserializing) {
87    }
88
89    protected TracingSymbolicExpressionTreeCrossover(TracingSymbolicExpressionTreeCrossover original, Cloner cloner)
90      : base(original, cloner) {
91    }
92
93    protected TracingSymbolicExpressionTreeCrossover()
94      : base() {
95      Parameters.Add(new ScopeTreeLookupParameter<ISymbolicExpressionTree>(ParentsParameterName, "The parent symbolic expression trees which should be crossed."));
96      Parameters.Add(new LookupParameter<ISymbolicExpressionTree>(ChildParameterName, "The child symbolic expression tree resulting from the crossover."));
97      Parameters.Add(new LookupParameter<CloneMapType>(GlobalCloneMapParameterName, "A global map keeping track of trees and their clones (made during selection)."));
98      Parameters.Add(new LookupParameter<CloneMapType>(GlobalFragmentMapParameterName, "A global map keeping track of tree fragments received via crossover."));
99      Parameters.Add(new LookupParameter<TraceMapType>(GlobalTraceMapParameterName, "A global cache containing tracing info."));
100    }
101
102    public sealed override IOperation Apply() {
103      if (Parents.Length != 2)
104        throw new ArgumentException("Number of parents must be exactly two for symbolic expression tree crossover operators.");
105
106      // add global trace cache if not already present in global scope
107      var gScope = ExecutionContext.Scope;
108      while (gScope.Parent != null)
109        gScope = gScope.Parent;
110      if (GlobalTraceMap == null)
111        gScope.Variables.Add(new Variable(GlobalTraceMapParameterName, new TraceMapType()));
112      if (GlobalFragmentMap == null)
113        gScope.Variables.Add(new Variable(GlobalFragmentMapParameterName, new CloneMapType()));
114
115      // get original parents (this info will be needed later to construct the genealogy graph)
116      var originalParents = new ItemList<IItem>(Parents.Select(x => GlobalCloneMap[x]));
117
118      // save the nodes of parent0 in a list so we can track what modifications are made by crossover
119      var nodes0 = Parents[0].IterateNodesBreadth() as List<ISymbolicExpressionTreeNode>;
120
121      //perform crossover
122      Child = Crossover(Random, Parents[0], Parents[1]);
123
124      // create another list of parent0's nodes, so we can compare it with the first list to see what changed
125      var nodes1 = Child.IterateNodesBreadth() as List<ISymbolicExpressionTreeNode>;
126
127      // compare the two nodes lists and check the difference (comparing node references so we avoid false functional identity).
128      // if no difference is found, then it is assumed that the whole tree was swapped with itself (it can happen), so the index is 0
129      int i, min = Math.Max(nodes0.Count, nodes1.Count);
130      for (i = 0; i != min; ++i)
131        if (nodes0[i] != nodes1[i]) break;
132      if (i == min) i = 0;
133
134      // add heredity information into the global variables
135      GlobalTraceMap[Child] = originalParents; // map child to its corresponding parents from the previous generation
136      GlobalFragmentMap[Child] = new IntValue(i); // map child to the index of its fragment
137      return base.Apply();
138    }
139
140    public abstract ISymbolicExpressionTree Crossover(IRandom random, ISymbolicExpressionTree parent0, ISymbolicExpressionTree parent1);
141  }
142}
Note: See TracBrowser for help on using the repository browser.