Changeset 152
- Timestamp:
- 04/22/08 17:28:26 (17 years ago)
- Location:
- branches/FunctionsAndStructIdRefactoring/HeuristicLab.StructureIdentification
- Files:
-
- 7 edited
Legend:
- Unmodified
- Added
- Removed
-
branches/FunctionsAndStructIdRefactoring/HeuristicLab.StructureIdentification/GPOperatorGroup.cs
r2 r152 32 32 namespace HeuristicLab.StructureIdentification { 33 33 public class GPOperatorGroup : OperatorGroup { 34 35 34 public GPOperatorGroup() 36 35 : base() { … … 118 117 int maxArity; 119 118 GetMinMaxArity(op, out minArity, out maxArity); 120 ItemListslotsList = (ItemList)op.GetVariable(GPOperatorLibrary.ALLOWED_SUBOPERATORS).Value;119 var slotsList = (ItemList)op.GetVariable(GPOperatorLibrary.ALLOWED_SUBOPERATORS).Value; 121 120 slotsList.Clear(); 122 121 for(int i = 0; i < maxArity; i++) { … … 276 275 } 277 276 278 279 277 public override void AddSubGroup(IOperatorGroup group) { 280 278 throw new NotSupportedException(); -
branches/FunctionsAndStructIdRefactoring/HeuristicLab.StructureIdentification/Manipulation/ChangeNodeTypeManipulation.cs
r149 r152 81 81 // updating the variable is not necessary because it stays the same 82 82 } 83 if(!gardener.IsValidTree(root)) throw new InvalidProgramException(); 83 84 84 85 // size and height stays the same when changing a terminal so no need to update the variables … … 105 106 treeHeight.Data = gardener.GetTreeHeight(root); 106 107 108 // check if whole tree is ok 107 109 // check if the size of the new tree is still in the allowed bounds 108 if (treeHeight.Data > maxTreeHeight || 110 if (!gardener.IsValidTree(root) || 111 treeHeight.Data > maxTreeHeight || 109 112 treeSize.Data > maxTreeSize) { 110 113 throw new InvalidProgramException(); 111 114 } 112 115 113 // check if whole tree is ok114 if (!gardener.IsValidTree(root)) {115 throw new InvalidProgramException();116 }117 118 116 // return a composite operation that initializes all created sub-trees 119 117 return gardener.CreateInitializationOperation(uninitializedBranches, scope); 120 118 } 121 119 } 122 123 120 124 121 private IFunctionTree ChangeTerminalType(IFunctionTree parent, IFunctionTree child, int childIndex, TreeGardener gardener, MersenneTwister random) { … … 127 124 allowedChildren = gardener.Terminals; 128 125 } else { 129 SubOperatorsConstraintAnalyser analyser = new SubOperatorsConstraintAnalyser(); 130 analyser.AllPossibleOperators = gardener.Terminals.Cast<IOperator>().ToArray(); 131 allowedChildren = analyser.GetAllowedOperators(parent.Function, childIndex).Cast<IFunction>().ToList(); 126 allowedChildren = new List<IFunction>(); 127 var allAllowedChildren = gardener.GetAllowedSubFunctions(parent.Function, childIndex); 128 foreach(IFunction c in allAllowedChildren) { 129 if(gardener.IsTerminal(c)) allowedChildren.Add(c); 130 } 132 131 } 133 132 … … 144 143 // let's choose the function we want to use instead of the old child. For this we have to determine the 145 144 // pool of allowed functions based on constraints of the parent if there is one. 146 IList<IFunction> allowedFunctions; 147 SubOperatorsConstraintAnalyser analyser = new SubOperatorsConstraintAnalyser(); 148 analyser.AllPossibleOperators = gardener.AllFunctions.Cast<IOperator>().ToArray(); 149 if (parent == null) { 150 allowedFunctions = gardener.AllFunctions; 151 } else { 152 allowedFunctions = analyser.GetAllowedOperators(parent.Function, childIndex).Cast<IFunction>().ToList(); 153 } 145 IList<IFunction> allowedFunctions = gardener.GetAllowedSubFunctions(parent!=null?parent.Function:null, childIndex); 154 146 155 147 // try to make a tree with the same arity as the old child. … … 190 182 // then use a random existing sub-tree. When there are no existing sub-trees 191 183 // that fit in the given slot then create a new random tree and use it for the slot 192 I List<IFunction> allowedSubFunctions = analyser.GetAllowedOperators(newTree.Function, i).Cast<IFunction>().ToList();184 ICollection<IFunction> allowedSubFunctions = gardener.GetAllowedSubFunctions(newTree.Function, i); 193 185 var matchingSubTrees = availableSubTrees.Where(subTree => allowedSubFunctions.Contains(subTree.Function)); 194 186 -
branches/FunctionsAndStructIdRefactoring/HeuristicLab.StructureIdentification/Manipulation/CutOutNodeManipulation.cs
r149 r152 108 108 109 109 // match the sub-trees of the child with the allowed sub-trees of the parent 110 I List<IFunction> allowedFunctions = gardener.GetAllowedSubFunctions(parent.Function, childIndex);110 ICollection<IFunction> allowedFunctions = gardener.GetAllowedSubFunctions(parent.Function, childIndex); 111 111 IFunctionTree[] possibleChilds = child.SubTrees.Where(t => allowedFunctions.Contains(t.Function)).ToArray(); 112 112 -
branches/FunctionsAndStructIdRefactoring/HeuristicLab.StructureIdentification/Manipulation/DeleteSubTreeManipulation.cs
r149 r152 100 100 parent.RemoveSubTree(childIndex); 101 101 102 I List<IFunction> allowedFunctions = gardener.GetAllowedSubFunctions(parent.Function, childIndex);102 ICollection<IFunction> allowedFunctions = gardener.GetAllowedSubFunctions(parent.Function, childIndex); 103 103 IFunctionTree newFunctionTree = gardener.CreateRandomTree(allowedFunctions, 1, 1, true); 104 104 -
branches/FunctionsAndStructIdRefactoring/HeuristicLab.StructureIdentification/Manipulation/SubstituteSubTreeManipulation.cs
r149 r152 88 88 int childIndex = random.Next(parent.SubTrees.Count); 89 89 // get the list of allowed functions for the new sub-tree 90 I List<IFunction> allowedFunctions = gardener.GetAllowedSubFunctions(parent.Function, childIndex);90 ICollection<IFunction> allowedFunctions = gardener.GetAllowedSubFunctions(parent.Function, childIndex); 91 91 if(allowedFunctions.Count == 0) { 92 92 // don't change anything -
branches/FunctionsAndStructIdRefactoring/HeuristicLab.StructureIdentification/Recombination/SinglePointCrossOver.cs
r143 r152 78 78 } 79 79 80 81 80 private IOperation Cross(TreeGardener gardener, int maxTreeSize, int maxTreeHeight, 82 81 IScope scope, MersenneTwister random, IScope parent1, IScope parent2, IScope child) { … … 85 84 random, maxTreeSize, maxTreeHeight, out newBranches); 86 85 87 if(!gardener.IsValidTree(newTree)) {88 throw new InvalidProgramException();89 }90 86 91 87 int newTreeSize = gardener.GetTreeSize(newTree); 92 88 int newTreeHeight = gardener.GetTreeHeight(newTree); 93 child.AddVariable(new HeuristicLab.Core.Variable("FunctionTree", newTree)); 94 child.AddVariable(new HeuristicLab.Core.Variable("TreeSize", new IntData(newTreeSize))); 95 child.AddVariable(new HeuristicLab.Core.Variable("TreeHeight", new IntData(newTreeHeight))); 96 97 // check if the size of the new tree is still in the allowed bounds 98 if (newTreeHeight > maxTreeHeight || 89 child.AddVariable(new HeuristicLab.Core.Variable(scope.TranslateName("FunctionTree"), newTree)); 90 child.AddVariable(new HeuristicLab.Core.Variable(scope.TranslateName("TreeSize"), new IntData(newTreeSize))); 91 child.AddVariable(new HeuristicLab.Core.Variable(scope.TranslateName("TreeHeight"), new IntData(newTreeHeight))); 92 93 // check if the new tree is valid and if the size of is still in the allowed bounds 94 if(!gardener.IsValidTree(newTree) || 95 newTreeHeight > maxTreeHeight || 99 96 newTreeSize > maxTreeSize) { 100 97 throw new InvalidProgramException(); … … 139 136 140 137 List<int> possibleChildIndices = new List<int>(); 141 TreeGardener.FunctionEqualityComparer comparer = new TreeGardener.FunctionEqualityComparer();142 138 143 139 // Now tree0 is supposed to take tree1 as one if its children. If this is not possible, 144 140 // then go down in either of the two trees as far as possible. If even then it is not possible 145 141 // to merge the trees then throw an exception 146 // find the list of allowed indices (regarding allowed sub- operators, maxTreeSize and maxTreeHeight)142 // find the list of allowed indices (regarding allowed sub-trees, maxTreeSize and maxTreeHeight) 147 143 for(int i = 0; i < tree0.SubTrees.Count; i++) { 148 144 int subTreeSize = gardener.GetTreeSize(tree0.SubTrees[i]); 149 145 150 146 // the index is ok when the function is allowed as sub-tree and we don't violate the maxSize and maxHeight constraints 151 if( GetAllowedOperators(tree0.Function, i).Contains(tree1.Function, comparer) &&147 if(gardener.GetAllowedSubFunctions(tree0.Function, i).Contains(tree1.Function) && 152 148 rootSize - subTreeSize + tree1Size < maxTreeSize && 153 149 tree0Level + tree1Height < maxTreeHeight) { … … 157 153 158 154 while(possibleChildIndices.Count == 0) { 159 // okwe couln't find a possible configuration given the current tree0 and tree1155 // we couln't find a possible configuration given the current tree0 and tree1 160 156 // possible reasons for this are: 161 157 // - tree1 is not allowed as sub-tree of tree0 … … 187 183 // when the function is allowed as sub-tree and we don't violate the maxSize and maxHeight constraints 188 184 // the index is ok 189 if( GetAllowedOperators(tree0.Function, i).Contains(tree1.Function, comparer) &&185 if(gardener.GetAllowedSubFunctions(tree0.Function, i).Contains(tree1.Function) && 190 186 rootSize - subTreeSize + tree1Size < maxTreeSize && 191 187 tree0Level + tree1Height < maxTreeHeight) { … … 211 207 } 212 208 213 private ICollection<IFunction> GetAllowedOperators(IFunction f, int i) { 214 ItemList slotList = (ItemList)f.GetVariable(GPOperatorLibrary.ALLOWED_SUBOPERATORS).Value; 215 return ((ItemList)slotList[i]).Cast<IFunction>().ToArray(); 216 } 217 209 210 // take f and g and create a tree that has f and g as sub-trees 211 // example 212 // O 213 // /|\ 214 // g 2 f 215 // 218 216 private IFunctionTree CombineTerminals(TreeGardener gardener, IFunctionTree f, IFunctionTree g, MersenneTwister random, int maxTreeHeight, out List<IFunctionTree> newBranches) { 219 217 newBranches = new List<IFunctionTree>(); 218 // determine the set of possible parent functions 220 219 ICollection<IFunction> possibleParents = gardener.GetPossibleParents(new List<IFunction>() { f.Function, g.Function }); 221 220 if(possibleParents.Count == 0) throw new InvalidProgramException(); 222 221 // and select a random one 223 222 IFunctionTree parent = new FunctionTree(possibleParents.ElementAt(random.Next(possibleParents.Count()))); 224 223 … … 226 225 int maxArity; 227 226 gardener.GetMinMaxArity(parent.Function, out minArity, out maxArity); 228 229 227 int nSlots = Math.Max(2, minArity); 230 231 HashSet<IFunction>[] slotSets = new HashSet<IFunction>[nSlots]; 232 233 SubOperatorsConstraintAnalyser analyser = new SubOperatorsConstraintAnalyser(); 234 analyser.AllPossibleOperators = new List<IOperator>() { g.Function, f.Function }; 228 // determine which slot can take which sub-trees 229 List<IFunctionTree>[] slots = new List<IFunctionTree>[nSlots]; 235 230 for(int slot = 0; slot < nSlots; slot++) { 236 HashSet<IFunction> slotSet = new HashSet<IFunction>(analyser.GetAllowedOperators(parent.Function, slot).Cast<IFunction>()); 237 slotSets[slot] = slotSet; 238 } 239 240 int[] slotSequence = Enumerable.Range(0, slotSets.Count()).OrderBy(slot => slotSets[slot].Count()).ToArray(); 241 231 ICollection<IFunction> allowedSubFunctions = gardener.GetAllowedSubFunctions(parent.Function, slot); 232 List<IFunctionTree> allowedTrees = new List<IFunctionTree>(); 233 if(allowedSubFunctions.Contains(f.Function)) allowedTrees.Add(f); 234 if(allowedSubFunctions.Contains(g.Function)) allowedTrees.Add(g); 235 slots[slot] = allowedTrees; 236 } 237 // fill the slots in the order of degrees of freedom 238 int[] slotSequence = Enumerable.Range(0, slots.Count()).OrderBy(slot => slots[slot].Count()).ToArray(); 239 240 // tmp arry to store the tree for each sub-tree slot of the parent 242 241 IFunctionTree[] selectedFunctionTrees = new IFunctionTree[nSlots]; 242 243 // fill the sub-tree slots of the parent starting with the slots that can take potentially both functions (f and g) 243 244 for(int i = 0; i < slotSequence.Length; i++) { 244 245 int slot = slotSequence[i]; 245 HashSet<IFunction> slotSet = slotSets[slot]; 246 if(slotSet.Count() == 0) { 247 var allowedFunctions = GetAllowedOperators(parent.Function, slot); 246 List<IFunctionTree> allowedTrees = slots[slot]; 247 // when neither f nor g fit into the slot => create a new random tree 248 if(allowedTrees.Count() == 0) { 249 var allowedFunctions = gardener.GetAllowedSubFunctions(parent.Function, slot); 248 250 selectedFunctionTrees[slot] = gardener.CreateRandomTree(allowedFunctions, 1, 1, true); 249 251 newBranches.AddRange(gardener.GetAllSubTrees(selectedFunctionTrees[slot])); 250 252 } else { 251 IFunction selectedFunction = slotSet.ElementAt(random.Next(slotSet.Count())); 252 selectedFunctionTrees[slot] = new FunctionTree(selectedFunction); 253 // select randomly which tree to insert into this slot 254 IFunctionTree selectedTree = allowedTrees[random.Next(allowedTrees.Count())]; 255 selectedFunctionTrees[slot] = selectedTree; 256 // remove the tree that we used in this slot from following function-sets 253 257 for(int j = i + 1; j < slotSequence.Length; j++) { 254 258 int otherSlot = slotSequence[j]; 255 slot Sets[otherSlot].Remove(selectedFunction);256 } 257 } 258 } 259 259 slots[otherSlot].Remove(selectedTree); 260 } 261 } 262 } 263 // actually append the sub-trees to the parent tree 260 264 for(int i = 0; i < selectedFunctionTrees.Length; i++) { 261 265 parent.InsertSubTree(i, selectedFunctionTrees[i]); -
branches/FunctionsAndStructIdRefactoring/HeuristicLab.StructureIdentification/TreeGardener.cs
r148 r152 32 32 using HeuristicLab.Selection; 33 33 using HeuristicLab.Functions; 34 using System.Collections; 34 35 35 36 namespace HeuristicLab.StructureIdentification { 36 37 internal class TreeGardener { 37 38 private IRandom random; 38 private IOperatorLibrary funLibrary;39 private GPOperatorLibrary funLibrary; 39 40 private List<IFunction> functions; 40 41 private List<IFunction> terminals; … … 49 50 } 50 51 51 internal TreeGardener(IRandom random, IOperatorLibrary funLibrary) {52 internal TreeGardener(IRandom random, GPOperatorLibrary funLibrary) { 52 53 this.random = random; 53 54 this.funLibrary = funLibrary; … … 254 255 return allFunctions; 255 256 } else { 256 257 SubOperatorsConstraintAnalyser analyser = new SubOperatorsConstraintAnalyser(); 258 analyser.AllPossibleOperators = allFunctions.Cast<IOperator>().ToArray<IOperator>(); 259 260 return analyser.GetAllowedOperators(f, index).Cast<IFunction>().ToList<IFunction>(); 257 ItemList slotList = (ItemList)f.GetVariable(GPOperatorLibrary.ALLOWED_SUBOPERATORS).Value; 258 List<IFunction> result = new List<IFunction>(); 259 foreach(IFunction function in (ItemList)slotList[index]) { 260 result.Add(function); 261 } 262 return result; 261 263 } 262 264 } … … 284 286 List<IFunction> parents = new List<IFunction>(); 285 287 foreach (IFunction function in functions) { 286 I List<IFunction> allowedSubFunctions = GetAllowedSubFunctions(function, childIndex);287 if (allowedSubFunctions.Contains(child , new FunctionEqualityComparer())) {288 ICollection<IFunction> allowedSubFunctions = GetAllowedSubFunctions(function, childIndex); 289 if (allowedSubFunctions.Contains(child)) { 288 290 parents.Add(function); 289 291 } … … 377 379 #endregion 378 380 379 internal class FunctionEqualityComparer : IEqualityComparer<IFunction> {380 #region IEqualityComparer<IFunction> Members381 public bool Equals(IFunction x, IFunction y) {382 return x==y ||383 ((StringData)x.GetVariable(GPOperatorLibrary.TYPE_ID).Value).Data ==384 ((StringData)y.GetVariable(GPOperatorLibrary.TYPE_ID).Value).Data;385 }386 387 public int GetHashCode(IFunction obj) {388 return ((StringData)obj.GetVariable(GPOperatorLibrary.TYPE_ID).Value).Data.GetHashCode();389 }390 #endregion391 }392 393 381 internal ICollection<IFunction> GetPossibleParents(List<IFunction> list) { 394 382 List<IFunction> result = new List<IFunction>();
Note: See TracChangeset
for help on using the changeset viewer.