Changeset 3294 for trunk/sources/HeuristicLab.Encodings.SymbolicExpressionTreeEncoding/3.3/Crossovers
- Timestamp:
- 04/09/10 17:28:32 (15 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/sources/HeuristicLab.Encodings.SymbolicExpressionTreeEncoding/3.3/Crossovers/SubtreeCrossover.cs
r3237 r3294 27 27 using System; 28 28 using HeuristicLab.Parameters; 29 using HeuristicLab.Encodings.SymbolicExpressionTreeEncoding.GeneralSymbols; 29 30 namespace HeuristicLab.Encodings.SymbolicExpressionTreeEncoding { 30 31 … … 39 40 [StorableClass] 40 41 public class SubtreeCrossover : SymbolicExpressionTreeCrossover { 41 private const int MAX_TRIES = 100;42 43 42 public IValueLookupParameter<PercentValue> InternalCrossoverPointProbabilityParameter { 44 43 get { return (IValueLookupParameter<PercentValue>)Parameters["InternalCrossoverPointProbability"]; } … … 52 51 protected override SymbolicExpressionTree Cross(IRandom random, ISymbolicExpressionGrammar grammar, 53 52 SymbolicExpressionTree parent0, SymbolicExpressionTree parent1, 54 IntValue maxTreeSize, IntValue maxTreeHeight ) {55 return Apply(random, grammar, parent0, parent1, InternalCrossoverPointProbabilityParameter.ActualValue.Value, maxTreeSize.Value, maxTreeHeight.Value);53 IntValue maxTreeSize, IntValue maxTreeHeight, out bool success) { 54 return Cross(random, grammar, parent0, parent1, InternalCrossoverPointProbabilityParameter.ActualValue.Value, maxTreeSize.Value, maxTreeHeight.Value, out success); 56 55 } 57 56 58 public static SymbolicExpressionTree Apply(IRandom random, ISymbolicExpressionGrammar grammar,57 public static SymbolicExpressionTree Cross(IRandom random, ISymbolicExpressionGrammar grammar, 59 58 SymbolicExpressionTree parent0, SymbolicExpressionTree parent1, 60 double internalCrossoverPointProbability, int maxTreeSize, int maxTreeHeight) { 61 int tries = 0; 62 while (tries++ < MAX_TRIES) { 63 // select a random crossover point in the first parent 64 SymbolicExpressionTreeNode crossoverPoint0; 65 int replacedSubtreeIndex; 66 SelectCrossoverPoint(random, parent0, internalCrossoverPointProbability, out crossoverPoint0, out replacedSubtreeIndex); 59 double internalCrossoverPointProbability, int maxTreeSize, int maxTreeHeight, out bool success) { 60 // select a random crossover point in the first parent 61 SymbolicExpressionTreeNode crossoverPoint0; 62 int replacedSubtreeIndex; 63 SelectCrossoverPoint(random, parent0, internalCrossoverPointProbability, out crossoverPoint0, out replacedSubtreeIndex); 67 64 68 69 70 65 // calculate the max size and height that the inserted branch can have 66 int maxInsertedBranchSize = maxTreeSize - (parent0.Size - crossoverPoint0.SubTrees[replacedSubtreeIndex].GetSize()); 67 int maxInsertedBranchHeight = maxTreeHeight - GetBranchLevel(parent0.Root, crossoverPoint0); 71 68 72 var allowedBranches = from branch in IterateNodes(parent1.Root) 73 where branch.GetSize() < maxInsertedBranchSize 74 where branch.GetHeight() < maxInsertedBranchHeight 75 where grammar.AllowedSymbols(crossoverPoint0.Symbol, replacedSubtreeIndex).Contains(branch.Symbol) 76 select branch; 69 var allowedBranches = from branch in IterateNodes(parent1.Root) 70 where branch.GetSize() < maxInsertedBranchSize 71 where branch.GetHeight() < maxInsertedBranchHeight 72 where grammar.GetAllowedSymbols(crossoverPoint0.Symbol, replacedSubtreeIndex).Contains(branch.Symbol) 73 where IsMatchingPointType(parent0, crossoverPoint0, branch) 74 select branch; 77 75 78 79 76 if (allowedBranches.Count() > 0) { 77 var selectedBranch = SelectRandomBranch(random, allowedBranches, internalCrossoverPointProbability); 80 78 81 82 83 84 85 return parent0;86 }79 // manipulate the tree of parent0 in place 80 // replace the branch in tree0 with the selected branch from tree1 81 crossoverPoint0.RemoveSubTree(replacedSubtreeIndex); 82 crossoverPoint0.InsertSubTree(replacedSubtreeIndex, selectedBranch); 83 success = true; 84 return parent0; 87 85 } 88 86 89 // TODO: we should have a way to track the number of failed crossover attempts 90 // for now just return the first parent unchanged 87 success = false; 91 88 return parent0; 89 } 90 91 private static bool IsMatchingPointType(SymbolicExpressionTree tree, SymbolicExpressionTreeNode parent, SymbolicExpressionTreeNode newBranch) { 92 var functionCalls = (from node in IterateNodes(newBranch) 93 let invokeNode = node as InvokeFunctionTreeNode 94 let argNode = node as ArgumentTreeNode 95 where invokeNode != null || argNode != null 96 let name = invokeNode != null ? invokeNode.InvokedFunctionName : "ARG" + argNode.ArgumentIndex 97 let argCount = invokeNode != null ? invokeNode.SubTrees.Count : 0 98 select new { FunctionName = name, FunctionArgumentCount = argCount }).Distinct(); 99 var definingBranch = GetDefiningBranch(tree, parent); 100 if (definingBranch == null) return false; 101 foreach (var functionCall in functionCalls) { 102 if (!definingBranch.DynamicSymbols.Contains(functionCall.FunctionName) || 103 definingBranch.GetDynamicSymbolArgumentCount(functionCall.FunctionName) != functionCall.FunctionArgumentCount) 104 return false; 105 } 106 return true; 107 } 108 109 private static SymbolicExpressionTreeNode GetDefiningBranch(SymbolicExpressionTree tree, SymbolicExpressionTreeNode parent) { 110 foreach (var treeNode in tree.Root.SubTrees) { 111 if (IterateNodes(treeNode).Contains(parent)) return treeNode; 112 } 113 return null; 92 114 } 93 115 … … 95 117 var crossoverPoints = from branch in IterateNodes(parent0.Root) 96 118 where branch.SubTrees.Count > 0 119 where !(branch.Symbol is ProgramRootSymbol) 97 120 from index in Enumerable.Range(0, branch.SubTrees.Count) 98 121 let p = new { CrossoverPoint = branch, SubtreeIndex = index, IsLeaf = branch.SubTrees[index].SubTrees.Count == 0 } … … 101 124 where !p.IsLeaf 102 125 select p).ToList(); 103 // select internal crossover point or leaf 104 if (random.NextDouble() < internalNodeProbability && internalCrossoverPoints.Count > 0) { 126 var leafCrossoverPoints = (from p in crossoverPoints 127 where p.IsLeaf 128 select p).ToList(); 129 if (internalCrossoverPoints.Count == 0) { 130 var selectedCrossoverPoint = leafCrossoverPoints[random.Next(leafCrossoverPoints.Count)]; 131 crossoverPoint = selectedCrossoverPoint.CrossoverPoint; 132 subtreeIndex = selectedCrossoverPoint.SubtreeIndex; 133 } else if (leafCrossoverPoints.Count == 0) { 134 var selectedCrossoverPoint = internalCrossoverPoints[random.Next(internalCrossoverPoints.Count)]; 135 crossoverPoint = selectedCrossoverPoint.CrossoverPoint; 136 subtreeIndex = selectedCrossoverPoint.SubtreeIndex; 137 } else if (random.NextDouble() < internalNodeProbability && internalCrossoverPoints.Count > 0) { 138 // select internal crossover point or leaf 105 139 var selectedCrossoverPoint = internalCrossoverPoints[random.Next(internalCrossoverPoints.Count)]; 106 140 crossoverPoint = selectedCrossoverPoint.CrossoverPoint; 107 141 subtreeIndex = selectedCrossoverPoint.SubtreeIndex; 108 142 } else { 109 var leafCrossoverPoints = (from p in crossoverPoints110 where p.IsLeaf111 select p).ToList();112 143 var selectedCrossoverPoint = leafCrossoverPoints[random.Next(leafCrossoverPoints.Count)]; 113 144 crossoverPoint = selectedCrossoverPoint.CrossoverPoint; … … 125 156 from branch in g 126 157 select branch).ToList(); 127 if (random.NextDouble() < internalNodeProbability && allowedInternalBranches.Count > 0) { 158 var allowedLeafBranches = (from g in groupedBranches 159 where g.Key == 0 160 from leaf in g 161 select leaf).ToList(); 162 if (allowedInternalBranches.Count == 0) { 163 return allowedLeafBranches[random.Next(allowedLeafBranches.Count)]; 164 } else if (allowedLeafBranches.Count == 0) { 165 return allowedInternalBranches[random.Next(allowedInternalBranches.Count)]; 166 } else if (random.NextDouble() < internalNodeProbability) { 167 // when leaf and internal nodes are possible then choose either a leaf or internal node with internalNodeProbability 128 168 return allowedInternalBranches[random.Next(allowedInternalBranches.Count)]; 129 169 } else { 130 var allowedLeafBranches = (from g in groupedBranches131 where g.Key == 0132 from leaf in g133 select leaf).ToList();134 170 return allowedLeafBranches[random.Next(allowedLeafBranches.Count)]; 135 171 }
Note: See TracChangeset
for help on using the changeset viewer.