Changeset 815 for trunk/sources
- Timestamp:
- 11/25/08 23:20:03 (16 years ago)
- Location:
- trunk/sources/HeuristicLab.GP
- Files:
-
- 1 added
- 3 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/sources/HeuristicLab.GP/HeuristicLab.GP.csproj
r802 r815 71 71 <Compile Include="Logging\TreeArityAnalyser.cs" /> 72 72 <Compile Include="OffspringEqualiser.cs" /> 73 <Compile Include="Recombination\GPCrossoverBase.cs" /> 73 74 <Compile Include="Recombination\UniformCrossover.cs" /> 74 75 <Compile Include="UnknownFunctionException.cs" /> -
trunk/sources/HeuristicLab.GP/Recombination/OnePointCrossOver.cs
r812 r815 36 36 /// W. B. Langdon and R. Poli. Foundations of Genetic Programming. Springer-Verlag, 2002. 37 37 /// </summary> 38 public class OnePointCrossOver : OperatorBase { 38 public class OnePointCrossOver : GPCrossoverBase { 39 // internal data structure to represent crossover points 40 private class CrossoverPoint { 41 public IFunctionTree parent0; 42 public IFunctionTree parent1; 43 public int childIndex; 44 } 39 45 public override string Description { 40 46 get { … … 42 48 } 43 49 } 44 public OnePointCrossOver()45 : base() {46 AddVariableInfo(new VariableInfo("Random", "Pseudo random number generator", typeof(MersenneTwister), VariableKind.In));47 AddVariableInfo(new VariableInfo("OperatorLibrary", "The operator library containing all available operators", typeof(GPOperatorLibrary), VariableKind.In));48 AddVariableInfo(new VariableInfo("FunctionTree", "The tree to mutate", typeof(IFunctionTree), VariableKind.In | VariableKind.New));49 AddVariableInfo(new VariableInfo("TreeSize", "The size (number of nodes) of the tree", typeof(IntData), VariableKind.In | VariableKind.New));50 AddVariableInfo(new VariableInfo("TreeHeight", "The height of the tree", typeof(IntData), VariableKind.In | VariableKind.New));51 }52 50 53 public override IOperation Apply(IScope scope) { 54 MersenneTwister random = GetVariableValue<MersenneTwister>("Random", scope, true); 55 GPOperatorLibrary opLibrary = GetVariableValue<GPOperatorLibrary>("OperatorLibrary", scope, true); 56 TreeGardener gardener = new TreeGardener(random, opLibrary); 57 58 if ((scope.SubScopes.Count % 2) != 0) 59 throw new InvalidOperationException("Number of parents is not even"); 60 61 int crossoverEvents = scope.SubScopes.Count / 2; 62 for (int i = 0; i < crossoverEvents; i++) { 63 IScope parent1 = scope.SubScopes[0]; 64 scope.RemoveSubScope(parent1); 65 IScope parent2 = scope.SubScopes[0]; 66 scope.RemoveSubScope(parent2); 67 IScope child0 = new Scope((i * 2).ToString()); 68 IScope child1 = new Scope((i * 2 + 1).ToString()); 69 Cross(scope, random, gardener, parent1, parent2, child0, child1); 70 scope.AddSubScope(child0); 71 scope.AddSubScope(child1); 72 } 73 return null; 74 } 75 76 private void Cross(IScope scope, MersenneTwister random, TreeGardener gardener, IScope parent1, IScope parent2, IScope child0, IScope child1) { 77 IFunctionTree newTree0; 78 IFunctionTree newTree1; 79 Cross(random, gardener, parent1, parent2, out newTree0, out newTree1); 80 81 child0.AddVariable(new HeuristicLab.Core.Variable(scope.TranslateName("FunctionTree"), newTree0)); 82 child0.AddVariable(new HeuristicLab.Core.Variable(scope.TranslateName("TreeSize"), new IntData(newTree0.Size))); 83 child0.AddVariable(new HeuristicLab.Core.Variable(scope.TranslateName("TreeHeight"), new IntData(newTree0.Height))); 84 child1.AddVariable(new HeuristicLab.Core.Variable(scope.TranslateName("FunctionTree"), newTree1)); 85 child1.AddVariable(new HeuristicLab.Core.Variable(scope.TranslateName("TreeSize"), new IntData(newTree1.Size))); 86 child1.AddVariable(new HeuristicLab.Core.Variable(scope.TranslateName("TreeHeight"), new IntData(newTree1.Height))); 87 } 88 89 90 private void Cross(MersenneTwister random, TreeGardener gardener, IScope f, IScope g, out IFunctionTree child0, out IFunctionTree child1) { 91 IFunctionTree tree0 = f.GetVariableValue<IFunctionTree>("FunctionTree", false); 92 int tree0Height = f.GetVariableValue<IntData>("TreeHeight", false).Data; 93 int tree0Size = f.GetVariableValue<IntData>("TreeSize", false).Data; 94 95 IFunctionTree tree1 = g.GetVariableValue<IFunctionTree>("FunctionTree", false); 96 int tree1Height = g.GetVariableValue<IntData>("TreeHeight", false).Data; 97 int tree1Size = g.GetVariableValue<IntData>("TreeSize", false).Data; 98 99 List<CrossoverPoint> allowedCrossOverPoints = GetCrossOverPoints(gardener, tree0, tree1); 51 internal override IFunctionTree Cross(TreeGardener gardener, MersenneTwister random, IFunctionTree tree0, IFunctionTree tree1) { 52 List<CrossoverPoint> allowedCrossOverPoints = new List<CrossoverPoint>(); 53 GetCrossOverPoints(gardener, tree0, tree1, allowedCrossOverPoints); 100 54 if (allowedCrossOverPoints.Count > 0) { 101 55 CrossoverPoint crossOverPoint = allowedCrossOverPoints[random.Next(allowedCrossOverPoints.Count)]; 102 56 IFunctionTree parent0 = crossOverPoint.parent0; 103 IFunctionTree parent1 = crossOverPoint.parent1;104 IFunctionTree branch0 = crossOverPoint.parent0.SubTrees[crossOverPoint.childIndex];105 57 IFunctionTree branch1 = crossOverPoint.parent1.SubTrees[crossOverPoint.childIndex]; 106 58 parent0.RemoveSubTree(crossOverPoint.childIndex); 107 parent1.RemoveSubTree(crossOverPoint.childIndex);108 59 parent0.InsertSubTree(crossOverPoint.childIndex, branch1); 109 parent1.InsertSubTree(crossOverPoint.childIndex, branch0);110 60 } 111 112 child0 = tree0; 113 child1 = tree1; 114 } 115 class CrossoverPoint { 116 public IFunctionTree parent0; 117 public IFunctionTree parent1; 118 public int childIndex; 61 return tree0; 119 62 } 120 63 121 private List<CrossoverPoint> GetCrossOverPoints(TreeGardener gardener, IFunctionTree branch0, IFunctionTree branch1) { 122 List<CrossoverPoint> results = new List<CrossoverPoint>(); 123 if (branch0.SubTrees.Count != branch1.SubTrees.Count) return results; 64 private void GetCrossOverPoints(TreeGardener gardener, IFunctionTree branch0, IFunctionTree branch1, List<CrossoverPoint> crossoverPoints) { 65 if (branch0.SubTrees.Count != branch1.SubTrees.Count) return; 124 66 125 67 for (int i = 0; i < branch0.SubTrees.Count; i++) { 126 // if the branches fit to the parent 127 if (gardener.GetAllowedSubFunctions(branch0.Function, i).Contains(branch1.SubTrees[i].Function) && 128 gardener.GetAllowedSubFunctions(branch1.Function, i).Contains(branch0.SubTrees[i].Function)) { 68 // if the current branch can be attached as a sub-tree to branch0 69 if (gardener.GetAllowedSubFunctions(branch0.Function, i).Contains(branch1.SubTrees[i].Function)) { 129 70 CrossoverPoint p = new CrossoverPoint(); 130 71 p.childIndex = i; 131 72 p.parent0 = branch0; 132 73 p.parent1 = branch1; 133 results.Add(p);74 crossoverPoints.Add(p); 134 75 } 135 results.AddRange(GetCrossOverPoints(gardener, branch0.SubTrees[i], branch1.SubTrees[i]));76 GetCrossOverPoints(gardener, branch0.SubTrees[i], branch1.SubTrees[i], crossoverPoints); 136 77 } 137 return results;138 78 } 139 79 } -
trunk/sources/HeuristicLab.GP/Recombination/UniformCrossover.cs
r813 r815 37 37 /// In Proceedings of Genetic Programming '98, Madison, Wisconsin, 1998. 38 38 /// </summary> 39 public class UniformCrossover : OperatorBase { 39 public class UniformCrossover : GPCrossoverBase { 40 // internal datastructure to represent crossover points 41 private class CrossoverPoint { 42 public IFunctionTree Parent0; 43 public IFunctionTree Parent1; 44 public int ChildIndex; 45 public bool IsInternal; 46 } 47 40 48 public override string Description { 41 49 get { … … 43 51 } 44 52 } 45 public UniformCrossover()46 : base() {47 AddVariableInfo(new VariableInfo("Random", "Pseudo random number generator", typeof(MersenneTwister), VariableKind.In));48 AddVariableInfo(new VariableInfo("OperatorLibrary", "The operator library containing all available operators", typeof(GPOperatorLibrary), VariableKind.In));49 AddVariableInfo(new VariableInfo("FunctionTree", "The tree to mutate", typeof(IFunctionTree), VariableKind.In | VariableKind.New));50 AddVariableInfo(new VariableInfo("TreeSize", "The size (number of nodes) of the tree", typeof(IntData), VariableKind.In | VariableKind.New));51 AddVariableInfo(new VariableInfo("TreeHeight", "The height of the tree", typeof(IntData), VariableKind.In | VariableKind.New));52 }53 53 54 public override IOperation Apply(IScope scope) { 55 MersenneTwister random = GetVariableValue<MersenneTwister>("Random", scope, true); 56 GPOperatorLibrary opLibrary = GetVariableValue<GPOperatorLibrary>("OperatorLibrary", scope, true); 57 TreeGardener gardener = new TreeGardener(random, opLibrary); 58 59 if ((scope.SubScopes.Count % 2) != 0) 60 throw new InvalidOperationException("Number of parents is not even"); 61 62 CompositeOperation initOperations = new CompositeOperation(); 63 64 int crossoverEvents = scope.SubScopes.Count / 2; 65 for (int i = 0; i < crossoverEvents; i++) { 66 IScope parent1 = scope.SubScopes[0]; 67 scope.RemoveSubScope(parent1); 68 IScope parent2 = scope.SubScopes[0]; 69 scope.RemoveSubScope(parent2); 70 IScope child0 = new Scope((i * 2).ToString()); 71 IScope child1 = new Scope((i * 2 + 1).ToString()); 72 Cross(scope, random, gardener, parent1, parent2, child0, child1); 73 scope.AddSubScope(child0); 74 scope.AddSubScope(child1); 75 } 76 77 return null; 78 } 79 80 private void Cross(IScope scope, MersenneTwister random, TreeGardener gardener, IScope parent1, IScope parent2, IScope child0, IScope child1) { 81 IFunctionTree childTree0; 82 IFunctionTree childTree1; 83 Cross(random, gardener, parent1, parent2, out childTree0, out childTree1); 84 Debug.Assert(gardener.IsValidTree(childTree0)); 85 Debug.Assert(gardener.IsValidTree(childTree1)); 86 child0.AddVariable(new HeuristicLab.Core.Variable(scope.TranslateName("FunctionTree"), childTree0)); 87 child0.AddVariable(new HeuristicLab.Core.Variable(scope.TranslateName("TreeSize"), new IntData(childTree0.Size))); 88 child0.AddVariable(new HeuristicLab.Core.Variable(scope.TranslateName("TreeHeight"), new IntData(childTree0.Height))); 89 90 child1.AddVariable(new HeuristicLab.Core.Variable(scope.TranslateName("FunctionTree"), childTree1)); 91 child1.AddVariable(new HeuristicLab.Core.Variable(scope.TranslateName("TreeSize"), new IntData(childTree1.Size))); 92 child1.AddVariable(new HeuristicLab.Core.Variable(scope.TranslateName("TreeHeight"), new IntData(childTree1.Height))); 93 } 94 95 96 private void Cross(MersenneTwister random, TreeGardener gardener, IScope f, IScope g, out IFunctionTree child0, out IFunctionTree child1) { 97 IFunctionTree tree0 = f.GetVariableValue<IFunctionTree>("FunctionTree", false); 98 int tree0Height = f.GetVariableValue<IntData>("TreeHeight", false).Data; 99 int tree0Size = f.GetVariableValue<IntData>("TreeSize", false).Data; 100 101 IFunctionTree tree1 = g.GetVariableValue<IFunctionTree>("FunctionTree", false); 102 int tree1Height = g.GetVariableValue<IntData>("TreeHeight", false).Data; 103 int tree1Size = g.GetVariableValue<IntData>("TreeSize", false).Data; 104 105 List<CrossoverPoint> allowedCrossOverPoints = GetCrossOverPoints(gardener, tree0, tree1); 106 foreach (CrossoverPoint p in allowedCrossOverPoints) { 107 Debug.Assert(gardener.GetAllowedSubFunctions(p.parent0.Function, p.childIndex).Contains(p.parent1.SubTrees[p.childIndex].Function)); 108 Debug.Assert(gardener.GetAllowedSubFunctions(p.parent1.Function, p.childIndex).Contains(p.parent0.SubTrees[p.childIndex].Function)); 109 } 54 internal override IFunctionTree Cross(TreeGardener gardener, MersenneTwister random, IFunctionTree tree0, IFunctionTree tree1) { 55 List<CrossoverPoint> allowedCrossOverPoints = new List<CrossoverPoint>(); 56 GetCrossOverPoints(gardener, tree0, tree1, allowedCrossOverPoints); 110 57 // iterate through the list of crossover points and swap nodes with p=0.5 111 58 foreach (CrossoverPoint crossoverPoint in allowedCrossOverPoints) { 112 59 if (random.NextDouble() < 0.5) { 113 IFunctionTree parent0 = crossoverPoint.parent0; 114 IFunctionTree parent1 = crossoverPoint.parent1; 115 IFunctionTree branch0 = crossoverPoint.parent0.SubTrees[crossoverPoint.childIndex]; 116 IFunctionTree branch1 = crossoverPoint.parent1.SubTrees[crossoverPoint.childIndex]; 60 if (crossoverPoint.IsInternal) { 61 ExchangeNodes(crossoverPoint); 62 } else { 63 SwapSubtrees(crossoverPoint); 64 } 65 } 66 } 67 return tree0; 68 } 117 69 118 // if we are at an internal node of the common region swap only the node but not the subtrees 119 if (branch0.SubTrees.Count == branch1.SubTrees.Count) { 120 if (parent0 != null) { 121 Debug.Assert(parent1 != null); Debug.Assert(branch0 != null); Debug.Assert(branch0 != null); 122 Debug.Assert(gardener.GetAllowedSubFunctions(parent0.Function, crossoverPoint.childIndex).Contains(branch1.Function)); 123 Debug.Assert(gardener.GetAllowedSubFunctions(parent1.Function, crossoverPoint.childIndex).Contains(branch0.Function)); 124 // we are not at the root => exchange the branches in the parent 125 parent0.RemoveSubTree(crossoverPoint.childIndex); 126 parent1.RemoveSubTree(crossoverPoint.childIndex); 127 parent0.InsertSubTree(crossoverPoint.childIndex, branch1); 128 parent1.InsertSubTree(crossoverPoint.childIndex, branch0); 129 } 130 // always exchange all children 131 List<IFunctionTree> branch0Children = new List<IFunctionTree>(branch0.SubTrees); // create backup lists 132 List<IFunctionTree> branch1Children = new List<IFunctionTree>(branch1.SubTrees); 133 while (branch0.SubTrees.Count > 0) branch0.RemoveSubTree(0); // remove all children 134 while (branch1.SubTrees.Count > 0) branch1.RemoveSubTree(0); 135 foreach (IFunctionTree subTree in branch1Children) { 136 Debug.Assert(gardener.GetAllowedSubFunctions(branch0.Function, branch0.SubTrees.Count).Contains(subTree.Function)); 137 branch0.AddSubTree(subTree); // append children of branch1 to branch0 138 } 139 foreach (IFunctionTree subTree in branch0Children) { 140 Debug.Assert(gardener.GetAllowedSubFunctions(branch1.Function, branch1.SubTrees.Count).Contains(subTree.Function)); 141 branch1.AddSubTree(subTree); // and vice versa 142 } 70 private void GetCrossOverPoints(TreeGardener gardener, IFunctionTree branch0, IFunctionTree branch1, List<CrossoverPoint> crossoverPoints) { 71 if (branch0.SubTrees.Count != branch1.SubTrees.Count) return; // branches have to have same number of sub-trees to be valid crossover points 72 // iterate over all sub-trees 73 for (int i = 0; i < branch0.SubTrees.Count; i++) { 74 IFunctionTree currentSubTree0 = branch0.SubTrees[i]; 75 IFunctionTree currentSubTree1 = branch1.SubTrees[i]; 76 // when the current sub-tree in branch1 can be attached as a child of branch0 77 // and the sub-tree of branch0 can be attached as child of branch1. 78 // note: we have to check both cases because either branch0 or branch1 can end up in the result tree 79 if (gardener.GetAllowedSubFunctions(branch0.Function, i).Contains(currentSubTree1.Function) && 80 gardener.GetAllowedSubFunctions(branch1.Function, i).Contains(currentSubTree0.Function)) { 81 // and the sub-tree is at the border of the common region 82 if (currentSubTree0.SubTrees.Count != currentSubTree1.SubTrees.Count) { 83 // then we have found a valid crossover point 84 CrossoverPoint p = new CrossoverPoint(); 85 p.ChildIndex = i; 86 p.Parent0 = branch0; 87 p.Parent1 = branch1; 88 p.IsInternal = false; 89 crossoverPoints.Add(p); 143 90 } else { 144 // If we are at a node at the border of the common region then exchange the whole branch. 145 // If we are at the root node and the number of children is already different we can't do anything now but 146 // at the end either tree0 or tree1 must be returned with p=0.5. 147 148 // However if we are not at the root => exchange the branches in the parent 149 if (parent0 != null) { 150 Debug.Assert(parent1 != null); Debug.Assert(branch0 != null); Debug.Assert(branch1 != null); 151 Debug.Assert(gardener.GetAllowedSubFunctions(parent0.Function, crossoverPoint.childIndex).Contains(branch1.Function)); 152 Debug.Assert(gardener.GetAllowedSubFunctions(parent1.Function, crossoverPoint.childIndex).Contains(branch0.Function)); 153 parent0.RemoveSubTree(crossoverPoint.childIndex); 154 parent1.RemoveSubTree(crossoverPoint.childIndex); 155 parent0.InsertSubTree(crossoverPoint.childIndex, branch1); 156 parent1.InsertSubTree(crossoverPoint.childIndex, branch0); 91 // when the sub-trees are not on the border of the common region 92 // we also have to check if the children of the current sub-trees of branch0 and branch1 can be exchanged 93 if (CanHaveSubTrees(gardener, currentSubTree0, currentSubTree1.SubTrees) && 94 CanHaveSubTrees(gardener, currentSubTree1, currentSubTree0.SubTrees)) { 95 CrossoverPoint p = new CrossoverPoint(); 96 p.ChildIndex = i; 97 p.Parent0 = branch0; 98 p.Parent1 = branch1; 99 p.IsInternal = true; 100 crossoverPoints.Add(p); 157 101 } 158 102 } 159 103 } 104 GetCrossOverPoints(gardener, currentSubTree0, currentSubTree1, crossoverPoints); 160 105 } 161 child0 = tree0;162 child1 = tree1;163 106 } 164 107 165 class CrossoverPoint { 166 public IFunctionTree parent0; 167 public IFunctionTree parent1; 168 public int childIndex; 108 private bool CanHaveSubTrees(TreeGardener gardener, IFunctionTree parent, IList<IFunctionTree> subTrees) { 109 for (int i = 0; i < subTrees.Count; i++) { 110 if (!gardener.GetAllowedSubFunctions(parent.Function, i).Contains(subTrees[i].Function)) return false; 111 } 112 return true; 169 113 } 170 114 171 private List<CrossoverPoint> GetCrossOverPoints(TreeGardener gardener, IFunctionTree branch0, IFunctionTree branch1) { 172 List<CrossoverPoint> results = new List<CrossoverPoint>(); 173 if (branch0.SubTrees.Count != branch1.SubTrees.Count) return results; 115 private void ExchangeNodes(CrossoverPoint crossoverPoint) { 116 IFunctionTree parent0 = crossoverPoint.Parent0; 117 IFunctionTree parent1 = crossoverPoint.Parent1; 118 int childIndex = crossoverPoint.ChildIndex; 119 IFunctionTree branch0 = crossoverPoint.Parent0.SubTrees[childIndex]; 120 IFunctionTree branch1 = crossoverPoint.Parent1.SubTrees[childIndex]; 121 // exchange the branches in the parent 122 parent0.RemoveSubTree(childIndex); 123 parent0.InsertSubTree(childIndex, branch1); 124 parent1.RemoveSubTree(childIndex); 125 parent1.InsertSubTree(childIndex, branch0); 174 126 175 for (int i = 0; i < branch0.SubTrees.Count; i++) { 176 // if the branches fit to the parent 177 if (gardener.GetAllowedSubFunctions(branch0.Function, i).Contains(branch1.SubTrees[i].Function) && 178 gardener.GetAllowedSubFunctions(branch1.Function, i).Contains(branch0.SubTrees[i].Function)) { 179 // if the point is at the border of the common region we don't care about the children 180 // however if the point is not on the border of the common region we also have to check if 181 // the children of the branches fit together 182 bool fit = true; 183 if (branch0.SubTrees[i].SubTrees.Count == branch1.SubTrees[i].SubTrees.Count) { 184 for (int j = 0; j < branch0.SubTrees[i].SubTrees.Count; j++) { 185 fit = fit & gardener.GetAllowedSubFunctions(branch0.SubTrees[i].Function, j).Contains(branch1.SubTrees[i].SubTrees[j].Function); 186 fit = fit & gardener.GetAllowedSubFunctions(branch1.SubTrees[i].Function, j).Contains(branch0.SubTrees[i].SubTrees[j].Function); 187 } 188 } 189 if (fit) { 190 CrossoverPoint p = new CrossoverPoint(); 191 p.childIndex = i; 192 p.parent0 = branch0; 193 p.parent1 = branch1; 194 results.Add(p); 195 } 196 } 197 results.AddRange(GetCrossOverPoints(gardener, branch0.SubTrees[i], branch1.SubTrees[i])); 127 ExchangeChildren(branch0, branch1); 128 } 129 130 private void SwapSubtrees(CrossoverPoint crossoverPoint) { 131 IFunctionTree parent0 = crossoverPoint.Parent0; 132 IFunctionTree parent1 = crossoverPoint.Parent1; 133 int childIndex = crossoverPoint.ChildIndex; 134 IFunctionTree branch0 = crossoverPoint.Parent0.SubTrees[childIndex]; 135 IFunctionTree branch1 = crossoverPoint.Parent1.SubTrees[childIndex]; 136 // insert branch1 into parent0 replacing branch0 137 parent0.RemoveSubTree(childIndex); 138 parent0.InsertSubTree(childIndex, branch1); 139 // insert branch0 into parent1 replacing branch1 140 parent1.RemoveSubTree(childIndex); 141 parent1.InsertSubTree(childIndex, branch0); 142 } 143 144 private void ExchangeChildren(IFunctionTree branch0, IFunctionTree branch1) { 145 List<IFunctionTree> branch0Children = new List<IFunctionTree>(branch0.SubTrees); // lists to backup subtrees 146 List<IFunctionTree> branch1Children = new List<IFunctionTree>(branch1.SubTrees); 147 148 // remove children of branch0 and branch1 149 while (branch1.SubTrees.Count > 0) branch1.RemoveSubTree(0); 150 while (branch0.SubTrees.Count > 0) branch0.RemoveSubTree(0); 151 152 // add original children of branch0 to branch1 153 foreach (IFunctionTree subTree in branch0Children) { 154 branch1.AddSubTree(subTree); 198 155 } 199 return results; 156 // add original children of branch1 to branch0 157 foreach (IFunctionTree subTree in branch1Children) { 158 branch0.AddSubTree(subTree); 159 } 200 160 } 201 161 }
Note: See TracChangeset
for help on using the changeset viewer.