- Timestamp:
- 04/22/08 18:05:14 (16 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/sources/HeuristicLab.StructureIdentification/TreeGardener.cs
r23 r155 31 31 using HeuristicLab.Operators; 32 32 using HeuristicLab.Selection; 33 using HeuristicLab.Functions; 34 using System.Collections; 33 35 34 36 namespace HeuristicLab.StructureIdentification { 35 37 internal class TreeGardener { 36 38 private IRandom random; 37 private IOperatorLibrary opLibrary;38 private List<I Operator> functions;39 private List<I Operator> terminals;40 41 internal IList<I Operator> Terminals {39 private GPOperatorLibrary funLibrary; 40 private List<IFunction> functions; 41 private List<IFunction> terminals; 42 43 internal IList<IFunction> Terminals { 42 44 get { return terminals.AsReadOnly(); } 43 45 } 44 private List<I Operator> allOperators;45 46 internal IList<I Operator> AllOperators {47 get { return all Operators.AsReadOnly(); }48 } 49 50 internal TreeGardener(IRandom random, IOperatorLibrary opLibrary) {46 private List<IFunction> allFunctions; 47 48 internal IList<IFunction> AllFunctions { 49 get { return allFunctions.AsReadOnly(); } 50 } 51 52 internal TreeGardener(IRandom random, GPOperatorLibrary funLibrary) { 51 53 this.random = random; 52 this. opLibrary = opLibrary;53 54 this.all Operators = new List<IOperator>();55 terminals = new List<I Operator>();56 functions = new List<I Operator>();54 this.funLibrary = funLibrary; 55 56 this.allFunctions = new List<IFunction>(); 57 terminals = new List<IFunction>(); 58 functions = new List<IFunction>(); 57 59 58 60 // init functions and terminals based on constraints 59 foreach (I Operator op in opLibrary.Group.Operators) {61 foreach (IFunction fun in funLibrary.Group.Operators) { 60 62 int maxA, minA; 61 GetMinMaxArity( op, out minA, out maxA);63 GetMinMaxArity(fun, out minA, out maxA); 62 64 if (maxA == 0) { 63 terminals.Add( op);65 terminals.Add(fun); 64 66 } else { 65 functions.Add( op);66 } 67 } 68 69 all Operators.AddRange(functions);70 all Operators.AddRange(terminals);67 functions.Add(fun); 68 } 69 } 70 71 allFunctions.AddRange(functions); 72 allFunctions.AddRange(terminals); 71 73 } 72 74 73 75 #region random initialization 74 internal I Operator CreateRandomTree(ICollection<IOperator> allowedOperators, int maxTreeSize, int maxTreeHeight, bool balanceTrees) {75 76 int minTreeHeight = allowed Operators.Select(op => ((IntData)op.GetVariable(GPOperatorLibrary.MIN_TREE_HEIGHT).Value).Data).Min();76 internal IFunctionTree CreateRandomTree(ICollection<IFunction> allowedFunctions, int maxTreeSize, int maxTreeHeight, bool balanceTrees) { 77 78 int minTreeHeight = allowedFunctions.Select(f => ((IntData)f.GetVariable(GPOperatorLibrary.MIN_TREE_HEIGHT).Value).Data).Min(); 77 79 if (minTreeHeight > maxTreeHeight) 78 80 maxTreeHeight = minTreeHeight; 79 81 80 int minTreeSize = allowed Operators.Select(op => ((IntData)op.GetVariable(GPOperatorLibrary.MIN_TREE_SIZE).Value).Data).Min();82 int minTreeSize = allowedFunctions.Select(f => ((IntData)f.GetVariable(GPOperatorLibrary.MIN_TREE_SIZE).Value).Data).Min(); 81 83 if (minTreeSize > maxTreeSize) 82 84 maxTreeSize = minTreeSize; … … 85 87 int treeSize = random.Next(minTreeSize, maxTreeSize + 1); 86 88 87 IOperator[] possibleOperators = allowedOperators.Where(op => ((IntData)op.GetVariable(GPOperatorLibrary.MIN_TREE_HEIGHT).Value).Data <= treeHeight && 88 ((IntData)op.GetVariable(GPOperatorLibrary.MIN_TREE_SIZE).Value).Data <= treeSize).ToArray(); 89 IOperator selectedOperator = (IOperator)possibleOperators[random.Next(possibleOperators.Length)].Clone(); 90 91 IOperator rootOperator = CreateRandomTree(selectedOperator, treeSize, treeHeight, balanceTrees); 92 93 return rootOperator; 94 } 95 96 internal IOperator CreateRandomTree(int maxTreeSize, int maxTreeHeight, bool balanceTrees) { 89 IFunction[] possibleFunctions = allowedFunctions.Where(f => ((IntData)f.GetVariable(GPOperatorLibrary.MIN_TREE_HEIGHT).Value).Data <= treeHeight && 90 ((IntData)f.GetVariable(GPOperatorLibrary.MIN_TREE_SIZE).Value).Data <= treeSize).ToArray(); 91 IFunction selectedFunction = possibleFunctions[random.Next(possibleFunctions.Length)]; 92 93 return CreateRandomTree(selectedFunction, treeSize, treeHeight, balanceTrees); 94 } 95 96 internal IFunctionTree CreateRandomTree(int maxTreeSize, int maxTreeHeight, bool balanceTrees) { 97 97 if (balanceTrees) { 98 98 if (maxTreeHeight == 1 || maxTreeSize==1) { 99 I Operator selectedTerminal = (IOperator)terminals[random.Next(terminals.Count())].Clone();100 return selectedTerminal;99 IFunction selectedTerminal = terminals[random.Next(terminals.Count())]; 100 return new FunctionTree(selectedTerminal); 101 101 } else { 102 I Operator[] possibleFunctions = functions.Where(f => GetMinimalTreeHeight(f) <= maxTreeHeight &&102 IFunction[] possibleFunctions = functions.Where(f => GetMinimalTreeHeight(f) <= maxTreeHeight && 103 103 GetMinimalTreeSize(f) <= maxTreeSize).ToArray(); 104 IOperator selectedFunction = (IOperator)possibleFunctions[random.Next(possibleFunctions.Length)].Clone(); 105 MakeBalancedTree(selectedFunction, maxTreeSize - 1, maxTreeHeight - 1); 106 return selectedFunction; 104 IFunction selectedFunction = possibleFunctions[random.Next(possibleFunctions.Length)]; 105 FunctionTree root = new FunctionTree(selectedFunction); 106 MakeBalancedTree(root, maxTreeSize - 1, maxTreeHeight - 1); 107 return root; 107 108 } 108 109 109 110 } else { 110 IOperator[] possibleOperators = allOperators.Where(op => GetMinimalTreeHeight(op) <= maxTreeHeight && 111 GetMinimalTreeSize(op) <= maxTreeSize).ToArray(); 112 IOperator selectedOperator = (IOperator)possibleOperators[random.Next(possibleOperators.Length)].Clone(); 113 MakeUnbalancedTree(selectedOperator, maxTreeSize - 1, maxTreeHeight - 1); 114 return selectedOperator; 115 } 116 } 117 118 internal IOperator CreateRandomTree(IOperator root, int maxTreeSize, int maxTreeHeight, bool balanceTrees) { 111 IFunction[] possibleFunctions = allFunctions.Where(f => GetMinimalTreeHeight(f) <= maxTreeHeight && 112 GetMinimalTreeSize(f) <= maxTreeSize).ToArray(); 113 IFunction selectedFunction = possibleFunctions[random.Next(possibleFunctions.Length)]; 114 FunctionTree root = new FunctionTree(selectedFunction); 115 MakeUnbalancedTree(root, maxTreeSize - 1, maxTreeHeight - 1); 116 return root; 117 } 118 } 119 120 internal IFunctionTree CreateRandomTree(IFunction rootFunction, int maxTreeSize, int maxTreeHeight, bool balanceTrees) { 121 IFunctionTree root = new FunctionTree(rootFunction); 119 122 if (balanceTrees) { 120 123 MakeBalancedTree(root, maxTreeSize - 1, maxTreeHeight - 1); … … 130 133 131 134 132 private void MakeUnbalancedTree(I Operatorparent, int maxTreeSize, int maxTreeHeight) {135 private void MakeUnbalancedTree(IFunctionTree parent, int maxTreeSize, int maxTreeHeight) { 133 136 if (maxTreeHeight == 0 || maxTreeSize == 0) return; 134 137 int minArity; 135 138 int maxArity; 136 GetMinMaxArity(parent , out minArity, out maxArity);139 GetMinMaxArity(parent.Function, out minArity, out maxArity); 137 140 if (maxArity >= maxTreeSize) { 138 141 maxArity = maxTreeSize; … … 142 145 int maxSubTreeSize = maxTreeSize / actualArity; 143 146 for (int i = 0; i < actualArity; i++) { 144 IOperator[] possibleOperators = GetAllowedSubOperators(parent, i).Where(op => GetMinimalTreeHeight(op) <= maxTreeHeight && 145 GetMinimalTreeSize(op) <= maxSubTreeSize).ToArray(); 146 IOperator selectedOperator = (IOperator)possibleOperators[random.Next(possibleOperators.Length)].Clone(); 147 parent.AddSubOperator(selectedOperator, i); 148 MakeUnbalancedTree(selectedOperator, maxSubTreeSize - 1, maxTreeHeight - 1); 147 IFunction[] possibleFunctions = GetAllowedSubFunctions(parent.Function, i).Where(f => GetMinimalTreeHeight(f) <= maxTreeHeight && 148 GetMinimalTreeSize(f) <= maxSubTreeSize).ToArray(); 149 IFunction selectedFunction = possibleFunctions[random.Next(possibleFunctions.Length)]; 150 FunctionTree newSubTree = new FunctionTree(selectedFunction); 151 MakeUnbalancedTree(newSubTree, maxSubTreeSize - 1, maxTreeHeight - 1); 152 parent.InsertSubTree(i, newSubTree); 149 153 } 150 154 } … … 152 156 153 157 // NOTE: this method doesn't build fully balanced trees because we have constraints on the 154 // types of possible sub operators which can indirectly impose a limit for the depth of a given suboperator155 private void MakeBalancedTree(I Operatorparent, int maxTreeSize, int maxTreeHeight) {158 // types of possible sub-functions which can indirectly impose a limit for the depth of a given sub-tree 159 private void MakeBalancedTree(IFunctionTree parent, int maxTreeSize, int maxTreeHeight) { 156 160 if (maxTreeHeight == 0 || maxTreeSize == 0) return; // should never happen anyway 157 161 int minArity; 158 162 int maxArity; 159 GetMinMaxArity(parent , out minArity, out maxArity);163 GetMinMaxArity(parent.Function, out minArity, out maxArity); 160 164 if (maxArity >= maxTreeSize) { 161 165 maxArity = maxTreeSize; … … 166 170 for (int i = 0; i < actualArity; i++) { 167 171 if (maxTreeHeight == 1 || maxSubTreeSize == 1) { 168 IOperator[] possibleTerminals = GetAllowedSubOperators(parent, i).Where( 169 op => GetMinimalTreeHeight(op) <= maxTreeHeight && 170 GetMinimalTreeSize(op) <= maxSubTreeSize && 171 IsTerminal(op)).ToArray(); 172 IOperator selectedTerminal = (IOperator)possibleTerminals[random.Next(possibleTerminals.Length)].Clone(); 173 parent.AddSubOperator(selectedTerminal, i); 172 IFunction[] possibleTerminals = GetAllowedSubFunctions(parent.Function, i).Where( 173 f => GetMinimalTreeHeight(f) <= maxTreeHeight && 174 GetMinimalTreeSize(f) <= maxSubTreeSize && 175 IsTerminal(f)).ToArray(); 176 IFunction selectedTerminal = possibleTerminals[random.Next(possibleTerminals.Length)]; 177 IFunctionTree newTree = new FunctionTree(selectedTerminal); 178 parent.InsertSubTree(i, newTree); 174 179 } else { 175 IOperator[] possibleFunctions = GetAllowedSubOperators(parent, i).Where( 176 op => GetMinimalTreeHeight(op) <= maxTreeHeight && 177 GetMinimalTreeSize(op) <= maxSubTreeSize && 178 !IsTerminal(op)).ToArray(); 179 IOperator selectedFunction = (IOperator)possibleFunctions[random.Next(possibleFunctions.Length)].Clone(); 180 parent.AddSubOperator(selectedFunction, i); 181 MakeBalancedTree(selectedFunction, maxSubTreeSize - 1, maxTreeHeight - 1); 180 IFunction[] possibleFunctions = GetAllowedSubFunctions(parent.Function, i).Where( 181 f => GetMinimalTreeHeight(f) <= maxTreeHeight && 182 GetMinimalTreeSize(f) <= maxSubTreeSize && 183 !IsTerminal(f)).ToArray(); 184 IFunction selectedFunction = possibleFunctions[random.Next(possibleFunctions.Length)]; 185 FunctionTree newTree = new FunctionTree(selectedFunction); 186 parent.InsertSubTree(i, newTree); 187 MakeBalancedTree(newTree, maxSubTreeSize - 1, maxTreeHeight - 1); 182 188 } 183 189 } … … 185 191 } 186 192 187 internal CompositeOperation CreateInitializationOperation(ICollection<I Operator> operators, IScope scope) {193 internal CompositeOperation CreateInitializationOperation(ICollection<IFunctionTree> trees, IScope scope) { 188 194 // needed for the parameter shaking operation 189 195 CompositeOperation initializationOperation = new CompositeOperation(); 190 196 Scope tempScope = new Scope("Temp. initialization scope"); 191 197 192 var parametric Operators = operators.Where(o => o.GetVariable(GPOperatorLibrary.INITIALIZATION) != null);193 194 foreach (I Operator op in parametricOperators) {198 var parametricTrees = trees.Where(t => t.Function.GetVariable(GPOperatorLibrary.INITIALIZATION) != null); 199 200 foreach (IFunctionTree tree in parametricTrees) { 195 201 // enqueue an initialization operation for each operator with local variables 196 IOperator initialization = (IOperator) op.GetVariable(GPOperatorLibrary.INITIALIZATION).Value;202 IOperator initialization = (IOperator)tree.Function.GetVariable(GPOperatorLibrary.INITIALIZATION).Value; 197 203 Scope initScope = new Scope(); 198 204 199 205 // copy the local variables into a temporary scope used for initialization 200 foreach (VariableInfo info in op.VariableInfos) { 201 if (info.Local) { 202 initScope.AddVariable(op.GetVariable(info.FormalName)); 203 } 206 foreach (IVariable variable in tree.LocalVariables) { 207 initScope.AddVariable(variable); 204 208 } 205 209 … … 223 227 224 228 #region tree information gathering 225 internal int GetTreeSize(I Operatortree) {226 return 1 + tree.Sub Operators.Sum(f => GetTreeSize(f));227 } 228 229 internal int GetTreeHeight(I Operatortree) {230 if (tree.Sub Operators.Count == 0) return 1;231 return 1 + tree.Sub Operators.Max(f => GetTreeHeight(f));232 } 233 234 internal I Operator GetRandomParentNode(IOperatortree) {235 List<I Operator> parentNodes = new List<IOperator>();229 internal int GetTreeSize(IFunctionTree tree) { 230 return 1 + tree.SubTrees.Sum(f => GetTreeSize(f)); 231 } 232 233 internal int GetTreeHeight(IFunctionTree tree) { 234 if (tree.SubTrees.Count == 0) return 1; 235 return 1 + tree.SubTrees.Max(f => GetTreeHeight(f)); 236 } 237 238 internal IFunctionTree GetRandomParentNode(IFunctionTree tree) { 239 List<IFunctionTree> parentNodes = new List<IFunctionTree>(); 236 240 237 241 // add null for the parent of the root node 238 242 parentNodes.Add(null); 239 243 240 TreeForEach(tree, delegate(I Operator op) {241 if ( op.SubOperators.Count > 0) {242 parentNodes.Add( op);244 TreeForEach(tree, delegate(IFunctionTree possibleParentNode) { 245 if (possibleParentNode.SubTrees.Count > 0) { 246 parentNodes.Add(possibleParentNode); 243 247 } 244 248 }); … … 247 251 } 248 252 249 internal IList<I Operator> GetAllowedSubOperators(IOperator op, int index) {250 if ( op== null) {251 return all Operators;253 internal IList<IFunction> GetAllowedSubFunctions(IFunction f, int index) { 254 if (f == null) { 255 return allFunctions; 252 256 } else { 253 254 SubOperatorsConstraintAnalyser analyser = new SubOperatorsConstraintAnalyser(); 255 analyser.AllPossibleOperators = allOperators; 256 257 return analyser.GetAllowedOperators(op, index); 258 } 259 } 260 internal void GetMinMaxArity(IOperator root, out int minArity, out int maxArity) { 261 foreach (IConstraint constraint in root.Constraints) { 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; 263 } 264 } 265 internal void GetMinMaxArity(IFunction f, out int minArity, out int maxArity) { 266 foreach (IConstraint constraint in f.Constraints) { 262 267 NumberOfSubOperatorsConstraint theConstraint = constraint as NumberOfSubOperatorsConstraint; 263 268 if (theConstraint != null) { … … 271 276 maxArity = 2; 272 277 } 273 internal bool IsTerminal(I Operatorf) {278 internal bool IsTerminal(IFunction f) { 274 279 int minArity; 275 280 int maxArity; … … 278 283 } 279 284 280 internal IList<I Operator> GetAllowedParents(IOperatorchild, int childIndex) {281 List<I Operator> parents = new List<IOperator>();282 foreach (I Operatorfunction in functions) {283 I List<IOperator> allowedSubOperators = GetAllowedSubOperators(function, childIndex);284 if (allowedSub Operators.Contains(child, new OperatorEqualityComparer())) {285 internal IList<IFunction> GetAllowedParents(IFunction child, int childIndex) { 286 List<IFunction> parents = new List<IFunction>(); 287 foreach (IFunction function in functions) { 288 ICollection<IFunction> allowedSubFunctions = GetAllowedSubFunctions(function, childIndex); 289 if (allowedSubFunctions.Contains(child)) { 285 290 parents.Add(function); 286 291 } … … 289 294 } 290 295 291 internal ICollection<I Operator> GetAllOperators(IOperatorroot) {292 List<I Operator> allOps = new List<IOperator>();293 TreeForEach(root, t => { all Ops.Add(t); });294 return all Ops;296 internal ICollection<IFunctionTree> GetAllSubTrees(IFunctionTree root) { 297 List<IFunctionTree> allTrees = new List<IFunctionTree>(); 298 TreeForEach(root, t => { allTrees.Add(t); }); 299 return allTrees; 295 300 } 296 301 297 302 /// <summary> 298 /// returns the height level of opin the tree299 /// if the op== tree => 1300 /// if op is in the suboperators of tree => 2303 /// returns the height level of branch in the tree 304 /// if the branch == tree => 1 305 /// if branch is in the sub-trees of tree => 2 301 306 /// ... 302 /// if opis not found => -1307 /// if branch is not found => -1 303 308 /// </summary> 304 /// <param name="tree"> operatortree to process</param>305 /// <param name=" op">operaterthat is searched in the tree</param>309 /// <param name="tree">root of the function tree to process</param> 310 /// <param name="branch">branch that is searched in the tree</param> 306 311 /// <returns></returns> 307 internal int GetNodeLevel(IOperator tree, IOperator op) { 308 return GetNodeLevelHelper(tree, op, 1); 309 } 310 311 private int GetNodeLevelHelper(IOperator tree, IOperator op, int level) { 312 if (op == tree) return level; 313 314 foreach (IOperator subTree in tree.SubOperators) { 315 int result = GetNodeLevelHelper(subTree, op, level + 1); 312 internal int GetBranchLevel(IFunctionTree tree, IFunctionTree branch) { 313 return GetBranchLevelHelper(tree, branch, 1); 314 } 315 316 // 'tail-recursive' helper 317 private int GetBranchLevelHelper(IFunctionTree tree, IFunctionTree branch, int level) { 318 if (branch == tree) return level; 319 320 foreach (IFunctionTree subTree in tree.SubTrees) { 321 int result = GetBranchLevelHelper(subTree, branch, level + 1); 316 322 if (result != -1) return result; 317 323 } … … 320 326 } 321 327 322 internal bool IsValidTree(IOperator tree) { 323 if (!tree.IsValid()) 324 return false; 325 foreach (IOperator subTree in tree.SubOperators) { 326 if (!subTree.IsValid()) 327 return false; 328 } 329 328 internal bool IsValidTree(IFunctionTree tree) { 329 foreach(IConstraint constraint in tree.Function.Constraints) { 330 if(constraint is NumberOfSubOperatorsConstraint) { 331 int max = ((NumberOfSubOperatorsConstraint)constraint).MaxOperators.Data; 332 int min = ((NumberOfSubOperatorsConstraint)constraint).MinOperators.Data; 333 if(tree.SubTrees.Count < min || tree.SubTrees.Count > max) 334 return false; 335 } 336 } 337 foreach(IFunctionTree subTree in tree.SubTrees) { 338 if(!IsValidTree(subTree)) return false; 339 } 330 340 return true; 331 341 } 332 342 333 // returns a random nodefrom the specified level in the tree334 internal I Operator GetRandomNode(IOperatortree, int level) {343 // returns a random branch from the specified level in the tree 344 internal IFunctionTree GetRandomBranch(IFunctionTree tree, int level) { 335 345 if (level == 0) return tree; 336 List<I Operator> nodes = GetOperatorsAtLevel(tree, level);337 return nodes[random.Next(nodes.Count)];346 List<IFunctionTree> branches = GetBranchesAtLevel(tree, level); 347 return branches[random.Next(branches.Count)]; 338 348 } 339 349 #endregion … … 349 359 } 350 360 351 private void TreeForEach(I Operator tree, Action<IOperator> action) {361 private void TreeForEach(IFunctionTree tree, Action<IFunctionTree> action) { 352 362 action(tree); 353 foreach (IOperator child in tree.SubOperators) { 354 TreeForEach(child, action); 355 } 356 } 357 358 private List<IOperator> GetOperatorsAtLevel(IOperator tree, int level) { 359 if (level == 1) return new List<IOperator>(tree.SubOperators); 360 361 List<IOperator> result = new List<IOperator>(); 362 foreach (IOperator subOperator in tree.SubOperators) { 363 result.AddRange(GetOperatorsAtLevel(subOperator, level - 1)); 363 foreach (IFunctionTree subTree in tree.SubTrees) { 364 TreeForEach(subTree, action); 365 } 366 } 367 368 private List<IFunctionTree> GetBranchesAtLevel(IFunctionTree tree, int level) { 369 if (level == 1) return new List<IFunctionTree>(tree.SubTrees); 370 371 List<IFunctionTree> branches = new List<IFunctionTree>(); 372 foreach (IFunctionTree subTree in tree.SubTrees) { 373 branches.AddRange(GetBranchesAtLevel(subTree, level - 1)); 374 } 375 return branches; 376 } 377 378 379 #endregion 380 381 internal ICollection<IFunction> GetPossibleParents(List<IFunction> list) { 382 List<IFunction> result = new List<IFunction>(); 383 foreach (IFunction f in functions) { 384 if (IsPossibleParent(f, list)) { 385 result.Add(f); 386 } 364 387 } 365 388 return result; 366 389 } 367 390 368 369 #endregion 370 371 internal class OperatorEqualityComparer : IEqualityComparer<IOperator> { 372 #region IEqualityComparer<IOperator> Members 373 374 public bool Equals(IOperator x, IOperator y) { 375 return ((StringData)x.GetVariable(GPOperatorLibrary.TYPE_ID).Value).Data == 376 ((StringData)y.GetVariable(GPOperatorLibrary.TYPE_ID).Value).Data; 377 } 378 379 public int GetHashCode(IOperator obj) { 380 return ((StringData)obj.GetVariable(GPOperatorLibrary.TYPE_ID).Value).Data.GetHashCode(); 381 } 382 383 #endregion 384 } 385 386 internal ICollection<IOperator> GetPossibleParents(List<IOperator> list) { 387 List<IOperator> result = new List<IOperator>(); 388 foreach (IOperator op in functions) { 389 if (IsPossibleParent(op, list)) { 390 result.Add(op); 391 } 392 } 393 return result; 394 } 395 396 private bool IsPossibleParent(IOperator op, List<IOperator> children) { 391 private bool IsPossibleParent(IFunction f, List<IFunction> children) { 397 392 int minArity; 398 393 int maxArity; 399 GetMinMaxArity( op, out minArity, out maxArity);394 GetMinMaxArity(f, out minArity, out maxArity); 400 395 401 396 // note: we can't assume that the operators in the children list have different types! … … 409 404 410 405 SubOperatorsConstraintAnalyser analyzer = new SubOperatorsConstraintAnalyser(); 411 analyzer.AllPossibleOperators = children ;412 413 List<HashSet<I Operator>> slotSets = new List<HashSet<IOperator>>();414 415 // we iterate through all slots for sub- operators and calculate the set of416 // allowed sub-operators for this slot.406 analyzer.AllPossibleOperators = children.Cast<IOperator>().ToArray<IOperator>(); 407 408 List<HashSet<IFunction>> slotSets = new List<HashSet<IFunction>>(); 409 410 // we iterate through all slots for sub-trees and calculate the set of 411 // allowed functions for this slot. 417 412 // we only count those slots that can hold at least one of the children that we should combine 418 413 for (int slot = 0; slot < nSlots; slot++) { 419 HashSet<I Operator> operatorSet = new HashSet<IOperator>(analyzer.GetAllowedOperators(op, slot));420 if ( operatorSet.Count() > 0) {421 slotSets.Add( operatorSet);414 HashSet<IFunction> functionSet = new HashSet<IFunction>(analyzer.GetAllowedOperators(f, slot).Cast<IFunction>()); 415 if (functionSet.Count() > 0) { 416 slotSets.Add(functionSet); 422 417 } 423 418 } … … 426 421 // hold one of our children. 427 422 // if the number of slots is smaller than the number of children we can be sure that 428 // we can never combine all children as sub- operators of the operator and thus the operator423 // we can never combine all children as sub-trees of the function and thus the function 429 424 // can't be a parent. 430 425 if (slotSets.Count() < children.Count()) { … … 433 428 434 429 // finally we sort the sets by size and beginning from the first set select one 435 // operator for the slot and thus remove it as possible sub-operatorfrom the remaining sets.436 // when we can successfully assign all available children to a slot the operatoris a valid parent437 // when only a subset of all children can be assigned to slots the operatoris no valid parent430 // function for the slot and thus remove it as possible sub-tree from the remaining sets. 431 // when we can successfully assign all available children to a slot the function is a valid parent 432 // when only a subset of all children can be assigned to slots the function is no valid parent 438 433 slotSets.Sort((p, q) => p.Count() - q.Count()); 439 434 … … 441 436 for (int i = 0; i < slotSets.Count() - 1; i++) { 442 437 if (slotSets[i].Count > 0) { 443 I Operatorselected = slotSets[i].ElementAt(0);438 IFunction selected = slotSets[i].ElementAt(0); 444 439 assignments++; 445 440 for (int j = i + 1; j < slotSets.Count(); j++) {
Note: See TracChangeset
for help on using the changeset viewer.