Changeset 8557 for branches/HeuristicLab.EvolutionaryTracking/HeuristicLab.Encodings.SymbolicExpressionTreeEncoding
- Timestamp:
- 09/03/12 15:26:04 (12 years ago)
- 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 28 28 using HeuristicLab.Persistence.Default.CompositeSerializers.Storable; 29 29 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 30 namespace HeuristicLab.Encodings.SymbolicExpressionTreeEncoding { 34 31 /// <summary> … … 37 34 [Item("SymbolicExpressionTreeCrossover", "A base class for operators that perform a crossover of symbolic expression trees.")] 38 35 [StorableClass] 39 public abstract class TracingSymbolicExpressionTreeCrossover : SymbolicExpressionTreeOperator, ISymbolicExpressionTreeCrossover {36 public abstract class TracingSymbolicExpressionTreeCrossover : TracingSymbolicExpressionTreeOperator, ISymbolicExpressionTreeCrossover { 40 37 private const string ParentsParameterName = "Parents"; 41 38 private const string ChildParameterName = "Child"; 42 private const string GlobalTraceMapParameterName = "GlobalTraceMap"; 43 private const string GlobalCloneMapParameterName = "GlobalCloneMap"; 44 private const string GlobalFragmentMapParameterName = "GlobalFragmentMap"; 39 45 40 46 41 #region Parameter Properties … … 50 45 public ILookupParameter<ISymbolicExpressionTree> ChildParameter { 51 46 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]; }61 47 } 62 48 #endregion … … 70 56 set { ChildParameter.ActualValue = value; } 71 57 } 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 }81 58 #endregion 82 59 … … 85 62 : base(deserializing) { 86 63 } 87 88 64 protected TracingSymbolicExpressionTreeCrossover(TracingSymbolicExpressionTreeCrossover original, Cloner cloner) 89 65 : base(original, cloner) { 90 66 } 91 92 67 protected TracingSymbolicExpressionTreeCrossover() 93 68 : base() { 94 69 Parameters.Add(new ScopeTreeLookupParameter<ISymbolicExpressionTree>(ParentsParameterName, "The parent symbolic expression trees which should be crossed.")); 95 70 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 99 72 } 100 101 73 public sealed override IOperation Apply() { 102 74 if (Parents.Length != 2) 103 75 throw new ArgumentException("Number of parents must be exactly two for symbolic expression tree crossover operators."); 104 76 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(); 116 78 117 79 // save the nodes of parent0 in a list so we can track what modifications are made by crossover … … 124 86 var nodes1 = Child.IterateNodesBreadth().ToList(); 125 87 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 131 92 // add heredity information into the global variables 132 GlobalTraceMap[Child] = originalParents; // map child to its corresponding parents from the previous generation133 GlobalFragmentMap[Child] = new GenericWrapper< SymbolicExpressionTreeNode>(i == min ? null : (SymbolicExpressionTreeNode)nodes1[i]); // map child to the index of its fragment93 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 134 95 return base.Apply(); 135 96 } -
branches/HeuristicLab.EvolutionaryTracking/HeuristicLab.Encodings.SymbolicExpressionTreeEncoding/3.4/GenericWrapper.cs
r8213 r8557 6 6 [Item("Generic wrapper", "Wrapper class for non-item HeuristicLab objects")] 7 7 [StorableClass] 8 public class GenericWrapper<T> : NamedItem where T : class { 8 public class GenericWrapper<T> : NamedItem where T : class, IDeepCloneable { 9 [Storable] 9 10 public T Content { get; private set; } 10 11 private GenericWrapper() {12 }13 11 14 12 public GenericWrapper(T content) { … … 17 15 18 16 [StorableConstructor] 19 protected GenericWrapper(bool serializing) 20 : base(serializing) { 21 } 17 private GenericWrapper(bool serializing) : base(serializing) { } 22 18 23 19 private GenericWrapper(GenericWrapper<T> original, Cloner cloner) 24 20 : base(original, cloner) { 21 this.Content = cloner.Clone(Content); 25 22 } 26 23 -
branches/HeuristicLab.EvolutionaryTracking/HeuristicLab.Encodings.SymbolicExpressionTreeEncoding/3.4/HeuristicLab.Encodings.SymbolicExpressionTreeEncoding-3.4.csproj
r8213 r8557 167 167 <Compile Include="Compiler\SymbolicExpressionTreeCompiler.cs" /> 168 168 <None Include="Plugin.cs.frame" /> 169 <Compile Include="Interfaces\Operators\ITracingSymbolicExpressionTreeOperator.cs" /> 170 <Compile Include="TracingSymbolicExpressionTreeOperator.cs" /> 169 171 <Compile Include="Creators\TracingSymbolicExpressionTreeCreator.cs" /> 170 172 <Compile Include="Creators\FullTreeCreator.cs"> … … 181 183 <Compile Include="Interfaces\ISymbolicExpressionGrammarBase.cs" /> 182 184 <Compile Include="Interfaces\ISymbolicExpressionTreeGrammar.cs" /> 185 <Compile Include="Interfaces\ISymbolicExpressionTreeNodeComparer.cs" /> 183 186 <Compile Include="Interfaces\Operators\ISymbolicExpressionTreeArchitectureAlteringOperator.cs" /> 184 187 <Compile Include="Interfaces\Operators\ISymbolicExpressionTreeGrammarBasedOperator.cs" /> -
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.