- Timestamp:
- 11/26/08 23:41:56 (16 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/sources/HeuristicLab.GP/Recombination/SizeFairCrossOver.cs
r833 r835 38 38 /// Genetic Programming and Evolvable Machines, Vol. 1, Number 1/2, pp. 95-119, April 2000 39 39 /// </summary> 40 public class SizeFairCrossOver : GPCrossoverBase {40 public class SizeFairCrossOver : SizeConstrictedGPCrossoverBase { 41 41 private const int MAX_RECOMBINATION_TRIES = 20; 42 public override string Description { 43 get { 44 return @""; 45 } 46 } 47 public SizeFairCrossOver() 48 : base() { 49 AddVariableInfo(new VariableInfo("MaxTreeHeight", "The maximal allowed height of the tree", typeof(IntData), VariableKind.In)); 50 AddVariableInfo(new VariableInfo("MaxTreeSize", "The maximal allowed size (number of nodes) of the tree", typeof(IntData), VariableKind.In)); 42 // private data structure for crossover points 43 protected class CrossoverPoint { 44 public IFunctionTree tree; 45 public int branchSize; 46 public List<int> trail; 51 47 } 52 48 53 internal override IFunctionTree Cross(IScope scope, TreeGardener gardener, MersenneTwister random, IFunctionTree tree0, IFunctionTree tree1) { 54 int maxTreeHeight = GetVariableValue<IntData>("MaxTreeHeight", scope, true).Data; 55 int maxTreeSize = GetVariableValue<IntData>("MaxTreeSize", scope, true).Data; 56 57 // when tree0 is terminal then try to cross into tree1, when tree1 is also terminal just return tree0 unchanged. 58 IFunctionTree newTree; 59 if(tree0.SubTrees.Count > 0) { 60 newTree = Cross(gardener, tree0, tree1, random, maxTreeSize, maxTreeHeight); 61 } else if(tree1.SubTrees.Count > 0) { 62 newTree = Cross(gardener, tree1, tree0, random, maxTreeSize, maxTreeHeight); 63 } else newTree = tree0; 64 65 // check if the height and size of the new tree are still in the allowed bounds 66 Debug.Assert(newTree.Height <= maxTreeHeight); 67 Debug.Assert(newTree.Size <= maxTreeSize); 68 return newTree; 69 } 70 71 private IFunctionTree Cross(TreeGardener gardener, IFunctionTree tree0, IFunctionTree tree1, MersenneTwister random, int maxTreeSize, int maxTreeHeight) { 49 internal override IFunctionTree Cross(TreeGardener gardener, MersenneTwister random, IFunctionTree tree0, IFunctionTree tree1, int maxTreeSize, int maxTreeHeight) { 72 50 int tries = 0; 73 51 IFunctionTree insertedBranch = null; 74 IFunctionTree crossoverPoint = null;52 IFunctionTree parent = null; 75 53 int removedBranchIndex = 0; 76 54 do { 77 55 // select a random suboperator of the 'receiving' tree 78 while(crossoverPoint == null) crossoverPoint = gardener.GetRandomParentNode(tree0); 79 removedBranchIndex = random.Next(crossoverPoint.SubTrees.Count); 80 IFunctionTree removedBranch = crossoverPoint.SubTrees[removedBranchIndex]; 81 IList<IFunction> allowedFunctions = gardener.GetAllowedSubFunctions(crossoverPoint.Function, removedBranchIndex); 82 int removedBranchSize = removedBranch.Size; 83 int maxBranchSize = maxTreeSize - (tree0.Size - removedBranchSize); 84 int maxBranchHeight = maxTreeHeight - gardener.GetBranchLevel(tree0, crossoverPoint); 85 insertedBranch = GetReplacementBranch(random, gardener, allowedFunctions, tree1, removedBranchSize, maxBranchSize, maxBranchHeight); 86 } while(insertedBranch == null && tries++ < MAX_RECOMBINATION_TRIES); 56 while (parent == null) parent = gardener.GetRandomParentNode(tree0); 57 removedBranchIndex = random.Next(parent.SubTrees.Count); 58 insertedBranch = GetReplacementBranch(random, gardener, tree0, parent, removedBranchIndex, tree1, maxTreeSize, maxTreeHeight); 59 } while (insertedBranch == null && tries++ < MAX_RECOMBINATION_TRIES); 87 60 88 if (insertedBranch != null) {61 if (insertedBranch != null) { 89 62 // replace the branch below the crossoverpoint with the selected branch from root1 90 crossoverPoint.RemoveSubTree(removedBranchIndex);91 crossoverPoint.InsertSubTree(removedBranchIndex, insertedBranch);63 parent.RemoveSubTree(removedBranchIndex); 64 parent.InsertSubTree(removedBranchIndex, insertedBranch); 92 65 } 93 66 return tree0; 94 67 } 95 68 96 private IFunctionTree GetReplacementBranch(IRandom random, TreeGardener gardener, IList<IFunction> allowedFunctions, IFunctionTree tree, int removedBranchSize, int maxBranchSize, int maxBranchHeight) { 97 var branches = gardener.GetAllSubTrees(tree).Where(t => allowedFunctions.Contains(t.Function) && t.Size <= maxBranchSize && t.Height <= maxBranchHeight) 98 .Select(t => new { Tree = t, Size = t.Size }).Where(s => s.Size < 2 * removedBranchSize + 1); 69 private IFunctionTree GetReplacementBranch(MersenneTwister random, TreeGardener gardener, IFunctionTree intoTree, IFunctionTree parent, int replacedBranchIndex, IFunctionTree fromTree, int maxTreeSize, int maxTreeHeight) { 70 IList<IFunction> allowedFunctions = gardener.GetAllowedSubFunctions(parent.Function, replacedBranchIndex); 71 int removedBranchSize = parent.SubTrees[replacedBranchIndex].Size; 72 int maxBranchSize = maxTreeSize - (intoTree.Size - removedBranchSize); 73 int maxBranchHeight = maxTreeHeight - gardener.GetBranchLevel(intoTree, parent); // returns 1 if intoTree==parent and 2 if parent is a child of intoTree 74 List<int> replacedTrail = GetTrail(intoTree, parent); 75 replacedTrail.Add(replacedBranchIndex); 99 76 100 var shorterBranches = branches.Where(t => t.Size < removedBranchSize);101 var longerBranches = branches.Where(t => t.Size > removedBranchSize);102 var equalLengthBranches = branches.Where(t => t.Size == removedBranchSize);77 List<CrossoverPoint> shorterBranches = new List<CrossoverPoint>(); 78 List<CrossoverPoint> longerBranches = new List<CrossoverPoint>(); 79 List<CrossoverPoint> equalLengthBranches = new List<CrossoverPoint>(); 103 80 104 if(shorterBranches.Count() == 0 || longerBranches.Count() == 0) { 105 if(equalLengthBranches.Count() == 0) { 106 return null; 107 } else { 108 return equalLengthBranches.ElementAt(random.Next(equalLengthBranches.Count())).Tree; 109 } 110 } else { 111 // invariant: |shorterBranches| > 0 and |longerBranches| > 0 112 double pEqualLength = equalLengthBranches.Count() > 0 ? 1.0 / removedBranchSize : 0.0; 113 double pLonger = (1.0 - pEqualLength) / (longerBranches.Count() * (1.0 + longerBranches.Average(t => t.Size) / shorterBranches.Average(t => t.Size))); 81 FindPossibleBranches(fromTree, allowedFunctions, maxBranchSize, maxBranchHeight, removedBranchSize, shorterBranches, equalLengthBranches, longerBranches, new List<int>()); 82 83 if (shorterBranches.Count > 0 && longerBranches.Count > 0) { 84 double pEqualLength = equalLengthBranches.Count > 0 ? 1.0 / removedBranchSize : 0.0; 85 double pLonger = (1.0 - pEqualLength) / (longerBranches.Count * (1.0 + longerBranches.Average(p => p.branchSize) / shorterBranches.Average(p => p.branchSize))); 114 86 double pShorter = (1.0 - pEqualLength - pLonger); 115 87 116 88 double r = random.NextDouble(); 117 if (r < pLonger) {118 return longerBranches.ElementAt(random.Next(longerBranches.Count())).Tree;119 } else if (r < pLonger + pShorter) {120 return shorterBranches.ElementAt(random.Next(shorterBranches.Count())).Tree;89 if (r < pLonger) { 90 return SelectReplacement(random, replacedTrail, longerBranches); 91 } else if (r < pLonger + pShorter) { 92 return SelectReplacement(random, replacedTrail, shorterBranches); 121 93 } else { 122 return equalLengthBranches.ElementAt(random.Next(equalLengthBranches.Count())).Tree; 94 return SelectReplacement(random, replacedTrail, equalLengthBranches); 95 } 96 } else if (equalLengthBranches.Count > 0) { 97 return SelectReplacement(random, replacedTrail, equalLengthBranches); 98 } else { 99 return null; 100 } 101 } 102 103 protected virtual IFunctionTree SelectReplacement(MersenneTwister random, List<int> replacedTrail, List<CrossoverPoint> crossoverPoints) { 104 return crossoverPoints[random.Next(crossoverPoints.Count)].tree; 105 } 106 107 private void FindPossibleBranches(IFunctionTree tree, IList<IFunction> allowedFunctions, int maxBranchSize, int maxBranchHeight, int removedBranchSize, 108 List<CrossoverPoint> shorterBranches, List<CrossoverPoint> equalLengthBranches, List<CrossoverPoint> longerBranches, List<int> trail) { 109 int treeSize = tree.Size; 110 if (allowedFunctions.Contains(tree.Function) && treeSize <= maxBranchSize && tree.Height <= maxBranchHeight) { 111 CrossoverPoint p = new CrossoverPoint(); 112 p.branchSize = treeSize; 113 p.tree = tree; 114 p.trail = new List<int>(trail); 115 if (treeSize < removedBranchSize) shorterBranches.Add(p); 116 else if (treeSize > removedBranchSize) longerBranches.Add(p); 117 else equalLengthBranches.Add(p); 118 } 119 for (int i = 0; i < tree.SubTrees.Count; i++) { 120 trail.Add(i); 121 FindPossibleBranches(tree.SubTrees[i], allowedFunctions, maxBranchSize, maxBranchHeight, removedBranchSize, shorterBranches, equalLengthBranches, longerBranches, trail); 122 trail.RemoveAt(trail.Count - 1); 123 } 124 } 125 126 private List<int> GetTrail(IFunctionTree root, IFunctionTree branch) { 127 List<int> trail = new List<int>(); 128 GetTrail(root, branch, trail); 129 trail.Reverse(); 130 trail.RemoveAt(trail.Count - 1); 131 return trail; 132 } 133 private void GetTrail(IFunctionTree root, IFunctionTree branch, List<int> trail) { 134 if (root == branch) { 135 trail.Add(-1); // add flag that there was a match 136 return; 137 } 138 139 for (int i = 0; i < root.SubTrees.Count; i++) { 140 GetTrail(root.SubTrees[i], branch, trail); 141 if (trail.Count>0) { 142 trail.Add(i); 143 return; 123 144 } 124 145 }
Note: See TracChangeset
for help on using the changeset viewer.