Changeset 8557 for branches/HeuristicLab.EvolutionaryTracking/HeuristicLab.Encodings.SymbolicExpressionTreeEncoding/3.4/Manipulators/TracingSymbolicExpressionTreeManipulator.cs
- Timestamp:
- 09/03/12 15:26:04 (12 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
branches/HeuristicLab.EvolutionaryTracking/HeuristicLab.Encodings.SymbolicExpressionTreeEncoding/3.4/Manipulators/TracingSymbolicExpressionTreeManipulator.cs
r8213 r8557 21 21 22 22 using System; 23 using System.Collections.Generic; 23 24 using System.Linq; 24 25 using HeuristicLab.Common; … … 28 29 using HeuristicLab.Persistence.Default.CompositeSerializers.Storable; 29 30 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 33 31 namespace HeuristicLab.Encodings.SymbolicExpressionTreeEncoding { 34 32 /// <summary> … … 37 35 [Item("TracingSymbolicExpressionTreeManipulator", "A base class for operators that manipulate symbolic expression trees.")] 38 36 [StorableClass] 39 public abstract class TracingSymbolicExpressionTreeManipulator : SymbolicExpressionTreeOperator, ISymbolicExpressionTreeManipulator {37 public abstract class TracingSymbolicExpressionTreeManipulator : TracingSymbolicExpressionTreeOperator, ISymbolicExpressionTreeManipulator { 40 38 private const string SymbolicExpressionTreeParameterName = "SymbolicExpressionTree"; 41 private const string GlobalTraceMapParameterName = "GlobalTraceMap";42 private const string GlobalCloneMapParameterName = "GlobalCloneMap";43 private const string GlobalFragmentMapParameterName = "GlobalFragmentMap";44 39 45 40 #region Parameter Properties 46 41 public ILookupParameter<ISymbolicExpressionTree> SymbolicExpressionTreeParameter { 47 42 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]; }57 43 } 58 44 #endregion … … 61 47 public ISymbolicExpressionTree SymbolicExpressionTree { 62 48 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; }72 49 } 73 50 #endregion … … 79 56 : base() { 80 57 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."));84 58 } 85 59 … … 87 61 ISymbolicExpressionTree tree = SymbolicExpressionTreeParameter.ActualValue; 88 62 89 var gScope = ExecutionContext.Scope; 90 while (gScope.Parent != null) 91 gScope = gScope.Parent; 63 AddTracingVariablesToGlobalScope(); 92 64 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; 99 75 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 105 77 GlobalTraceMap[clone] = GlobalTraceMap[tree]; // clone gets parents of tree 106 78 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); 110 104 } 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 };116 105 } 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); 124 111 return base.Apply(); 125 112 }
Note: See TracChangeset
for help on using the changeset viewer.