Changeset 9083 for branches/HeuristicLab.EvolutionaryTracking/HeuristicLab.Encodings.SymbolicExpressionTreeEncoding/3.4/Manipulators
- Timestamp:
- 12/20/12 16:24:54 (12 years ago)
- Location:
- branches/HeuristicLab.EvolutionaryTracking/HeuristicLab.Encodings.SymbolicExpressionTreeEncoding
- Files:
-
- 6 edited
- 1 copied
Legend:
- Unmodified
- Added
- Removed
-
branches/HeuristicLab.EvolutionaryTracking/HeuristicLab.Encodings.SymbolicExpressionTreeEncoding
- Property svn:mergeinfo changed
-
branches/HeuristicLab.EvolutionaryTracking/HeuristicLab.Encodings.SymbolicExpressionTreeEncoding/3.4/Manipulators/ChangeNodeTypeManipulation.cs
r7514 r9083 24 24 using HeuristicLab.Core; 25 25 using HeuristicLab.Persistence.Default.CompositeSerializers.Storable; 26 using System.Collections.Generic; 26 27 27 28 namespace HeuristicLab.Encodings.SymbolicExpressionTreeEncoding { … … 29 30 [Item("ChangeNodeTypeManipulation", "Selects a random tree node and changes the symbol.")] 30 31 public sealed class ChangeNodeTypeManipulation : TracingSymbolicExpressionTreeManipulator { 32 private const int MAX_TRIES = 100; 33 31 34 [StorableConstructor] 32 35 private ChangeNodeTypeManipulation(bool deserializing) : base(deserializing) { } … … 43 46 44 47 public static void ChangeNodeType(IRandom random, ISymbolicExpressionTree symbolicExpressionTree) { 45 // select any node as parent (except the root node) 46 var manipulationPoints = (from parent in symbolicExpressionTree.Root.IterateNodesPrefix().Skip(1) 47 let subtreeCount = parent.Subtrees.Count() 48 from subtreeIndex in Enumerable.Range(0, subtreeCount) 49 let subtree = parent.GetSubtree(subtreeIndex) 50 let existingSubtreeCount = subtree.Subtrees.Count() 51 // find possible symbols for the node (also considering the existing branches below it) 52 let allowedSymbols = (from symbol in parent.Grammar.GetAllowedChildSymbols(parent.Symbol, subtreeIndex) 53 // do not replace the existing symbol with itself 54 where symbol.Name != subtree.Symbol.Name 55 where symbol.InitialFrequency > 0 56 where existingSubtreeCount <= parent.Grammar.GetMaximumSubtreeCount(symbol) 57 where existingSubtreeCount >= parent.Grammar.GetMinimumSubtreeCount(symbol) 58 // keep only symbols that are still possible considering the existing sub-trees 59 where (from existingSubtreeIndex in Enumerable.Range(0, existingSubtreeCount) 60 let existingSubtree = subtree.GetSubtree(existingSubtreeIndex) 61 select parent.Grammar.IsAllowedChildSymbol(symbol, existingSubtree.Symbol, existingSubtreeIndex)) 62 .All(x => x == true) 63 select symbol) 64 .ToList() 65 where allowedSymbols.Count() > 0 66 select new { Parent = parent, Child = subtree, Index = subtreeIndex, AllowedSymbols = allowedSymbols }) 67 .ToList(); 68 if (manipulationPoints.Count == 0) { return; } 69 var selectedManipulationPoint = manipulationPoints.SelectRandom(random); 48 List<ISymbol> allowedSymbols = new List<ISymbol>(); 49 ISymbolicExpressionTreeNode parent; 50 int childIndex; 51 ISymbolicExpressionTreeNode child; 52 // repeat until a fitting parent and child are found (MAX_TRIES times) 53 int tries = 0; 54 do { 55 parent = symbolicExpressionTree.Root.IterateNodesPrefix().Skip(1).Where(n => n.SubtreeCount > 0).SelectRandom(random); 56 childIndex = random.Next(parent.SubtreeCount); 70 57 71 var weights = selectedManipulationPoint.AllowedSymbols.Select(s => s.InitialFrequency).ToList(); 72 var newSymbol = selectedManipulationPoint.AllowedSymbols.SelectRandom(weights, random); 58 child = parent.GetSubtree(childIndex); 59 int existingSubtreeCount = child.SubtreeCount; 60 allowedSymbols.Clear(); 61 foreach (var symbol in parent.Grammar.GetAllowedChildSymbols(parent.Symbol, childIndex)) { 62 // check basic properties that the new symbol must have 63 if (symbol.Name != child.Symbol.Name && 64 symbol.InitialFrequency > 0 && 65 existingSubtreeCount <= parent.Grammar.GetMinimumSubtreeCount(symbol) && 66 existingSubtreeCount >= parent.Grammar.GetMaximumSubtreeCount(symbol)) { 67 // check that all existing subtrees are also allowed for the new symbol 68 bool allExistingSubtreesAllowed = true; 69 for (int existingSubtreeIndex = 0; existingSubtreeIndex < existingSubtreeCount && allExistingSubtreesAllowed; existingSubtreeIndex++) { 70 var existingSubtree = child.GetSubtree(existingSubtreeIndex); 71 allExistingSubtreesAllowed &= parent.Grammar.IsAllowedChildSymbol(symbol, existingSubtree.Symbol, existingSubtreeIndex); 72 } 73 if (allExistingSubtreesAllowed) { 74 allowedSymbols.Add(symbol); 75 } 76 } 77 } 78 tries++; 79 } while (tries < MAX_TRIES && allowedSymbols.Count == 0); 73 80 74 // replace the old node with the new node 75 var newNode = newSymbol.CreateTreeNode(); 76 if (newNode.HasLocalParameters) 77 newNode.ResetLocalParameters(random); 78 foreach (var subtree in selectedManipulationPoint.Child.Subtrees) 79 newNode.AddSubtree(subtree); 80 selectedManipulationPoint.Parent.RemoveSubtree(selectedManipulationPoint.Index); 81 selectedManipulationPoint.Parent.InsertSubtree(selectedManipulationPoint.Index, newNode); 81 if (tries < MAX_TRIES) { 82 var weights = allowedSymbols.Select(s => s.InitialFrequency).ToList(); 83 var newSymbol = allowedSymbols.SelectRandom(weights, random); 84 85 // replace the old node with the new node 86 var newNode = newSymbol.CreateTreeNode(); 87 if (newNode.HasLocalParameters) 88 newNode.ResetLocalParameters(random); 89 foreach (var subtree in child.Subtrees) 90 newNode.AddSubtree(subtree); 91 parent.RemoveSubtree(childIndex); 92 parent.InsertSubtree(childIndex, newNode); 93 } 82 94 } 83 95 } -
branches/HeuristicLab.EvolutionaryTracking/HeuristicLab.Encodings.SymbolicExpressionTreeEncoding/3.4/Manipulators/MultiSymbolicExpressionTreeManipulator.cs
r7439 r9083 37 37 [StorableClass] 38 38 public sealed class MultiSymbolicExpressionTreeManipulator : StochasticMultiBranch<ISymbolicExpressionTreeManipulator>, 39 ITracingSymbolicExpressionTreeOperator, 39 40 ISymbolicExpressionTreeManipulator, 40 41 IStochasticOperator, … … 43 44 private const string MaximumSymbolicExpressionTreeLengthParameterName = "MaximumSymbolicExpressionTreeLength"; 44 45 private const string MaximumSymbolicExpressionTreeDepthParameterName = "MaximumSymbolicExpressionTreeDepth"; 46 private const string SymbolicExpressionTreeNodeComparerParameterName = "SymbolicExpressionTreeNodeComparer"; 47 private const string SymbolicExpressionTreeNodeComparerParameterDescription = "The comparison operator used to check if two symbolic expression tree nodes are equal or similar."; 45 48 46 49 public override bool CanChangeName { … … 49 52 protected override bool CreateChildOperation { 50 53 get { return true; } 54 } 55 public ValueParameter<ISymbolicExpressionTreeNodeComparer> SymbolicExpressionTreeNodeComparerParameter { 56 get { return (ValueParameter<ISymbolicExpressionTreeNodeComparer>)Parameters[SymbolicExpressionTreeNodeComparerParameterName]; } 57 } 58 public ISymbolicExpressionTreeNodeComparer SymbolicExpressionTreeNodeComparer { 59 get { return (ISymbolicExpressionTreeNodeComparer)SymbolicExpressionTreeNodeComparerParameter.ActualValue; } 51 60 } 52 61 … … 71 80 Parameters.Add(new ValueLookupParameter<IntValue>(MaximumSymbolicExpressionTreeLengthParameterName, "The maximal length (number of nodes) of the symbolic expression tree.")); 72 81 Parameters.Add(new ValueLookupParameter<IntValue>(MaximumSymbolicExpressionTreeDepthParameterName, "The maximal depth of the symbolic expression tree (a tree with one node has depth = 0).")); 82 Parameters.Add(new ValueParameter<ISymbolicExpressionTreeNodeComparer>(SymbolicExpressionTreeNodeComparerParameterName, SymbolicExpressionTreeNodeComparerParameterDescription)); 73 83 74 84 List<ISymbolicExpressionTreeManipulator> list = new List<ISymbolicExpressionTreeManipulator>(); … … 110 120 manipulator.MaximumSymbolicExpressionTreeLengthParameter.ActualName = MaximumSymbolicExpressionTreeLengthParameter.Name; 111 121 } 122 var comparers = ApplicationManager.Manager.GetInstances<ISymbolicExpressionTreeNodeComparer>().ToList(); 123 if (comparers.Count > 0) 124 foreach (var manipulator in Operators.OfType<ITracingSymbolicExpressionTreeOperator>()) { 125 manipulator.SymbolicExpressionTreeNodeComparerParameter.ActualValue = comparers.First(); 126 } 112 127 } 113 128 } -
branches/HeuristicLab.EvolutionaryTracking/HeuristicLab.Encodings.SymbolicExpressionTreeEncoding/3.4/Manipulators/OnePointShaker.cs
r7514 r9083 57 57 58 58 protected override void Manipulate(IRandom random, ISymbolicExpressionTree tree) { 59 OnePointShaker.Shake(random, tree, ShakingFactor); 60 } 61 62 public static void Shake(IRandom random, ISymbolicExpressionTree tree, double shakingFactor) { 59 63 List<ISymbolicExpressionTreeNode> parametricNodes = new List<ISymbolicExpressionTreeNode>(); 60 64 tree.Root.ForEachNodePostfix(n => { … … 63 67 if (parametricNodes.Count > 0) { 64 68 var selectedPoint = parametricNodes.SelectRandom(random); 65 selectedPoint.ShakeLocalParameters(random, ShakingFactor);69 selectedPoint.ShakeLocalParameters(random, shakingFactor); 66 70 } 67 71 } -
branches/HeuristicLab.EvolutionaryTracking/HeuristicLab.Encodings.SymbolicExpressionTreeEncoding/3.4/Manipulators/ReplaceBranchManipulation.cs
r7514 r9083 26 26 using HeuristicLab.Parameters; 27 27 using HeuristicLab.Persistence.Default.CompositeSerializers.Storable; 28 using System.Collections.Generic; 28 29 29 30 namespace HeuristicLab.Encodings.SymbolicExpressionTreeEncoding { … … 31 32 [Item("ReplaceBranchManipulation", "Selects a branch of the tree randomly and replaces it with a newly initialized branch (using PTC2).")] 32 33 public sealed class ReplaceBranchManipulation : TracingSymbolicExpressionTreeManipulator, ISymbolicExpressionTreeSizeConstraintOperator { 34 private const int MAX_TRIES = 100; 33 35 private const string MaximumSymbolicExpressionTreeLengthParameterName = "MaximumSymbolicExpressionTreeLength"; 34 36 private const string MaximumSymbolicExpressionTreeDepthParameterName = "MaximumSymbolicExpressionTreeDepth"; … … 68 70 69 71 public static void ReplaceRandomBranch(IRandom random, ISymbolicExpressionTree symbolicExpressionTree, int maxTreeLength, int maxTreeDepth) { 70 // select any node as parent (except the root node) 71 var manipulationPoints = (from parent in symbolicExpressionTree.Root.IterateNodesPrefix().Skip(1) 72 from subtree in parent.Subtrees 73 let subtreeIndex = parent.IndexOfSubtree(subtree) 74 let maxLength = maxTreeLength - symbolicExpressionTree.Length + subtree.GetLength() 75 let maxDepth = maxTreeDepth - symbolicExpressionTree.Depth + subtree.GetDepth() 76 // find possible symbols for the node (also considering the existing branches below it) 77 let allowedSymbols = (from symbol in parent.Grammar.GetAllowedChildSymbols(parent.Symbol, subtreeIndex) 78 // do not replace symbol with the same symbol 79 where symbol.Name != subtree.Symbol.Name 80 where symbol.InitialFrequency > 0 81 where parent.Grammar.GetMinimumExpressionDepth(symbol) + 1 <= maxDepth 82 where parent.Grammar.GetMinimumExpressionLength(symbol) <= maxLength 83 select symbol) 84 .ToList() 85 where allowedSymbols.Count > 0 86 select new { 87 Parent = parent, 88 Child = subtree, 89 Index = subtreeIndex, 90 AllowedSymbols = allowedSymbols, 91 MaxLength = maxLength, 92 MaxDepth = maxDepth 93 }) 94 .ToList(); 72 var allowedSymbols = new List<ISymbol>(); 73 ISymbolicExpressionTreeNode parent; 74 int childIndex; 75 int maxLength; 76 int maxDepth; 77 // repeat until a fitting parent and child are found (MAX_TRIES times) 78 int tries = 0; 79 do { 80 parent = symbolicExpressionTree.Root.IterateNodesPrefix().Skip(1).Where(n => n.SubtreeCount > 0).SelectRandom(random); 81 childIndex = random.Next(parent.SubtreeCount); 82 var child = parent.GetSubtree(childIndex); 83 maxLength = maxTreeLength - symbolicExpressionTree.Length + child.GetLength(); 84 maxDepth = maxTreeDepth - symbolicExpressionTree.Depth + child.GetDepth(); 95 85 96 if (manipulationPoints.Count == 0) return; 97 var selectedManipulationPoint = manipulationPoints.SelectRandom(random); 86 allowedSymbols.Clear(); 87 foreach (var symbol in parent.Grammar.GetAllowedChildSymbols(parent.Symbol, childIndex)) { 88 // check basic properties that the new symbol must have 89 if (symbol.Name != child.Symbol.Name && 90 symbol.InitialFrequency > 0 && 91 parent.Grammar.GetMinimumExpressionDepth(symbol) + 1 <= maxDepth && 92 parent.Grammar.GetMinimumExpressionLength(symbol) <= maxLength) { 93 allowedSymbols.Add(symbol); 94 } 95 } 96 tries++; 97 } while (tries < MAX_TRIES && allowedSymbols.Count == 0); 98 98 99 var weights = selectedManipulationPoint.AllowedSymbols.Select(s => s.InitialFrequency).ToList(); 100 var seedSymbol = selectedManipulationPoint.AllowedSymbols.SelectRandom(weights, random); 101 // replace the old node with the new node 102 var seedNode = seedSymbol.CreateTreeNode(); 103 if (seedNode.HasLocalParameters) 104 seedNode.ResetLocalParameters(random); 99 if (tries < MAX_TRIES) { 100 var weights = allowedSymbols.Select(s => s.InitialFrequency).ToList(); 101 var seedSymbol = allowedSymbols.SelectRandom(weights, random); 102 // replace the old node with the new node 103 var seedNode = seedSymbol.CreateTreeNode(); 104 if (seedNode.HasLocalParameters) 105 seedNode.ResetLocalParameters(random); 105 106 106 selectedManipulationPoint.Parent.RemoveSubtree(selectedManipulationPoint.Index); 107 selectedManipulationPoint.Parent.InsertSubtree(selectedManipulationPoint.Index, seedNode); 108 ProbabilisticTreeCreator.PTC2(random, seedNode, selectedManipulationPoint.MaxLength, selectedManipulationPoint.MaxDepth); 107 parent.RemoveSubtree(childIndex); 108 parent.InsertSubtree(childIndex, seedNode); 109 ProbabilisticTreeCreator.PTC2(random, seedNode, maxLength, maxDepth); 110 } 109 111 } 110 112 } -
branches/HeuristicLab.EvolutionaryTracking/HeuristicLab.Encodings.SymbolicExpressionTreeEncoding/3.4/Manipulators/TracingSymbolicExpressionTreeManipulator.cs
r8557 r9083 25 25 using HeuristicLab.Common; 26 26 using HeuristicLab.Core; 27 using HeuristicLab.EvolutionaryTracking;28 27 using HeuristicLab.Parameters; 29 28 using HeuristicLab.Persistence.Default.CompositeSerializers.Storable; … … 37 36 public abstract class TracingSymbolicExpressionTreeManipulator : TracingSymbolicExpressionTreeOperator, ISymbolicExpressionTreeManipulator { 38 37 private const string SymbolicExpressionTreeParameterName = "SymbolicExpressionTree"; 38 [Storable] 39 private readonly Dictionary<Type, byte> manipulationTypes = new Dictionary<Type, byte>(); 39 40 40 41 #region Parameter Properties … … 52 53 [StorableConstructor] 53 54 protected TracingSymbolicExpressionTreeManipulator(bool deserializing) : base(deserializing) { } 54 protected TracingSymbolicExpressionTreeManipulator(TracingSymbolicExpressionTreeManipulator original, Cloner cloner) : base(original, cloner) { } 55 protected TracingSymbolicExpressionTreeManipulator(TracingSymbolicExpressionTreeManipulator original, Cloner cloner) 56 : base(original, cloner) { 57 this.manipulationTypes = new Dictionary<Type, byte>(original.manipulationTypes); 58 } 55 59 public TracingSymbolicExpressionTreeManipulator() 56 60 : base() { 57 61 Parameters.Add(new LookupParameter<ISymbolicExpressionTree>(SymbolicExpressionTreeParameterName, "The symbolic expression tree on which the operator should be applied.")); 62 63 manipulationTypes.Add(typeof(FullTreeShaker), ManipulationType.FullTreeShaker); 64 manipulationTypes.Add(typeof(OnePointShaker), ManipulationType.OnePointShaker); 65 manipulationTypes.Add(typeof(ChangeNodeTypeManipulation), ManipulationType.ChangeNodeTypeManipulation); 66 manipulationTypes.Add(typeof(ReplaceBranchManipulation), ManipulationType.ReplaceBranchManipulation); 58 67 } 59 68 … … 72 81 * - After tree is mutated, we set GlobalTraceMap[tree] = clone and GlobalFragmentMap[tree] = modified node from tree 73 82 */ 74 ISymbolicExpressionTreeNode fragment;83 Fragment fragment = null; 75 84 if (GlobalTraceMap.ContainsKey(tree)) { 76 var clone = (IItem)tree.Clone(); // create clone of tree 85 var clone = (IItem)tree.Clone(); 86 GlobalCloneMap[clone] = GlobalCloneMap[tree]; 87 GlobalCloneMap[tree] = clone; 77 88 GlobalTraceMap[clone] = GlobalTraceMap[tree]; // clone gets parents of tree 78 89 GlobalTraceMap[tree] = new ItemList<IItem> { clone }; // tree gets clone as parent 79 fragment = ( (GenericWrapper<ISymbolicExpressionTreeNode>)GlobalFragmentMap[tree]).Content;80 int index = tree.IterateNodesBreadth().ToList().IndexOf(fragment ); // returns -1 if fragment is not present in tree81 GlobalFragmentMap[clone] = new GenericWrapper<ISymbolicExpressionTreeNode>(index == -1 ? null : ((ISymbolicExpressionTree)clone).IterateNodesBreadth().ElementAt(index));90 fragment = (Fragment)GlobalFragmentMap[tree]; 91 int index = tree.IterateNodesBreadth().ToList().IndexOf(fragment.Root); // returns -1 if fragment is not present in tree (can happen if fragment is null) 92 GlobalFragmentMap[clone] = new Fragment(index == -1 ? null : ((ISymbolicExpressionTree)clone).IterateNodesBreadth().ElementAt(index)); 82 93 } else { 83 94 GlobalTraceMap[tree] = new ItemList<IItem> { GlobalCloneMap[tree] }; 84 95 } 85 96 86 var original = GlobalCloneMap[tree]; 87 var nodes0 = ((ISymbolicExpressionTree)original).IterateNodesBreadth().ToList(); 97 var concreteType = this.GetType(); 88 98 89 // perform mutation 99 if (!manipulationTypes.ContainsKey(concreteType)) 100 throw new Exception(this.Name + ": Unknown manipulation type (key not found in the dictionary)."); 101 102 var nodes0 = tree.IterateNodesBreadth().ToList(); // list of nodes before manipulation 90 103 Manipulate(RandomParameter.ActualValue, tree); 104 var nodes1 = tree.IterateNodesBreadth().ToList(); // list of nodes after manipulation 105 int min = Math.Min(nodes0.Count, nodes1.Count); 91 106 92 var nodes1 = tree.IterateNodesBreadth().ToList(); 107 switch (manipulationTypes[concreteType]) { 108 case ManipulationType.FullTreeShaker: { 109 // the FullTreeShaker changes the local parameters of all the nodes in the tree 110 // therefore, the whole tree is considered to be the fragment 111 fragment = new Fragment(tree.Root.GetSubtree(0).GetSubtree(0)); 112 break; 113 } 114 case ManipulationType.OnePointShaker: { 115 var original = (ISymbolicExpressionTree)GlobalCloneMap[tree]; 116 var nodesOriginal = original.IterateNodesBreadth().ToList(); 117 int i = 0; 118 var comparer = SymbolicExpressionTreeNodeComparer; 119 while (i != min && comparer.Equals(nodesOriginal[i], nodes1[i])) ++i; 120 fragment = new Fragment(i == min ? null : nodes1[i], 1); 121 break; 122 } 123 case ManipulationType.ChangeNodeTypeManipulation: { 124 int i = 0; 125 while (i != min && ReferenceEquals(nodes0[i], nodes1[i])) ++i; 126 fragment = new Fragment(i == min ? null : nodes1[i], 1); 127 break; 128 } 129 case ManipulationType.ReplaceBranchManipulation: { 130 int i = 0; 131 while (i != min && ReferenceEquals(nodes0[i], nodes1[i])) ++i; 132 fragment = new Fragment(i == min ? null : nodes1[i]); 133 break; 134 } 135 default: 136 throw new Exception(Name + ": Unknown manipulaton type."); 137 } 93 138 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); 104 } 105 } 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); 139 GlobalFragmentMap[tree] = fragment; 111 140 return base.Apply(); 112 141 } 113 142 114 143 protected abstract void Manipulate(IRandom random, ISymbolicExpressionTree symbolicExpressionTree); 144 145 private struct ManipulationType { 146 public const byte FullTreeShaker = 1; 147 public const byte OnePointShaker = 2; 148 public const byte ChangeNodeTypeManipulation = 3; 149 public const byte ReplaceBranchManipulation = 4; 150 } 115 151 } 116 152 }
Note: See TracChangeset
for help on using the changeset viewer.