Changeset 163
- Timestamp:
- 04/22/08 20:28:26 (17 years ago)
- Location:
- trunk/sources/HeuristicLab.StructureIdentification
- Files:
-
- 5 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 } -
trunk/sources/HeuristicLab.StructureIdentification/Manipulation/CutOutNodeManipulation.cs
r155 r163 53 53 AddVariableInfo(new VariableInfo("MaxTreeHeight", "The maximal allowed height of the tree", typeof(IntData), VariableKind.In)); 54 54 AddVariableInfo(new VariableInfo("MaxTreeSize", "The maximal allowed size (number of nodes) of the tree", typeof(IntData), VariableKind.In)); 55 AddVariableInfo(new VariableInfo("BalancedTreesRate", "Determines how many trees should be balanced", typeof(DoubleData), VariableKind.In));56 55 AddVariableInfo(new VariableInfo("FunctionTree", "The tree to mutate", typeof(IFunctionTree), VariableKind.In | VariableKind.Out)); 57 56 AddVariableInfo(new VariableInfo("TreeSize", "The size (number of nodes) of the tree", typeof(IntData), VariableKind.In | VariableKind.Out)); … … 66 65 int maxTreeHeight = GetVariableValue<IntData>("MaxTreeHeight", scope, true).Data; 67 66 int maxTreeSize = GetVariableValue<IntData>("MaxTreeSize", scope, true).Data; 68 double balancedTreesRate = GetVariableValue<DoubleData>("BalancedTreesRate", scope, true).Data;69 70 67 TreeGardener gardener = new TreeGardener(random, library); 71 68 IFunctionTree parent = gardener.GetRandomParentNode(root); … … 76 73 if (root.SubTrees.Count > 0) { 77 74 root = root.SubTrees[random.Next(root.SubTrees.Count)]; 78 79 75 GetVariableValue<IntData>("TreeSize", scope, true).Data = gardener.GetTreeSize(root); 80 76 GetVariableValue<IntData>("TreeHeight", scope, true).Data = gardener.GetTreeHeight(root); 81 82 77 // update the variable 83 78 scope.GetVariable(scope.TranslateName("FunctionTree")).Value = root; … … 90 85 // we want to cut the root node and there are no sub-trees => create a new random terminal 91 86 IFunctionTree newTree; 92 newTree = gardener.CreateRandomTree(gardener.Terminals, 1, 1 , false);87 newTree = gardener.CreateRandomTree(gardener.Terminals, 1, 1); 93 88 GetVariableValue<IntData>("TreeSize", scope, true).Data = gardener.GetTreeSize(newTree); 94 89 GetVariableValue<IntData>("TreeHeight", scope, true).Data = gardener.GetTreeHeight(newTree); … … 102 97 } 103 98 } 104 105 99 // select a child to cut away 106 100 int childIndex = random.Next(parent.SubTrees.Count); 107 101 IFunctionTree child = parent.SubTrees[childIndex]; 108 109 102 // match the sub-trees of the child with the allowed sub-trees of the parent 110 103 ICollection<IFunction> allowedFunctions = gardener.GetAllowedSubFunctions(parent.Function, childIndex); 111 104 IFunctionTree[] possibleChilds = child.SubTrees.Where(t => allowedFunctions.Contains(t.Function)).ToArray(); 112 113 105 if (possibleChilds.Length > 0) { 114 106 // replace child with a random child of that child … … 116 108 parent.RemoveSubTree(childIndex); 117 109 parent.InsertSubTree(childIndex, selectedChild); 118 119 110 if (!gardener.IsValidTree(root)) { 120 111 throw new InvalidProgramException(); 121 112 } 122 123 113 // update the size and height of our tree 124 114 GetVariableValue<IntData>("TreeSize", scope, true).Data = gardener.GetTreeSize(root); … … 130 120 // determine the level of the parent 131 121 int parentLevel = gardener.GetBranchLevel(root, parent); 132 133 122 // first remove the old child (first step essential!) 134 123 parent.RemoveSubTree(childIndex); 135 124 // then determine the number of nodes left over after the child has been removed! 136 125 int remainingNodes = gardener.GetTreeSize(root); 137 138 126 allowedFunctions = gardener.GetAllowedSubFunctions(parent.Function, childIndex); 139 IFunctionTree newFunctionTree = gardener.CreateRandomTree(allowedFunctions, maxTreeSize - remainingNodes, maxTreeHeight - parentLevel, false); 140 127 IFunctionTree newFunctionTree = gardener.CreateRandomTree(allowedFunctions, maxTreeSize - remainingNodes, maxTreeHeight - parentLevel); 141 128 parent.InsertSubTree(childIndex, newFunctionTree); 142 143 129 GetVariableValue<IntData>("TreeSize", scope, true).Data = gardener.GetTreeSize(root); 144 130 GetVariableValue<IntData>("TreeHeight", scope, true).Data = gardener.GetTreeHeight(root); 145 146 131 if (!gardener.IsValidTree(root)) { 147 132 throw new InvalidProgramException(); 148 133 } 149 150 134 // schedule an initialization operation for the new function-tree 151 135 return gardener.CreateInitializationOperation(gardener.GetAllSubTrees(newFunctionTree), scope); -
trunk/sources/HeuristicLab.StructureIdentification/Manipulation/DeleteSubTreeManipulation.cs
r155 r163 60 60 if(parent == null) { 61 61 IFunctionTree newTree = gardener.CreateRandomTree(1, 1, false); 62 63 62 // check if the tree is ok 64 63 if(!gardener.IsValidTree(newTree)) { 65 64 throw new InvalidOperationException(); 66 65 } 67 68 66 // update sizes to match the new tree 69 67 GetVariableValue<IntData>("TreeSize", scope, true).Data = gardener.GetTreeSize(newTree); … … 91 89 throw new InvalidOperationException(); 92 90 } 93 94 91 GetVariableValue<IntData>("TreeSize", scope, true).Data = gardener.GetTreeSize(root); 95 92 GetVariableValue<IntData>("TreeHeight", scope, true).Data = gardener.GetTreeHeight(root); … … 99 96 // replace with a minimal random seedling 100 97 parent.RemoveSubTree(childIndex); 101 102 98 ICollection<IFunction> allowedFunctions = gardener.GetAllowedSubFunctions(parent.Function, childIndex); 103 IFunctionTree newFunctionTree = gardener.CreateRandomTree(allowedFunctions, 1, 1, true); 104 99 IFunctionTree newFunctionTree = gardener.CreateRandomTree(allowedFunctions, 1, 1); 105 100 parent.InsertSubTree(childIndex, newFunctionTree); 106 107 101 if(!gardener.IsValidTree(root)) { 108 102 throw new InvalidProgramException(); 109 103 } 110 111 104 GetVariableValue<IntData>("TreeSize", scope, true).Data = gardener.GetTreeSize(root); 112 105 GetVariableValue<IntData>("TreeHeight", scope, true).Data = gardener.GetTreeHeight(root); -
trunk/sources/HeuristicLab.StructureIdentification/Manipulation/SubstituteSubTreeManipulation.cs
r155 r163 42 42 AddVariableInfo(new VariableInfo("MaxTreeHeight", "The maximal allowed height of the tree", typeof(IntData), VariableKind.In)); 43 43 AddVariableInfo(new VariableInfo("MaxTreeSize", "The maximal allowed size (number of nodes) of the tree", typeof(IntData), VariableKind.In)); 44 AddVariableInfo(new VariableInfo("BalancedTreesRate", "Determines how many trees should be balanced", typeof(DoubleData), VariableKind.In));45 44 AddVariableInfo(new VariableInfo("FunctionTree", "The tree to manipulate", typeof(IFunctionTree), VariableKind.In | VariableKind.Out)); 46 45 AddVariableInfo(new VariableInfo("TreeSize", "The size (number of nodes) of the tree", typeof(IntData), VariableKind.In | VariableKind.Out)); … … 54 53 int maxTreeHeight = GetVariableValue<IntData>("MaxTreeHeight", scope, true).Data; 55 54 int maxTreeSize = GetVariableValue<IntData>("MaxTreeSize", scope, true).Data; 56 double balancedTreesRate = GetVariableValue<DoubleData>("BalancedTreesRate", scope, true).Data;57 55 int treeSize = GetVariableValue<IntData>("TreeSize", scope, true).Data; 58 56 int treeHeight = GetVariableValue<IntData>("TreeHeight", scope, true).Data; 59 60 57 TreeGardener gardener = new TreeGardener(random, library); 61 62 58 IFunctionTree parent = gardener.GetRandomParentNode(root); 63 59 if(parent == null) { 64 60 // parent == null means we should subsitute the whole tree 65 61 // => create a new random tree 66 67 // create a new random function tree 68 IFunctionTree newTree; 69 if(random.NextDouble() <= balancedTreesRate) { 70 newTree = gardener.CreateRandomTree(gardener.AllFunctions, maxTreeSize, maxTreeHeight, true); 71 } else { 72 newTree = gardener.CreateRandomTree(gardener.AllFunctions, maxTreeSize, maxTreeHeight, false); 73 } 74 62 IFunctionTree newTree = gardener.CreateRandomTree(gardener.AllFunctions, maxTreeSize, maxTreeHeight); 75 63 if(!gardener.IsValidTree(newTree)) { 76 64 throw new InvalidProgramException(); … … 98 86 // it will be inserted 99 87 int parentLevel = gardener.GetBranchLevel(root, parent); 100 101 88 int maxSubTreeHeight = maxTreeHeight - parentLevel; 102 89 int maxSubTreeSize = maxTreeSize - (treeSize - gardener.GetTreeSize(parent.SubTrees[childIndex])); 103 90 104 91 // create a random function tree 105 IFunctionTree newTree; 106 if(random.NextDouble() <= balancedTreesRate) { 107 newTree = gardener.CreateRandomTree(allowedFunctions, maxSubTreeSize, maxSubTreeHeight, true); 108 } else { 109 newTree = gardener.CreateRandomTree(allowedFunctions, maxSubTreeSize, maxSubTreeHeight, false); 110 } 111 92 IFunctionTree newTree = gardener.CreateRandomTree(allowedFunctions, maxSubTreeSize, maxSubTreeHeight); 112 93 parent.RemoveSubTree(childIndex); 113 94 parent.InsertSubTree(childIndex, newTree); -
trunk/sources/HeuristicLab.StructureIdentification/TreeGardener.cs
r155 r163 74 74 75 75 #region random initialization 76 internal IFunctionTree CreateRandomTree(ICollection<IFunction> allowedFunctions, int maxTreeSize, int maxTreeHeight) { 77 // default is non-balanced trees 78 return CreateRandomTree(allowedFunctions, maxTreeSize, maxTreeHeight, false); 79 } 76 80 internal IFunctionTree CreateRandomTree(ICollection<IFunction> allowedFunctions, int maxTreeSize, int maxTreeHeight, bool balanceTrees) { 77 81
Note: See TracChangeset
for help on using the changeset viewer.