Changeset 163 for trunk/sources/HeuristicLab.StructureIdentification/Manipulation/ChangeNodeTypeManipulation.cs
- Timestamp:
- 04/22/08 20:28:26 (16 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/sources/HeuristicLab.StructureIdentification/Manipulation/ChangeNodeTypeManipulation.cs
r162 r163 48 48 AddVariableInfo(new VariableInfo("MaxTreeHeight", "The maximal allowed height of the tree", typeof(IntData), VariableKind.In)); 49 49 AddVariableInfo(new VariableInfo("MaxTreeSize", "The maximal allowed size (number of nodes) of the tree", typeof(IntData), VariableKind.In)); 50 AddVariableInfo(new VariableInfo("BalancedTreesRate", "Determines how many trees should be balanced", typeof(DoubleData), VariableKind.In));51 50 AddVariableInfo(new VariableInfo("FunctionTree", "The tree to mutate", typeof(IFunctionTree), VariableKind.In | VariableKind.Out)); 52 51 AddVariableInfo(new VariableInfo("TreeSize", "The size (number of nodes) of the tree", typeof(IntData), VariableKind.In | VariableKind.Out)); … … 59 58 MersenneTwister random = GetVariableValue<MersenneTwister>("Random", scope, true); 60 59 GPOperatorLibrary library = GetVariableValue<GPOperatorLibrary>("OperatorLibrary", scope, true); 61 double balancedTreesRate = GetVariableValue<DoubleData>("BalancedTreesRate", scope, true).Data;62 60 IntData treeSize = GetVariableValue<IntData>("TreeSize", scope, false); 63 61 IntData treeHeight = GetVariableValue<IntData>("TreeHeight", scope, false); 64 62 int maxTreeSize = GetVariableValue<IntData>("MaxTreeSize", scope, true).Data; 65 63 int maxTreeHeight = GetVariableValue<IntData>("MaxTreeHeight", scope, true).Data; 66 67 64 TreeGardener gardener = new TreeGardener(random, library); 68 65 IFunctionTree parent = gardener.GetRandomParentNode(root); 69 70 66 IFunctionTree selectedChild; 71 67 int selectedChildIndex; … … 80 76 if (selectedChild.SubTrees.Count == 0) { 81 77 IFunctionTree newTerminal = ChangeTerminalType(parent, selectedChild, selectedChildIndex, gardener, random); 82 83 78 if (parent == null) { 84 79 // no parent means the new child is the initial operator … … 91 86 } 92 87 if(!gardener.IsValidTree(root)) throw new InvalidProgramException(); 93 94 88 // size and height stays the same when changing a terminal so no need to update the variables 95 89 // schedule an operation to initialize the new terminal … … 97 91 } else { 98 92 List<IFunctionTree> uninitializedBranches; 99 IFunctionTree newFunction = ChangeFunctionType(parent, selectedChild, selectedChildIndex, gardener, random, balancedTreesRate, out uninitializedBranches); 100 93 IFunctionTree newFunction = ChangeFunctionType(parent, selectedChild, selectedChildIndex, gardener, random, out uninitializedBranches); 101 94 if (parent == null) { 102 95 // no parent means the new function is the initial operator … … 110 103 parent.InsertSubTree(selectedChildIndex, newFunction); 111 104 } 112 113 105 // recalculate size and height 114 106 treeSize.Data = gardener.GetTreeSize(root); 115 107 treeHeight.Data = gardener.GetTreeHeight(root); 116 117 108 // check if whole tree is ok 118 109 // check if the size of the new tree is still in the allowed bounds … … 122 113 throw new InvalidProgramException(); 123 114 } 124 125 115 // return a composite operation that initializes all created sub-trees 126 116 return gardener.CreateInitializationOperation(uninitializedBranches, scope); … … 139 129 } 140 130 } 141 142 131 // selecting from the terminals should always work since the current child was also a terminal 143 132 // so in the worst case we will just create a new terminal of the same type again. … … 146 135 147 136 private IFunctionTree ChangeFunctionType(IFunctionTree parent, IFunctionTree child, int childIndex, TreeGardener gardener, MersenneTwister random, 148 double balancedTreesRate,out List<IFunctionTree> uninitializedBranches) {137 out List<IFunctionTree> uninitializedBranches) { 149 138 // since there are subtrees, we have to check which 150 // and how many of the existing subtrees we can reuse 151 152 // let's choose the function we want to use instead of the old child. For this we have to determine the 139 // and how many of the existing subtrees we can reuse. 140 // first let's choose the function we want to use instead of the old child. For this we have to determine the 153 141 // pool of allowed functions based on constraints of the parent if there is one. 154 142 IList<IFunction> allowedFunctions = gardener.GetAllowedSubFunctions(parent!=null?parent.Function:null, childIndex); 155 156 143 // try to make a tree with the same arity as the old child. 157 144 int actualArity = child.SubTrees.Count; … … 166 153 return minArity <= actualArity; 167 154 }).ToList(); 168 169 155 // create a new tree-node for a randomly selected function 170 156 IFunctionTree newTree = new FunctionTree(allowedFunctions[random.Next(allowedFunctions.Count)]); 171 172 157 gardener.GetMinMaxArity(newTree.Function, out minArity, out maxArity); 173 158 // if the old child had too many sub-trees then the new child should keep as many sub-trees as possible 174 159 if (actualArity > maxArity) 175 160 actualArity = maxArity; 176 177 161 // get the allowed size and height for new sub-trees 178 162 // use the size of the smallest subtree as the maximal allowed size for new subtrees to … … 180 164 int maxSubTreeSize = child.SubTrees.Select(subTree => gardener.GetTreeSize(subTree)).Min(); 181 165 int maxSubTreeHeight = gardener.GetTreeHeight(child) - 1; 182 183 166 // create a list that holds old sub-trees that we can reuse in the new tree 184 167 List<IFunctionTree> availableSubTrees = new List<IFunctionTree>(child.SubTrees); 185 168 List<IFunctionTree> freshSubTrees = new List<IFunctionTree>() { newTree }; 186 187 169 // randomly select the sub-trees that we keep 188 170 for (int i = 0; i < actualArity; i++) { … … 193 175 ICollection<IFunction> allowedSubFunctions = gardener.GetAllowedSubFunctions(newTree.Function, i); 194 176 var matchingSubTrees = availableSubTrees.Where(subTree => allowedSubFunctions.Contains(subTree.Function)); 195 196 177 if (matchingSubTrees.Count() > 0) { 197 178 IFunctionTree selectedSubTree = matchingSubTrees.ElementAt(random.Next(matchingSubTrees.Count())); … … 201 182 } else { 202 183 // no existing matching tree found => create a new one 203 IFunctionTree freshTree; 204 if(random.NextDouble() <= balancedTreesRate) { 205 freshTree = gardener.CreateRandomTree(allowedSubFunctions, maxSubTreeSize, maxSubTreeHeight, true); 206 } else { 207 freshTree = gardener.CreateRandomTree(allowedSubFunctions, maxSubTreeSize, maxSubTreeHeight, false); 208 } 184 IFunctionTree freshTree = gardener.CreateRandomTree(allowedSubFunctions, maxSubTreeSize, maxSubTreeHeight); 209 185 freshSubTrees.AddRange(gardener.GetAllSubTrees(freshTree)); 210 211 186 newTree.InsertSubTree(i, freshTree); 212 187 }
Note: See TracChangeset
for help on using the changeset viewer.