Changeset 167
- Timestamp:
- 04/22/08 23:52:28 (17 years ago)
- Location:
- trunk/sources/HeuristicLab.StructureIdentification
- Files:
-
- 2 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/sources/HeuristicLab.StructureIdentification/Manipulation/ChangeNodeTypeManipulation.cs
r163 r167 66 66 IFunctionTree selectedChild; 67 67 int selectedChildIndex; 68 if 68 if(parent == null) { 69 69 selectedChildIndex = 0; 70 70 selectedChild = root; … … 74 74 } 75 75 76 if 76 if(selectedChild.SubTrees.Count == 0) { 77 77 IFunctionTree newTerminal = ChangeTerminalType(parent, selectedChild, selectedChildIndex, gardener, random); 78 if 78 if(parent == null) { 79 79 // no parent means the new child is the initial operator 80 80 // and we have to update the value in the variable … … 91 91 } else { 92 92 List<IFunctionTree> uninitializedBranches; 93 IFunctionTree newFunction = ChangeFunctionType(parent, selectedChild, selectedChildIndex, gardener, random, out uninitializedBranches); 94 if (parent == null) { 93 IFunctionTree newFunctionTree = ChangeFunctionType(parent, selectedChild, selectedChildIndex, gardener, random, out uninitializedBranches); 94 // in rare cases the function creates a tree that breaks the size limits 95 // calculate the height and size difference and 96 // check if the size of the new tree is still in the allowed bounds 97 int oldChildSize = gardener.GetTreeSize(selectedChild); 98 int oldChildHeight = gardener.GetTreeSize(selectedChild); 99 int newChildSize = gardener.GetTreeSize(newFunctionTree); 100 int newChildHeight = gardener.GetTreeHeight(newFunctionTree); 101 if((treeHeight.Data - oldChildHeight) + newChildHeight > maxTreeHeight || 102 (treeSize.Data - oldChildSize) + newChildSize > maxTreeSize) { 103 // if size-constraints are violated don't change anything 104 return null; 105 } 106 if(parent == null) { 95 107 // no parent means the new function is the initial operator 96 108 // and we have to update the value in the variable 97 scope.GetVariable(scope.TranslateName("FunctionTree")).Value = newFunction ;98 root = newFunction ;109 scope.GetVariable(scope.TranslateName("FunctionTree")).Value = newFunctionTree; 110 root = newFunctionTree; 99 111 } else { 100 112 // remove the old child 101 113 parent.RemoveSubTree(selectedChildIndex); 102 114 // add the new child as sub-tree of parent 103 parent.InsertSubTree(selectedChildIndex, newFunction );115 parent.InsertSubTree(selectedChildIndex, newFunctionTree); 104 116 } 105 // recalculate size and height106 treeSize.Data = gardener.GetTreeSize(root);107 treeHeight.Data = gardener.GetTreeHeight(root); 117 // update size and height 118 treeSize.Data = (treeSize.Data - oldChildSize) + newChildSize; 119 treeHeight.Data = gardener.GetTreeHeight(root); // must recalculate height because we can't know wether the manipulated branch was the deepest branch 108 120 // check if whole tree is ok 109 // check if the size of the new tree is still in the allowed bounds 110 if (!gardener.IsValidTree(root) || 111 treeHeight.Data > maxTreeHeight || 112 treeSize.Data > maxTreeSize) { 121 if(!gardener.IsValidTree(root)) 113 122 throw new InvalidProgramException(); 114 }115 123 // return a composite operation that initializes all created sub-trees 116 124 return gardener.CreateInitializationOperation(uninitializedBranches, scope); 117 125 } 118 126 } 127 119 128 120 129 private IFunctionTree ChangeTerminalType(IFunctionTree parent, IFunctionTree child, int childIndex, TreeGardener gardener, MersenneTwister random) { … … 146 155 int minArity; 147 156 int maxArity; 148 // only allow functions where we can keep all existing sub-trees149 // we don't want to create new sub-trees here150 // this restriction can be removed if we add code that creates sub-trees where necessary (gkronber 22.04.08)151 allowedFunctions = allowedFunctions.Where(f => {152 gardener.GetMinMaxArity(f, out minArity, out maxArity);153 return minArity <= actualArity;154 }).ToList();155 157 // create a new tree-node for a randomly selected function 156 158 IFunctionTree newTree = new FunctionTree(allowedFunctions[random.Next(allowedFunctions.Count)]); … … 159 161 if (actualArity > maxArity) 160 162 actualArity = maxArity; 161 // get the allowed size and height for new sub-trees 162 // use the size of the smallest subtree as the maximal allowed size for new subtrees to 163 // prevent that we ever create trees over the MaxTreeSize limit 164 int maxSubTreeSize = child.SubTrees.Select(subTree => gardener.GetTreeSize(subTree)).Min(); 165 int maxSubTreeHeight = gardener.GetTreeHeight(child) - 1; 163 if(actualArity < minArity) 164 actualArity = minArity; 166 165 // create a list that holds old sub-trees that we can reuse in the new tree 167 166 List<IFunctionTree> availableSubTrees = new List<IFunctionTree>(child.SubTrees); … … 181 180 availableSubTrees.Remove(selectedSubTree); // the branch shouldn't be available for the following slots 182 181 } else { 183 // no existing matching tree found => create a new one184 IFunctionTree freshTree = gardener.CreateRandomTree(allowedSubFunctions, maxSubTreeSize, maxSubTreeHeight);182 // no existing matching tree found => create a new tree of minimal size 183 IFunctionTree freshTree = gardener.CreateRandomTree(allowedSubFunctions, 1, 1); 185 184 freshSubTrees.AddRange(gardener.GetAllSubTrees(freshTree)); 186 185 newTree.InsertSubTree(i, freshTree); -
trunk/sources/HeuristicLab.StructureIdentification/TreeGardener.cs
r163 r167 53 53 this.random = random; 54 54 this.funLibrary = funLibrary; 55 56 55 this.allFunctions = new List<IFunction>(); 57 56 terminals = new List<IFunction>(); 58 57 functions = new List<IFunction>(); 59 60 58 // init functions and terminals based on constraints 61 59 foreach (IFunction fun in funLibrary.Group.Operators) { … … 68 66 } 69 67 } 70 71 68 allFunctions.AddRange(functions); 72 69 allFunctions.AddRange(terminals);
Note: See TracChangeset
for help on using the changeset viewer.