Changeset 3237 for trunk/sources/HeuristicLab.Encodings.SymbolicExpressionTreeEncoding/3.3/Crossovers
- Timestamp:
- 03/30/10 19:38:22 (15 years ago)
- Location:
- trunk/sources/HeuristicLab.Encodings.SymbolicExpressionTreeEncoding/3.3/Crossovers
- Files:
-
- 1 deleted
- 1 moved
Legend:
- Unmodified
- Added
- Removed
-
trunk/sources/HeuristicLab.Encodings.SymbolicExpressionTreeEncoding/3.3/Crossovers/SubtreeCrossover.cs
r3232 r3237 1 1 #region License Information 2 2 /* HeuristicLab 3 * Copyright (C) 2002-20 08Heuristic and Evolutionary Algorithms Laboratory (HEAL)3 * Copyright (C) 2002-2010 Heuristic and Evolutionary Algorithms Laboratory (HEAL) 4 4 * 5 5 * This file is part of HeuristicLab. … … 22 22 using System.Collections.Generic; 23 23 using HeuristicLab.Core; 24 using HeuristicLab.GP.Interfaces; 24 using HeuristicLab.Persistence.Default.CompositeSerializers.Storable; 25 using HeuristicLab.Data; 26 using System.Linq; 27 using System; 28 using HeuristicLab.Parameters; 29 namespace HeuristicLab.Encodings.SymbolicExpressionTreeEncoding { 25 30 26 namespace HeuristicLab.Encodings.SymbolicExpressionTree {27 public class StandardCrossOver : SizeConstrictedGPCrossoverBase {28 private int MaxRecombinationTries { get { return 20; } }29 31 30 public override string Description { 31 get { 32 return @"Takes two parent individuals P0 and P1 each. Selects a random node N0 of P0 and a random node N1 of P1. 33 And replaces the branch with root0 N0 in P0 with N1 from P1 if the tree-size limits are not violated. 34 When recombination with N0 and N1 would create a tree that is too large or invalid the operator randomly selects new N0 and N1 35 until a valid configuration is found."; 32 /// <summary> 33 /// Takes two parent individuals P0 and P1 each. Selects a random node N0 of P0 and a random node N1 of P1. 34 /// And replaces the branch with root0 N0 in P0 with N1 from P1 if the tree-size limits are not violated. 35 /// When recombination with N0 and N1 would create a tree that is too large or invalid the operator randomly selects new N0 and N1 36 /// until a valid configuration is found. 37 /// </summary> 38 [Item("SubtreeCrossover", "An operator which performs subtree swapping crossover.")] 39 [StorableClass] 40 public class SubtreeCrossover : SymbolicExpressionTreeCrossover { 41 private const int MAX_TRIES = 100; 42 43 public IValueLookupParameter<PercentValue> InternalCrossoverPointProbabilityParameter { 44 get { return (IValueLookupParameter<PercentValue>)Parameters["InternalCrossoverPointProbability"]; } 45 } 46 47 public SubtreeCrossover() 48 : base() { 49 Parameters.Add(new ValueLookupParameter<PercentValue>("InternalCrossoverPointProbability", "The probability to select an internal crossover point (instead of a leaf node).", new PercentValue(0.9))); 50 } 51 52 protected override SymbolicExpressionTree Cross(IRandom random, ISymbolicExpressionGrammar grammar, 53 SymbolicExpressionTree parent0, SymbolicExpressionTree parent1, 54 IntValue maxTreeSize, IntValue maxTreeHeight) { 55 return Apply(random, grammar, parent0, parent1, InternalCrossoverPointProbabilityParameter.ActualValue.Value, maxTreeSize.Value, maxTreeHeight.Value); 56 } 57 58 public static SymbolicExpressionTree Apply(IRandom random, ISymbolicExpressionGrammar grammar, 59 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); 67 68 // calculate the max size and height that the inserted branch can have 69 int maxInsertedBranchSize = maxTreeSize - (parent0.Size - crossoverPoint0.SubTrees[replacedSubtreeIndex].GetSize()); 70 int maxInsertedBranchHeight = maxTreeHeight - GetBranchLevel(parent0.Root, crossoverPoint0); 71 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; 77 78 if (allowedBranches.Count() > 0) { 79 var selectedBranch = SelectRandomBranch(random, allowedBranches, internalCrossoverPointProbability); 80 81 // manipulate the tree of parent0 in place 82 // replace the branch in tree0 with the selected branch from tree1 83 crossoverPoint0.RemoveSubTree(replacedSubtreeIndex); 84 crossoverPoint0.InsertSubTree(replacedSubtreeIndex, selectedBranch); 85 return parent0; 86 } 87 } 88 89 // TODO: we should have a way to track the number of failed crossover attempts 90 // for now just return the first parent unchanged 91 return parent0; 92 } 93 94 private static void SelectCrossoverPoint(IRandom random, SymbolicExpressionTree parent0, double internalNodeProbability, out SymbolicExpressionTreeNode crossoverPoint, out int subtreeIndex) { 95 var crossoverPoints = from branch in IterateNodes(parent0.Root) 96 where branch.SubTrees.Count > 0 97 from index in Enumerable.Range(0, branch.SubTrees.Count) 98 let p = new { CrossoverPoint = branch, SubtreeIndex = index, IsLeaf = branch.SubTrees[index].SubTrees.Count == 0 } 99 select p; 100 var internalCrossoverPoints = (from p in crossoverPoints 101 where !p.IsLeaf 102 select p).ToList(); 103 // select internal crossover point or leaf 104 if (random.NextDouble() < internalNodeProbability && internalCrossoverPoints.Count > 0) { 105 var selectedCrossoverPoint = internalCrossoverPoints[random.Next(internalCrossoverPoints.Count)]; 106 crossoverPoint = selectedCrossoverPoint.CrossoverPoint; 107 subtreeIndex = selectedCrossoverPoint.SubtreeIndex; 108 } else { 109 var leafCrossoverPoints = (from p in crossoverPoints 110 where p.IsLeaf 111 select p).ToList(); 112 var selectedCrossoverPoint = leafCrossoverPoints[random.Next(leafCrossoverPoints.Count)]; 113 crossoverPoint = selectedCrossoverPoint.CrossoverPoint; 114 subtreeIndex = selectedCrossoverPoint.SubtreeIndex; 36 115 } 37 116 } 38 117 39 internal override IFunctionTree Cross(TreeGardener gardener, IRandom random, IFunctionTree tree0, IFunctionTree tree1, int maxTreeSize, int maxTreeHeight) { 40 int tries = 0; 41 List<IFunctionTree> allowedCrossoverPoints = null; 42 IFunctionTree parent0; 43 int replacedChildIndex; 44 do { 45 // select a random crossover point in the first parent tree0 46 parent0 = null; 47 while (parent0 == null) parent0 = gardener.GetRandomParentNode(tree0); 48 // select a random branch to replace 49 replacedChildIndex = random.Next(parent0.SubTrees.Count); 50 51 // calculate the max size and height that the inserted branch can have 52 int maxInsertedBranchSize = maxTreeSize - (tree0.GetSize() - parent0.SubTrees[replacedChildIndex].GetSize()); 53 int maxInsertedBranchHeight = maxTreeHeight - gardener.GetBranchLevel(tree0, parent0); // branchlevel is 1 if tree0==parent0 54 55 IList<IFunction> allowedFunctions = new List<IFunction>(gardener.GetAllowedSubFunctions(parent0.Function, replacedChildIndex)); 56 allowedCrossoverPoints = GetPossibleCrossoverPoints(tree1, maxInsertedBranchSize, maxInsertedBranchHeight, allowedFunctions); 57 } while (allowedCrossoverPoints.Count == 0 && tries++ < MaxRecombinationTries); 58 59 if (allowedCrossoverPoints.Count > 0) { 60 IFunctionTree branch1 = allowedCrossoverPoints[random.Next(allowedCrossoverPoints.Count)]; 61 62 // replace the branch in tree0 with the selected branch from tree1 63 parent0.RemoveSubTree(replacedChildIndex); 64 parent0.InsertSubTree(replacedChildIndex, branch1); 118 private static SymbolicExpressionTreeNode SelectRandomBranch(IRandom random, IEnumerable<SymbolicExpressionTreeNode> branches, double internalNodeProbability) { 119 if (internalNodeProbability < 0.0 || internalNodeProbability > 1.0) throw new ArgumentException("internalNodeProbability"); 120 var groupedBranches = from branch in branches 121 group branch by branch.SubTrees.Count into g 122 select g; 123 var allowedInternalBranches = (from g in groupedBranches 124 where g.Key > 0 125 from branch in g 126 select branch).ToList(); 127 if (random.NextDouble() < internalNodeProbability && allowedInternalBranches.Count > 0) { 128 return allowedInternalBranches[random.Next(allowedInternalBranches.Count)]; 129 } else { 130 var allowedLeafBranches = (from g in groupedBranches 131 where g.Key == 0 132 from leaf in g 133 select leaf).ToList(); 134 return allowedLeafBranches[random.Next(allowedLeafBranches.Count)]; 65 135 } 66 return tree0;67 136 } 68 137 69 private List<IFunctionTree> GetPossibleCrossoverPoints(IFunctionTree tree, int maxInsertedBranchSize, int maxInsertedBranchHeight, IList<IFunction> allowedFunctions) {70 List<IFunctionTree> crossoverPoints = new List<IFunctionTree>();71 foreach (IFunctionTree possiblePoint in TreeGardener.GetAllSubTrees(tree)) {72 if (allowedFunctions.Contains(possiblePoint.Function) && possiblePoint.GetSize() <= maxInsertedBranchSize && possiblePoint.GetHeight() <= maxInsertedBranchHeight)73 crossoverPoints.Add(possiblePoint);138 private static IEnumerable<SymbolicExpressionTreeNode> IterateNodes(SymbolicExpressionTreeNode root) { 139 foreach (var subTree in root.SubTrees) { 140 foreach (var branch in IterateNodes(subTree)) { 141 yield return branch; 142 } 74 143 } 75 return crossoverPoints; 144 yield return root; 145 } 146 147 private static int GetBranchLevel(SymbolicExpressionTreeNode root, SymbolicExpressionTreeNode point) { 148 if (root == point) return 0; 149 foreach (var subtree in root.SubTrees) { 150 int branchLevel = GetBranchLevel(subtree, point); 151 if (branchLevel < int.MaxValue) return 1 + branchLevel; 152 } 153 return int.MaxValue; 76 154 } 77 155 }
Note: See TracChangeset
for help on using the changeset viewer.