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.

File:
1 edited

Legend:

Unmodified
Added
Removed
  • 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.