Free cookie consent management tool by TermsFeed Policy Generator

Ignore:
Timestamp:
09/03/12 15:26:04 (12 years ago)
Author:
bburlacu
Message:

#1772: Introduced base class and interface for tracing operators. Introduced SymbolicExpressionTreeNodeComparer interface to be implemented by node matching operators. Fixed bug in the TracingSymbolicExpressionTreeManipulator where nodes modified by the Full- and OnePoint tree shakers were not correctly detected. The SymbolicExpressionTreeNodeSimilarityComparer is now injected in the tracing genetic operators as a parameter.

Location:
branches/HeuristicLab.EvolutionaryTracking/HeuristicLab.Encodings.SymbolicExpressionTreeEncoding/3.4
Files:
3 added
4 edited

Legend:

Unmodified
Added
Removed
  • branches/HeuristicLab.EvolutionaryTracking/HeuristicLab.Encodings.SymbolicExpressionTreeEncoding/3.4/Crossovers/TracingSymbolicExpressionTreeCrossover.cs

    r8213 r8557  
    2828using HeuristicLab.Persistence.Default.CompositeSerializers.Storable;
    2929
    30 using CloneMapType = HeuristicLab.Core.ItemDictionary<HeuristicLab.Core.IItem, HeuristicLab.Core.IItem>;
    31 using TraceMapType = HeuristicLab.Core.ItemDictionary<HeuristicLab.Core.IItem, HeuristicLab.Core.IItemList<HeuristicLab.Core.IItem>>;
    32 
    3330namespace HeuristicLab.Encodings.SymbolicExpressionTreeEncoding {
    3431  /// <summary>
     
    3734  [Item("SymbolicExpressionTreeCrossover", "A base class for operators that perform a crossover of symbolic expression trees.")]
    3835  [StorableClass]
    39   public abstract class TracingSymbolicExpressionTreeCrossover : SymbolicExpressionTreeOperator, ISymbolicExpressionTreeCrossover {
     36  public abstract class TracingSymbolicExpressionTreeCrossover : TracingSymbolicExpressionTreeOperator, ISymbolicExpressionTreeCrossover {
    4037    private const string ParentsParameterName = "Parents";
    4138    private const string ChildParameterName = "Child";
    42     private const string GlobalTraceMapParameterName = "GlobalTraceMap";
    43     private const string GlobalCloneMapParameterName = "GlobalCloneMap";
    44     private const string GlobalFragmentMapParameterName = "GlobalFragmentMap";
     39
    4540
    4641    #region Parameter Properties
     
    5045    public ILookupParameter<ISymbolicExpressionTree> ChildParameter {
    5146      get { return (ILookupParameter<ISymbolicExpressionTree>)Parameters[ChildParameterName]; }
    52     }
    53     public LookupParameter<CloneMapType> GlobalCloneMapParameter {
    54       get { return (LookupParameter<CloneMapType>)Parameters[GlobalCloneMapParameterName]; }
    55     }
    56     public LookupParameter<TraceMapType> GlobalTraceMapParameter {
    57       get { return (LookupParameter<TraceMapType>)Parameters[GlobalTraceMapParameterName]; }
    58     }
    59     public LookupParameter<CloneMapType> GlobalFragmentMapParameter {
    60       get { return (LookupParameter<CloneMapType>)Parameters[GlobalFragmentMapParameterName]; }
    6147    }
    6248    #endregion
     
    7056      set { ChildParameter.ActualValue = value; }
    7157    }
    72     public CloneMapType GlobalCloneMap {
    73       get { return GlobalCloneMapParameter.ActualValue; }
    74     }
    75     public TraceMapType GlobalTraceMap {
    76       get { return GlobalTraceMapParameter.ActualValue; }
    77     }
    78     public CloneMapType GlobalFragmentMap {
    79       get { return GlobalFragmentMapParameter.ActualValue; }
    80     }
    8158    #endregion
    8259
     
    8562      : base(deserializing) {
    8663    }
    87 
    8864    protected TracingSymbolicExpressionTreeCrossover(TracingSymbolicExpressionTreeCrossover original, Cloner cloner)
    8965      : base(original, cloner) {
    9066    }
    91 
    9267    protected TracingSymbolicExpressionTreeCrossover()
    9368      : base() {
    9469      Parameters.Add(new ScopeTreeLookupParameter<ISymbolicExpressionTree>(ParentsParameterName, "The parent symbolic expression trees which should be crossed."));
    9570      Parameters.Add(new LookupParameter<ISymbolicExpressionTree>(ChildParameterName, "The child symbolic expression tree resulting from the crossover."));
    96       Parameters.Add(new LookupParameter<CloneMapType>(GlobalCloneMapParameterName, "A global map keeping track of trees and their clones (made during selection)."));
    97       Parameters.Add(new LookupParameter<CloneMapType>(GlobalFragmentMapParameterName, "A global map keeping track of tree fragments received via crossover."));
    98       Parameters.Add(new LookupParameter<TraceMapType>(GlobalTraceMapParameterName, "A global cache containing tracing info."));
     71
    9972    }
    100 
    10173    public sealed override IOperation Apply() {
    10274      if (Parents.Length != 2)
    10375        throw new ArgumentException("Number of parents must be exactly two for symbolic expression tree crossover operators.");
    10476
    105       // add global trace cache if not already present in global scope
    106       var gScope = ExecutionContext.Scope;
    107       while (gScope.Parent != null)
    108         gScope = gScope.Parent;
    109       if (GlobalTraceMap == null)
    110         gScope.Variables.Add(new Variable(GlobalTraceMapParameterName, new TraceMapType()));
    111       if (GlobalFragmentMap == null)
    112         gScope.Variables.Add(new Variable(GlobalFragmentMapParameterName, new CloneMapType()));
    113 
    114       // get original parents (this info will be needed later to construct the genealogy graph)
    115       var originalParents = new ItemList<IItem>(Parents.Select(x => GlobalCloneMap[x]));
     77      AddTracingVariablesToGlobalScope();
    11678
    11779      // save the nodes of parent0 in a list so we can track what modifications are made by crossover
     
    12486      var nodes1 = Child.IterateNodesBreadth().ToList();
    12587
    126       // compare the two nodes lists and check the difference (comparing node references so we avoid false functional identity).
    127       // 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
    128       int i, min = Math.Min(nodes0.Count, nodes1.Count);
    129       for (i = 0; i != min; ++i)
    130         if (nodes0[i] != nodes1[i]) break;
     88      // compare the two node lists and check the difference (comparing node references so we avoid false functional identity).
     89      int i = 0, min = Math.Min(nodes0.Count, nodes1.Count);
     90      while (i != min && ReferenceEquals(nodes0[i], nodes1[i])) ++i;
     91
    13192      // add heredity information into the global variables
    132       GlobalTraceMap[Child] = originalParents; // map child to its corresponding parents from the previous generation
    133       GlobalFragmentMap[Child] = new GenericWrapper<SymbolicExpressionTreeNode>(i == min ? null : (SymbolicExpressionTreeNode)nodes1[i]); // map child to the index of its fragment
     93      GlobalTraceMap[Child] = new ItemList<IItem>(Parents.Select(x => GlobalCloneMap[x])); ; // map child to its corresponding parents from the previous generation
     94      GlobalFragmentMap[Child] = new GenericWrapper<ISymbolicExpressionTreeNode>(i == min ? null : nodes1[i]); // map child to the index of its fragment
    13495      return base.Apply();
    13596    }
  • branches/HeuristicLab.EvolutionaryTracking/HeuristicLab.Encodings.SymbolicExpressionTreeEncoding/3.4/GenericWrapper.cs

    r8213 r8557  
    66  [Item("Generic wrapper", "Wrapper class for non-item HeuristicLab objects")]
    77  [StorableClass]
    8   public class GenericWrapper<T> : NamedItem where T : class {
     8  public class GenericWrapper<T> : NamedItem where T : class, IDeepCloneable {
     9    [Storable]
    910    public T Content { get; private set; }
    10 
    11     private GenericWrapper() {
    12     }
    1311
    1412    public GenericWrapper(T content) {
     
    1715
    1816    [StorableConstructor]
    19     protected GenericWrapper(bool serializing)
    20       : base(serializing) {
    21     }
     17    private GenericWrapper(bool serializing) : base(serializing) { }
    2218
    2319    private GenericWrapper(GenericWrapper<T> original, Cloner cloner)
    2420      : base(original, cloner) {
     21      this.Content = cloner.Clone(Content);
    2522    }
    2623
  • branches/HeuristicLab.EvolutionaryTracking/HeuristicLab.Encodings.SymbolicExpressionTreeEncoding/3.4/HeuristicLab.Encodings.SymbolicExpressionTreeEncoding-3.4.csproj

    r8213 r8557  
    167167    <Compile Include="Compiler\SymbolicExpressionTreeCompiler.cs" />
    168168    <None Include="Plugin.cs.frame" />
     169    <Compile Include="Interfaces\Operators\ITracingSymbolicExpressionTreeOperator.cs" />
     170    <Compile Include="TracingSymbolicExpressionTreeOperator.cs" />
    169171    <Compile Include="Creators\TracingSymbolicExpressionTreeCreator.cs" />
    170172    <Compile Include="Creators\FullTreeCreator.cs">
     
    181183    <Compile Include="Interfaces\ISymbolicExpressionGrammarBase.cs" />
    182184    <Compile Include="Interfaces\ISymbolicExpressionTreeGrammar.cs" />
     185    <Compile Include="Interfaces\ISymbolicExpressionTreeNodeComparer.cs" />
    183186    <Compile Include="Interfaces\Operators\ISymbolicExpressionTreeArchitectureAlteringOperator.cs" />
    184187    <Compile Include="Interfaces\Operators\ISymbolicExpressionTreeGrammarBasedOperator.cs" />
  • branches/HeuristicLab.EvolutionaryTracking/HeuristicLab.Encodings.SymbolicExpressionTreeEncoding/3.4/Manipulators/TracingSymbolicExpressionTreeManipulator.cs

    r8213 r8557  
    2121
    2222using System;
     23using System.Collections.Generic;
    2324using System.Linq;
    2425using HeuristicLab.Common;
     
    2829using HeuristicLab.Persistence.Default.CompositeSerializers.Storable;
    2930
    30 using CloneMapType = HeuristicLab.Core.ItemDictionary<HeuristicLab.Core.IItem, HeuristicLab.Core.IItem>;
    31 using TraceMapType = HeuristicLab.Core.ItemDictionary<HeuristicLab.Core.IItem, HeuristicLab.Core.IItemList<HeuristicLab.Core.IItem>>;
    32 
    3331namespace HeuristicLab.Encodings.SymbolicExpressionTreeEncoding {
    3432  /// <summary>
     
    3735  [Item("TracingSymbolicExpressionTreeManipulator", "A base class for operators that manipulate symbolic expression trees.")]
    3836  [StorableClass]
    39   public abstract class TracingSymbolicExpressionTreeManipulator : SymbolicExpressionTreeOperator, ISymbolicExpressionTreeManipulator {
     37  public abstract class TracingSymbolicExpressionTreeManipulator : TracingSymbolicExpressionTreeOperator, ISymbolicExpressionTreeManipulator {
    4038    private const string SymbolicExpressionTreeParameterName = "SymbolicExpressionTree";
    41     private const string GlobalTraceMapParameterName = "GlobalTraceMap";
    42     private const string GlobalCloneMapParameterName = "GlobalCloneMap";
    43     private const string GlobalFragmentMapParameterName = "GlobalFragmentMap";
    4439
    4540    #region Parameter Properties
    4641    public ILookupParameter<ISymbolicExpressionTree> SymbolicExpressionTreeParameter {
    4742      get { return (ILookupParameter<ISymbolicExpressionTree>)Parameters[SymbolicExpressionTreeParameterName]; }
    48     }
    49     public LookupParameter<CloneMapType> GlobalCloneMapParameter {
    50       get { return (LookupParameter<CloneMapType>)Parameters[GlobalCloneMapParameterName]; }
    51     }
    52     public LookupParameter<TraceMapType> GlobalTraceMapParameter {
    53       get { return (LookupParameter<TraceMapType>)Parameters[GlobalTraceMapParameterName]; }
    54     }
    55     public LookupParameter<CloneMapType> GlobalFragmentMapParameter {
    56       get { return (LookupParameter<CloneMapType>)Parameters[GlobalFragmentMapParameterName]; }
    5743    }
    5844    #endregion
     
    6147    public ISymbolicExpressionTree SymbolicExpressionTree {
    6248      get { return SymbolicExpressionTreeParameter.ActualValue; }
    63     }
    64     public CloneMapType GlobalCloneMap {
    65       get { return GlobalCloneMapParameter.ActualValue; }
    66     }
    67     public TraceMapType GlobalTraceMap {
    68       get { return GlobalTraceMapParameter.ActualValue; }
    69     }
    70     public CloneMapType GlobalFragmentMap {
    71       get { return GlobalFragmentMapParameter.ActualValue; }
    7249    }
    7350    #endregion
     
    7956      : base() {
    8057      Parameters.Add(new LookupParameter<ISymbolicExpressionTree>(SymbolicExpressionTreeParameterName, "The symbolic expression tree on which the operator should be applied."));
    81       Parameters.Add(new LookupParameter<CloneMapType>(GlobalCloneMapParameterName, "A global map keeping track of trees and their clones (made during selection)."));
    82       Parameters.Add(new LookupParameter<TraceMapType>(GlobalTraceMapParameterName, "A global cache containing tracing info."));
    83       Parameters.Add(new LookupParameter<CloneMapType>(GlobalFragmentMapParameterName, "A global map keeping track of tree fragments received via crossover."));
    8458    }
    8559
     
    8761      ISymbolicExpressionTree tree = SymbolicExpressionTreeParameter.ActualValue;
    8862
    89       var gScope = ExecutionContext.Scope;
    90       while (gScope.Parent != null)
    91         gScope = gScope.Parent;
     63      AddTracingVariablesToGlobalScope();
    9264
    93       if (GlobalTraceMap == null)
    94         gScope.Variables.Add(new Variable(GlobalTraceMapParameterName, new TraceMapType()));
    95       if (GlobalFragmentMap == null)
    96         gScope.Variables.Add(new Variable(GlobalFragmentMapParameterName, new CloneMapType()));
    97 
    98       int i = 0;
     65      /* The following block needs to be explained in more detail;
     66       * If the tree was already affected by crossover (before mutation), then:
     67       * - it will already be contained in the GlobalTraceMap
     68       * - In order to preserve information, a clone of the tree is created
     69       * - The clone represents the intermediate stage of the tree, before mutation is applied
     70       * - The clone therefore represents the child after crossover so GlobalTraceMap[clone] will get tree's parents
     71       *   and GlobalFragmentMap[clone] will get the subtree from clone that represents the cloned fragment
     72       * - After tree is mutated, we set GlobalTraceMap[tree] = clone and GlobalFragmentMap[tree] = modified node from tree
     73       */
     74      ISymbolicExpressionTreeNode fragment;
    9975      if (GlobalTraceMap.ContainsKey(tree)) {
    100         // tree was affected by crossover before mutation
    101         // if the tree to be manipulated is already a product of crossover (in the current reproduction phase),
    102         // then there exists no relationship with the original "parent".
    103         // In order to preserve information, a tree clone is created before mutation and added to the trace map.
    104         var clone = (IItem)tree.Clone();
     76        var clone = (IItem)tree.Clone(); // create clone of tree
    10577        GlobalTraceMap[clone] = GlobalTraceMap[tree]; // clone gets parents of tree
    10678        GlobalTraceMap[tree] = new ItemList<IItem> { clone }; // tree gets clone as parent
    107         var nodes = tree.IterateNodesBreadth().ToList();
    108         for (i = 0; i != nodes.Count; ++i) {
    109           if ((GlobalFragmentMap[tree] as GenericWrapper<SymbolicExpressionTreeNode>).Content == nodes[i]) break;
     79        fragment = ((GenericWrapper<ISymbolicExpressionTreeNode>)GlobalFragmentMap[tree]).Content;
     80        int index = tree.IterateNodesBreadth().ToList().IndexOf(fragment); // returns -1 if fragment is not present in tree
     81        GlobalFragmentMap[clone] = new GenericWrapper<ISymbolicExpressionTreeNode>(index == -1 ? null : ((ISymbolicExpressionTree)clone).IterateNodesBreadth().ElementAt(index));
     82      } else {
     83        GlobalTraceMap[tree] = new ItemList<IItem> { GlobalCloneMap[tree] };
     84      }
     85
     86      var original = GlobalCloneMap[tree];
     87      var nodes0 = ((ISymbolicExpressionTree)original).IterateNodesBreadth().ToList();
     88
     89      // perform mutation
     90      Manipulate(RandomParameter.ActualValue, tree);
     91
     92      var nodes1 = tree.IterateNodesBreadth().ToList();
     93
     94      int min = Math.Min(nodes0.Count, nodes1.Count);
     95      // some tree manipulators only change local parameters while the actual node stays the same
     96      // consequently, we need a stronger comparison than ReferenceEquals
     97      var comp = SymbolicExpressionTreeNodeComparer;
     98      if (comp == null)
     99        throw new Exception(Name + ": Could not get SymbolicExpressionTreeNodeComparerParameter!");
     100      var mismatches = new List<int>();
     101      for (int i = 0; i != min; ++i) {
     102        if (!comp.Equals(nodes0[i], nodes1[i])) {
     103          mismatches.Add(i);
    110104        }
    111         var fragment = (SymbolicExpressionTreeNode)(((SymbolicExpressionTree)clone).IterateNodesBreadth().ElementAt(i));
    112         GlobalFragmentMap[clone] = new GenericWrapper<SymbolicExpressionTreeNode>(fragment);
    113       } else {
    114         var original = GlobalCloneMap[tree];
    115         GlobalTraceMap[tree] = new ItemList<IItem> { original };
    116105      }
    117       var nodes0 = tree.IterateNodesBreadth().ToList();
    118       Manipulate(RandomParameter.ActualValue, tree);
    119       var nodes1 = tree.IterateNodesBreadth().ToList();
    120       int min = Math.Min(nodes0.Count, nodes1.Count);
    121       for (i = 0; i != min; ++i)
    122         if (nodes0[i] != nodes1[i]) break;
    123       GlobalFragmentMap[tree] = new GenericWrapper<SymbolicExpressionTreeNode>(i == min ? null : (SymbolicExpressionTreeNode)nodes1[i]);
     106      if (mismatches.Count == 0) // should never happen
     107        fragment = null;
     108      else
     109        fragment = mismatches.Count > 1 ? nodes1[mismatches[0]].Parent : nodes1[mismatches[0]];
     110      GlobalFragmentMap[tree] = new GenericWrapper<ISymbolicExpressionTreeNode>(fragment);
    124111      return base.Apply();
    125112    }
Note: See TracChangeset for help on using the changeset viewer.