Changeset 3360 for trunk/sources/HeuristicLab.Encodings.SymbolicExpressionTreeEncoding/3.3/ArchitectureAlteringOperators
- Timestamp:
- 04/15/10 19:58:42 (15 years ago)
- Location:
- trunk/sources/HeuristicLab.Encodings.SymbolicExpressionTreeEncoding/3.3/ArchitectureAlteringOperators
- Files:
-
- 1 added
- 7 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/sources/HeuristicLab.Encodings.SymbolicExpressionTreeEncoding/3.3/ArchitectureAlteringOperators/ArgumentCreater.cs
r3338 r3360 96 96 // append a new argument branch after expanding all argument nodes 97 97 var clonedBranch = (SymbolicExpressionTreeNode)replacedBranch.Clone(); 98 ReplaceArgumentsInBranch(clonedBranch, invocationNode.SubTrees);98 clonedBranch = ReplaceArgumentsInBranch(clonedBranch, invocationNode.SubTrees); 99 99 invocationNode.InsertSubTree(newArgumentIndex, clonedBranch); 100 100 } … … 113 113 foreach (var subtree in symbolicExpressionTree.Root.SubTrees) { 114 114 // when the changed function is known in the branch then update the number of arguments 115 var matchingSymbol = subtree.Grammar.Symbols. Where(s => s.Name == selectedDefunBranch.FunctionName).SingleOrDefault();115 var matchingSymbol = subtree.Grammar.Symbols.OfType<InvokeFunction>().Where(s => s.FunctionName == selectedDefunBranch.FunctionName).SingleOrDefault(); 116 116 if (matchingSymbol != null) { 117 117 subtree.Grammar.SetMinSubtreeCount(matchingSymbol, selectedDefunBranch.NumberOfArguments); 118 118 subtree.Grammar.SetMaxSubtreeCount(matchingSymbol, selectedDefunBranch.NumberOfArguments); 119 foreach (var child in subtree.GetAllowedSymbols(0)) { 120 for (int i = 0; i < subtree.Grammar.GetMaxSubtreeCount(matchingSymbol); i++) { 121 subtree.Grammar.SetAllowedChild(matchingSymbol, child, i); 122 } 123 } 119 124 } 120 125 } … … 122 127 } 123 128 124 private static voidReplaceArgumentsInBranch(SymbolicExpressionTreeNode branch, IList<SymbolicExpressionTreeNode> argumentTrees) {125 // check if any subtree is an argument node126 for (int subtreeIndex = 0; subtreeIndex < branch.SubTrees.Count; subtreeIndex++) {127 var subtree = branch.SubTrees[subtreeIndex];128 var argNode = subtree as ArgumentTreeNode;129 if (argNode != null){130 // replace argument nodes by a clone of the original subtree that provided the result for the argument node131 branch.SubTrees[subtreeIndex] = (SymbolicExpressionTreeNode)argumentTrees[argNode.Symbol.ArgumentIndex].Clone();132 } else {133 // recursively replace arguments in all branches134 ReplaceArgumentsInBranch(subtree, argumentTrees);129 private static SymbolicExpressionTreeNode ReplaceArgumentsInBranch(SymbolicExpressionTreeNode branch, IList<SymbolicExpressionTreeNode> argumentTrees) { 130 if (branch is ArgumentTreeNode) { 131 var argNode = branch as ArgumentTreeNode; 132 // replace argument nodes by a clone of the original subtree that provided the result for the argument node 133 return (SymbolicExpressionTreeNode)argumentTrees[argNode.Symbol.ArgumentIndex].Clone(); 134 } else { 135 // call recursively for all subtree 136 List<SymbolicExpressionTreeNode> subtrees = new List<SymbolicExpressionTreeNode>(branch.SubTrees); 137 while (branch.SubTrees.Count > 0) branch.SubTrees.RemoveAt(0); 138 foreach (var subtree in subtrees) { 139 branch.AddSubTree(ReplaceArgumentsInBranch(subtree, argumentTrees)); 135 140 } 141 return branch; 136 142 } 137 143 } -
trunk/sources/HeuristicLab.Encodings.SymbolicExpressionTreeEncoding/3.3/ArchitectureAlteringOperators/ArgumentDeleter.cs
r3338 r3360 65 65 // argument deletion by consolidation is not possible => abort 66 66 return false; 67 // the argument to be removed is always the one with the largest index 68 // (otherwise we would have to decrement the index of the larger argument symbols) 67 69 var removedArgument = (from sym in selectedDefunBranch.Grammar.Symbols.OfType<Argument>() 68 select sym.ArgumentIndex).Distinct(). SelectRandom(random);70 select sym.ArgumentIndex).Distinct().OrderBy(x => x).Last(); 69 71 // find invocations of the manipulated funcion and remove the specified argument tree 70 var invocationNodes = from node in symbolicExpressionTree.IterateNodesPrefix().OfType<InvokeFunctionTreeNode>()71 where node.Symbol.FunctionName == selectedDefunBranch.FunctionName72 select node;72 var invocationNodes = (from node in symbolicExpressionTree.IterateNodesPrefix().OfType<InvokeFunctionTreeNode>() 73 where node.Symbol.FunctionName == selectedDefunBranch.FunctionName 74 select node).ToList(); 73 75 foreach (var invokeNode in invocationNodes) { 74 76 invokeNode.RemoveSubTree(removedArgument); … … 78 80 79 81 // delete the dynamic argument symbol that matches the argument to be removed 80 var matchingSymbol = selectedDefunBranch.Grammar.Symbols.OfType<Argument>().Where(s => s.ArgumentIndex == removedArgument). First();82 var matchingSymbol = selectedDefunBranch.Grammar.Symbols.OfType<Argument>().Where(s => s.ArgumentIndex == removedArgument).Single(); 81 83 selectedDefunBranch.Grammar.RemoveSymbol(matchingSymbol); 84 selectedDefunBranch.NumberOfArguments--; 82 85 // reduce arity in known functions of all root branches 83 86 foreach (var subtree in symbolicExpressionTree.Root.SubTrees) { 84 var matchingInvokeSymbol = subtree.Grammar.Symbols.OfType<InvokeFunction>().Where(s => s.FunctionName == selectedDefunBranch.FunctionName). FirstOrDefault();87 var matchingInvokeSymbol = subtree.Grammar.Symbols.OfType<InvokeFunction>().Where(s => s.FunctionName == selectedDefunBranch.FunctionName).SingleOrDefault(); 85 88 if (matchingInvokeSymbol != null) { 86 subtree.Grammar.SetMinSubtreeCount(matchingInvokeSymbol, selectedDefunBranch.NumberOfArguments - 1);87 subtree.Grammar.SetMaxSubtreeCount(matchingInvokeSymbol, selectedDefunBranch.NumberOfArguments - 1);89 subtree.Grammar.SetMinSubtreeCount(matchingInvokeSymbol, selectedDefunBranch.NumberOfArguments); 90 subtree.Grammar.SetMaxSubtreeCount(matchingInvokeSymbol, selectedDefunBranch.NumberOfArguments); 88 91 } 89 92 } 90 selectedDefunBranch.NumberOfArguments--;91 93 return true; 92 94 } -
trunk/sources/HeuristicLab.Encodings.SymbolicExpressionTreeEncoding/3.3/ArchitectureAlteringOperators/ArgumentDuplicater.cs
r3338 r3360 64 64 return false; 65 65 66 var selectedDefunBranch = SelectRandomBranch(random, functionDefiningBranches); 67 var argumentNodes = from node in IterateNodesPrefix(selectedDefunBranch) 68 where node is ArgumentTreeNode 69 select (ArgumentTreeNode)node; 70 if (argumentNodes.Count() == 0 || argumentNodes.Count() >= maxFunctionArguments) 66 var selectedDefunBranch = functionDefiningBranches.SelectRandom(random); 67 var argumentSymbols = selectedDefunBranch.Grammar.Symbols.OfType<Argument>(); 68 if (argumentSymbols.Count() == 0 || argumentSymbols.Count() >= maxFunctionArguments) 71 69 // when no argument or number of arguments is already at max allowed value => abort 72 70 return false; 73 var distinctArgumentIndexes = (from node in argumentNodes 74 select node.ArgumentIndex).Distinct().ToList(); 75 var selectedArgumentIndex = distinctArgumentIndexes[random.Next(distinctArgumentIndexes.Count)]; 76 var newArgumentIndex = allowedArgumentIndexes.Except(from argNode in argumentNodes select argNode.ArgumentIndex).First(); 71 var selectedArgumentSymbol = argumentSymbols.SelectRandom(random); 72 var takenIndexes = argumentSymbols.Select(s => s.ArgumentIndex); 73 var newArgumentIndex = allowedArgumentIndexes.Except(takenIndexes).First(); 74 75 var newArgSymbol = new Argument(newArgumentIndex); 76 77 77 // replace existing references to the original argument with references to the new argument randomly in the selectedBranch 78 var argumentNodes = selectedDefunBranch.IterateNodesPrefix().OfType<ArgumentTreeNode>(); 78 79 foreach (var argNode in argumentNodes) { 79 if (argNode. ArgumentIndex == selectedArgumentIndex) {80 if (argNode.Symbol == selectedArgumentSymbol) { 80 81 if (random.NextDouble() < 0.5) { 81 argNode. ArgumentIndex = newArgumentIndex;82 argNode.Symbol = newArgSymbol; 82 83 } 83 84 } 84 85 } 85 86 // find invocations of the functions and duplicate the matching argument branch 86 var invocationNodes = from node in symbolicExpressionTree.IterateNodesPrefix() 87 let invokeNode = node as InvokeFunctionTreeNode 88 where invokeNode != null 89 where invokeNode.InvokedFunctionName == selectedDefunBranch.Name 90 select invokeNode; 87 var invocationNodes = from node in symbolicExpressionTree.IterateNodesPrefix().OfType<InvokeFunctionTreeNode>() 88 where node.Symbol.FunctionName == selectedDefunBranch.FunctionName 89 select node; 91 90 foreach (var invokeNode in invocationNodes) { 92 var argumentBranch = invokeNode.SubTrees[selectedArgument Index];91 var argumentBranch = invokeNode.SubTrees[selectedArgumentSymbol.ArgumentIndex]; 93 92 var clonedArgumentBranch = (SymbolicExpressionTreeNode)argumentBranch.Clone(); 94 93 invokeNode.InsertSubTree(newArgumentIndex, clonedArgumentBranch); 95 94 } 96 // register the new argument node and increase the number of arguments of the ADF 97 selectedDefunBranch.AddDynamicSymbol("ARG" + newArgumentIndex); 95 // register the new argument symbol and increase the number of arguments of the ADF 96 selectedDefunBranch.Grammar.AddSymbol(newArgSymbol); 97 selectedDefunBranch.Grammar.SetMinSubtreeCount(newArgSymbol, 0); 98 selectedDefunBranch.Grammar.SetMaxSubtreeCount(newArgSymbol, 0); 99 // allow the argument as child of any other symbol 100 foreach (var symb in selectedDefunBranch.Grammar.Symbols) 101 for (int i = 0; i < selectedDefunBranch.Grammar.GetMaxSubtreeCount(symb); i++) { 102 selectedDefunBranch.Grammar.SetAllowedChild(symb, newArgSymbol, i); 103 } 98 104 selectedDefunBranch.NumberOfArguments++; 105 99 106 // increase the arity of the changed ADF in all branches that can use this ADF 100 107 foreach (var subtree in symbolicExpressionTree.Root.SubTrees) { 101 if (subtree.DynamicSymbols.Contains(selectedDefunBranch.Name)) { 102 subtree.SetDynamicSymbolArgumentCount(selectedDefunBranch.Name, selectedDefunBranch.NumberOfArguments); 108 var matchingInvokeSymbol = (from symb in subtree.Grammar.Symbols.OfType<InvokeFunction>() 109 where symb.FunctionName == selectedDefunBranch.FunctionName 110 select symb).SingleOrDefault(); 111 if (matchingInvokeSymbol != null) { 112 subtree.Grammar.SetMinSubtreeCount(matchingInvokeSymbol, selectedDefunBranch.NumberOfArguments); 113 subtree.Grammar.SetMaxSubtreeCount(matchingInvokeSymbol, selectedDefunBranch.NumberOfArguments); 114 foreach (var child in subtree.GetAllowedSymbols(0)) { 115 for (int i = 0; i < subtree.Grammar.GetMaxSubtreeCount(matchingInvokeSymbol); i++) { 116 subtree.Grammar.SetAllowedChild(matchingInvokeSymbol, child, i); 117 } 118 } 103 119 } 104 120 } 105 Debug.Assert(grammar.IsValidExpression(symbolicExpressionTree));106 121 return true; 107 122 } -
trunk/sources/HeuristicLab.Encodings.SymbolicExpressionTreeEncoding/3.3/ArchitectureAlteringOperators/RandomArchitectureAlteringOperator.cs
r3294 r3360 65 65 66 66 public override void ModifyArchitecture(IRandom random, SymbolicExpressionTree tree, ISymbolicExpressionGrammar grammar, IntValue maxTreeSize, IntValue maxTreeHeight, IntValue maxFunctionDefiningBranches, IntValue maxFunctionArguments, out bool success) { 67 var selectedOperator = Operators [random.Next(Operators.Count)];67 var selectedOperator = Operators.SelectRandom(random); 68 68 selectedOperator.ModifyArchitecture(random, tree, grammar, maxTreeSize, maxTreeHeight, maxFunctionDefiningBranches, maxFunctionArguments, out success); 69 69 } -
trunk/sources/HeuristicLab.Encodings.SymbolicExpressionTreeEncoding/3.3/ArchitectureAlteringOperators/SubroutineCreater.cs
r3338 r3360 42 42 [StorableClass] 43 43 public sealed class SubroutineCreater : SymbolicExpressionTreeArchitectureAlteringOperator { 44 private const double ARGUMENT_CUTOFF_PROBABILITY = 0.05; 45 44 46 public override sealed void ModifyArchitecture( 45 47 IRandom random, … … 62 64 // allowed maximum number of ADF reached => abort 63 65 return false; 64 string formatString = new StringBuilder().Append('0', (int)Math.Log10(maxFunctionDefiningBranches) + 1).ToString(); // >= 100 functions => ### 66 if (symbolicExpressionTree.Size + 4 > maxTreeSize) 67 // defining a new function causes an size increase by 4 nodes (max) if the max tree size is reached => abort 68 return false; 69 string formatString = new StringBuilder().Append('0', (int)Math.Log10(maxFunctionDefiningBranches * 10 - 1)).ToString(); // >= 100 functions => ### 65 70 var allowedFunctionNames = from index in Enumerable.Range(0, maxFunctionDefiningBranches) 66 71 select "ADF" + index.ToString(formatString); 67 // find all body branches 68 var bodies = from node in symbolicExpressionTree.IterateNodesPrefix()69 where node.Symbol is Defun || node.Symbol is StartSymbol72 73 // select a random body (either the result producing branch or an ADF branch) 74 var bodies = from node in symbolicExpressionTree.Root.SubTrees 70 75 select new { Tree = node, Size = node.GetSize() }; 71 76 var totalNumberOfBodyNodes = bodies.Select(x => x.Size).Sum(); 72 // select a random body73 77 int r = random.Next(totalNumberOfBodyNodes); 74 78 int aggregatedNumberOfBodyNodes = 0; … … 81 85 // sanity check 82 86 if (selectedBody == null) throw new InvalidOperationException(); 83 // select a random node in the selected branch 84 var allCutPoints = (from parent in selectedBody.IterateNodesPrefix() 85 from subtree in parent.SubTrees 86 select new { Parent = parent, ReplacedBranchIndex = parent.SubTrees.IndexOf(subtree), ReplacedBranch = subtree }).ToList(); 87 if (allCutPoints.Count == 0) 87 88 // select a random cut point in the selected branch 89 var allCutPoints = from parent in selectedBody.IterateNodesPrefix() 90 from subtree in parent.SubTrees 91 select new { Parent = parent, ReplacedBranchIndex = parent.SubTrees.IndexOf(subtree), ReplacedBranch = subtree }; 92 if (allCutPoints.Count() == 0) 88 93 // no cut points => abort 89 94 return false; 90 var selectedCutPoint = allCutPoints[random.Next(allCutPoints.Count)]; 95 string newFunctionName = allowedFunctionNames.Except(functionDefiningBranches.Select(x => x.FunctionName)).First(); 96 var selectedCutPoint = allCutPoints.SelectRandom(random); 91 97 // select random branches as argument cut-off points (replaced by argument terminal nodes in the function) 92 List<SymbolicExpressionTreeNode> argumentBranches = SelectRandomArgumentBranches(selectedCutPoint.ReplacedBranch, random, 0.25, maxFunctionArguments); 93 string functionName = allowedFunctionNames.Except(functionDefiningBranches.Select(x => x.Name)).First(); 98 List<SymbolicExpressionTreeNode> argumentBranches = SelectRandomArgumentBranches(selectedCutPoint.ReplacedBranch, random, ARGUMENT_CUTOFF_PROBABILITY, maxFunctionArguments); 94 99 SymbolicExpressionTreeNode functionBody = selectedCutPoint.ReplacedBranch; 95 100 // disconnect the function body from the tree 96 101 selectedCutPoint.Parent.RemoveSubTree(selectedCutPoint.ReplacedBranchIndex); 97 102 // disconnect the argument branches from the function 98 DisconnectBranches(functionBody, argumentBranches); 99 // and insert a function invocation symbol instead 100 var invokeNode = (InvokeFunctionTreeNode)(new InvokeFunction()).CreateTreeNode(); 101 invokeNode.InvokedFunctionName = functionName; 103 functionBody = DisconnectBranches(functionBody, argumentBranches); 104 // insert a function invocation symbol instead 105 var invokeNode = (InvokeFunctionTreeNode)(new InvokeFunction(newFunctionName)).CreateTreeNode(); 102 106 selectedCutPoint.Parent.InsertSubTree(selectedCutPoint.ReplacedBranchIndex, invokeNode); 107 // add the branches selected as argument as subtrees of the function invocation node 103 108 foreach (var argumentBranch in argumentBranches) 104 109 invokeNode.AddSubTree(argumentBranch); … … 106 111 // insert a new function defining branch 107 112 var defunNode = (DefunTreeNode)(new Defun()).CreateTreeNode(); 108 defunNode. Name = functionName;113 defunNode.FunctionName = newFunctionName; 109 114 defunNode.AddSubTree(functionBody); 110 115 symbolicExpressionTree.Root.AddSubTree(defunNode); 111 // copy known symbols from originating branch into new branch 112 foreach (var knownSymbol in selectedBody.DynamicSymbols) { 113 defunNode.AddDynamicSymbol(knownSymbol, selectedBody.GetDynamicSymbolArgumentCount(knownSymbol)); 114 } 115 // add function arguments as known symbols to new branch 116 for (int i = 0; i < argumentBranches.Count; i++) { 117 defunNode.AddDynamicSymbol("ARG" + i); 118 } 119 // add new function name to original branch 120 selectedBody.AddDynamicSymbol(functionName, argumentBranches.Count); 116 // the grammar in the newly defined function is a clone of the grammar of the originating branch 117 defunNode.Grammar = (ISymbolicExpressionGrammar)selectedBody.Grammar.Clone(); 118 // remove all argument symbols from grammar 119 var oldArgumentSymbols = defunNode.Grammar.Symbols.OfType<Argument>().ToList(); 120 foreach (var oldArgSymb in oldArgumentSymbols) 121 defunNode.Grammar.RemoveSymbol(oldArgSymb); 122 // find unique argument indexes and matching symbols in the function defining branch 123 var newArgumentIndexes = (from node in defunNode.IterateNodesPrefix().OfType<ArgumentTreeNode>() 124 select node.Symbol.ArgumentIndex).Distinct(); 125 // add argument symbols to grammar of function defining branch 126 GrammarModifier.AddDynamicArguments(defunNode.Grammar, defunNode.Symbol, newArgumentIndexes); 127 defunNode.NumberOfArguments = newArgumentIndexes.Count(); 128 if (defunNode.NumberOfArguments != argumentBranches.Count) throw new InvalidOperationException(); 129 // add invoke symbol for newly defined function to the original branch 130 var allowedParents = from symb in selectedBody.Grammar.Symbols 131 where !(symb is ProgramRootSymbol) 132 select symb; 133 var allowedChildren = from symb in selectedBody.Grammar.Symbols 134 where selectedBody.Grammar.IsAllowedChild(selectedBody.Symbol, symb, 0) 135 select symb; 136 GrammarModifier.AddDynamicSymbol(selectedBody.Grammar, selectedBody.Symbol, defunNode.FunctionName, defunNode.NumberOfArguments); 137 138 // when the new function body was taken from another function definition 139 // add invoke symbol for newly defined function to all branches that are allowed to invoke the original branch 140 if (selectedBody.Symbol is Defun) { 141 var originalFunctionDefinition = selectedBody as DefunTreeNode; 142 foreach (var subtree in symbolicExpressionTree.Root.SubTrees) { 143 var originalBranchInvokeSymbol = (from symb in subtree.Grammar.Symbols.OfType<InvokeFunction>() 144 where symb.FunctionName == originalFunctionDefinition.FunctionName 145 select symb).SingleOrDefault(); 146 // when the original branch can be invoked from the subtree then also allow invocation of the function 147 if (originalBranchInvokeSymbol != null) { 148 allowedParents = from symb in subtree.Grammar.Symbols 149 where !(symb is ProgramRootSymbol) 150 select symb; 151 allowedChildren = from symb in subtree.Grammar.Symbols 152 where subtree.Grammar.IsAllowedChild(subtree.Symbol, symb, 0) 153 select symb; 154 GrammarModifier.AddDynamicSymbol(subtree.Grammar, subtree.Symbol, defunNode.FunctionName, defunNode.NumberOfArguments); 155 } 156 } 157 } 121 158 return true; 122 159 } 123 160 124 private static void DisconnectBranches(SymbolicExpressionTreeNode node, List<SymbolicExpressionTreeNode> argumentBranches) { 161 private static SymbolicExpressionTreeNode DisconnectBranches(SymbolicExpressionTreeNode node, List<SymbolicExpressionTreeNode> argumentBranches) { 162 if (argumentBranches.Contains(node)) { 163 var argumentIndex = argumentBranches.IndexOf(node); 164 var argSymbol = new Argument(argumentIndex); 165 return argSymbol.CreateTreeNode(); 166 } 125 167 // remove the subtrees so that we can clone only the root node 126 168 List<SymbolicExpressionTreeNode> subtrees = new List<SymbolicExpressionTreeNode>(node.SubTrees); … … 128 170 // recursively apply function for subtrees or append a argument terminal node 129 171 foreach (var subtree in subtrees) { 130 if (argumentBranches.Contains(subtree)) { 131 node.AddSubTree(MakeArgumentNode(argumentBranches.IndexOf(subtree))); 132 } else { 133 DisconnectBranches(subtree, argumentBranches); 134 node.AddSubTree(subtree); 135 } 136 } 137 } 138 139 private static SymbolicExpressionTreeNode MakeArgumentNode(int argIndex) { 140 var node = (ArgumentTreeNode)(new Argument()).CreateTreeNode(); 141 node.ArgumentIndex = argIndex; 172 node.AddSubTree(DisconnectBranches(subtree, argumentBranches)); 173 } 142 174 return node; 143 175 } … … 145 177 private static List<SymbolicExpressionTreeNode> SelectRandomArgumentBranches(SymbolicExpressionTreeNode selectedRoot, 146 178 IRandom random, 147 double argumentProbability,179 double cutProbability, 148 180 int maxArguments) { 181 // breadth first determination of argument cut-off points 182 // we must make sure that we cut off all original argument nodes and that the number of new argument is smaller than the limit 149 183 List<SymbolicExpressionTreeNode> argumentBranches = new List<SymbolicExpressionTreeNode>(); 150 foreach (var subTree in selectedRoot.SubTrees) { 151 if (random.NextDouble() < argumentProbability) { 152 if (argumentBranches.Count < maxArguments) 153 argumentBranches.Add(subTree); 154 } else { 155 foreach (var argBranch in SelectRandomArgumentBranches(subTree, random, argumentProbability, maxArguments)) 156 if (argumentBranches.Count < maxArguments) 157 argumentBranches.Add(argBranch); 184 if (selectedRoot is ArgumentTreeNode) { 185 argumentBranches.Add(selectedRoot); 186 return argumentBranches; 187 } else { 188 // get the number of argument nodes (which must be cut-off) in the sub-trees 189 var numberOfArgumentsInSubtrees = (from subtree in selectedRoot.SubTrees 190 let nArgumentsInTree = subtree.IterateNodesPrefix().OfType<ArgumentTreeNode>().Count() 191 select nArgumentsInTree).ToList(); 192 // determine the minimal number of new argument nodes for each sub-tree 193 var minNewArgumentsForSubtrees = numberOfArgumentsInSubtrees.Select(x => x > 0 ? 1 : 0).ToList(); 194 if (minNewArgumentsForSubtrees.Sum() > maxArguments) { 195 argumentBranches.Add(selectedRoot); 196 return argumentBranches; 158 197 } 159 } 160 return argumentBranches; 161 } 162 163 private static IEnumerable<string> UsedFunctionNames(SymbolicExpressionTree symbolicExpressionTree) { 164 return from node in symbolicExpressionTree.IterateNodesPrefix() 165 where node.Symbol is Defun 166 select ((DefunTreeNode)node).Name; 198 // cut-off in the sub-trees in random order 199 var randomIndexes = (from index in Enumerable.Range(0, selectedRoot.SubTrees.Count) 200 select new { Index = index, OrderValue = random.NextDouble() }).OrderBy(x => x.OrderValue).Select(x => x.Index); 201 foreach (var subtreeIndex in randomIndexes) { 202 var subtree = selectedRoot.SubTrees[subtreeIndex]; 203 minNewArgumentsForSubtrees[subtreeIndex] = 0; 204 // => cut-off at 0..n points somewhere in the current sub-tree 205 // determine the maximum number of new arguments that should be created in the branch 206 // as the maximum for the whole branch minus already added arguments minus minimal number of arguments still left 207 int maxArgumentsFromBranch = maxArguments - argumentBranches.Count - minNewArgumentsForSubtrees.Sum(); 208 // when no argument is allowed from the current branch then we have to include the whole branch into the function 209 // otherwise: choose randomly wether to cut off immediately or wether to extend the function body into the branch 210 if (maxArgumentsFromBranch == 0) { 211 // don't cut at all => the whole sub-tree branch is included in the function body 212 // (we already checked ahead of time that there are no arguments left over in the subtree) 213 } else if (random.NextDouble() >= cutProbability) { 214 argumentBranches.AddRange(SelectRandomArgumentBranches(subtree, random, cutProbability, maxArgumentsFromBranch)); 215 } else { 216 // cut-off at current sub-tree 217 argumentBranches.Add(subtree); 218 } 219 } 220 return argumentBranches; 221 } 167 222 } 168 223 } -
trunk/sources/HeuristicLab.Encodings.SymbolicExpressionTreeEncoding/3.3/ArchitectureAlteringOperators/SubroutineDeleter.cs
r3338 r3360 41 41 [StorableClass] 42 42 public sealed class SubroutineDeleter : SymbolicExpressionTreeArchitectureAlteringOperator { 43 private const int MAX_TRIES = 100;44 43 public override sealed void ModifyArchitecture( 45 44 IRandom random, … … 68 67 symbolicExpressionTree.Root.RemoveSubTree(defunSubtreeIndex); 69 68 70 // get all cut points that contain an invokation of the deleted defun71 var invocationCutPoints = from node in symbolicExpressionTree.IterateNodesPrefix()72 where node.SubTrees.Count > 073 from argIndex in Enumerable.Range(0, node.SubTrees.Count)74 let subtree = node.SubTrees[argIndex] as InvokeFunctionTreeNode75 where subtree != null76 where subtree.InvokedFunctionName == selectedDefunBranch.Name77 select new { Parent = node, ReplacedChildIndex = argIndex, ReplacedChild = subtree };78 // deletion by random regeneration79 foreach (var cutPoint in invocationCutPoints) {80 SymbolicExpressionTreeNode replacementTree = null;81 int targetSize = random.Next(cutPoint.ReplacedChild.GetSize());82 int targetHeight = cutPoint.ReplacedChild.GetHeight();83 int tries = 0;84 do {85 try {86 replacementTree = ProbabilisticTreeCreator.PTC2(random, grammar, cutPoint.Parent.Symbol, targetSize, targetHeight);87 }88 catch (ArgumentException) {89 // try different size90 targetSize = random.Next(cutPoint.ReplacedChild.GetSize());91 if (tries++ > MAX_TRIES) throw;92 }93 } while (replacementTree == null);94 cutPoint.Parent.RemoveSubTree(cutPoint.ReplacedChildIndex);95 cutPoint.Parent.InsertSubTree(cutPoint.ReplacedChildIndex, replacementTree);96 }97 69 // remove references to deleted function 98 70 foreach (var subtree in symbolicExpressionTree.Root.SubTrees) { 99 if (subtree.DynamicSymbols.Contains(selectedDefunBranch.Name)) { 100 subtree.RemoveDynamicSymbol(selectedDefunBranch.Name); 71 var matchingInvokeSymbol = (from symb in subtree.Grammar.Symbols.OfType<InvokeFunction>() 72 where symb.FunctionName == selectedDefunBranch.FunctionName 73 select symb).SingleOrDefault(); 74 if (matchingInvokeSymbol != null) { 75 subtree.Grammar.RemoveSymbol(matchingInvokeSymbol); 101 76 } 102 77 } 103 Debug.Assert(grammar.IsValidExpression(symbolicExpressionTree)); 78 79 DeletionByRandomRegeneration(random, symbolicExpressionTree, selectedDefunBranch); 104 80 return true; 81 } 82 83 private static void DeletionByRandomRegeneration(IRandom random, SymbolicExpressionTree symbolicExpressionTree, DefunTreeNode selectedDefunBranch) { 84 // find first invocation and replace it with a randomly generated tree 85 // can't find all invocations in one step because once we replaced a top level invocation 86 // the invocations below it are removed already 87 var invocationCutPoint = (from node in symbolicExpressionTree.IterateNodesPrefix() 88 from subtree in node.SubTrees.OfType<InvokeFunctionTreeNode>() 89 where subtree.Symbol.FunctionName == selectedDefunBranch.FunctionName 90 select new { Parent = node, ReplacedChildIndex = node.SubTrees.IndexOf(subtree), ReplacedChild = subtree }).FirstOrDefault(); 91 while (invocationCutPoint != null) { 92 // deletion by random regeneration 93 SymbolicExpressionTreeNode replacementTree = null; 94 // TODO: should weight symbols by tickets 95 var selectedSymbol = invocationCutPoint.Parent.GetAllowedSymbols(invocationCutPoint.ReplacedChildIndex).SelectRandom(random); 96 97 int minPossibleSize = invocationCutPoint.Parent.Grammar.GetMinExpressionLength(selectedSymbol); 98 int maxSize = Math.Max(minPossibleSize, invocationCutPoint.ReplacedChild.GetSize()); 99 int minPossibleHeight = invocationCutPoint.Parent.Grammar.GetMinExpressionDepth(selectedSymbol); 100 int maxHeight = Math.Max(minPossibleHeight, invocationCutPoint.ReplacedChild.GetHeight()); 101 102 replacementTree = ProbabilisticTreeCreator.PTC2(random, invocationCutPoint.Parent.Grammar, selectedSymbol, maxSize, maxHeight, 0, 0); 103 invocationCutPoint.Parent.RemoveSubTree(invocationCutPoint.ReplacedChildIndex); 104 invocationCutPoint.Parent.InsertSubTree(invocationCutPoint.ReplacedChildIndex, replacementTree); 105 106 invocationCutPoint = (from node in symbolicExpressionTree.IterateNodesPrefix() 107 from subtree in node.SubTrees.OfType<InvokeFunctionTreeNode>() 108 where subtree.Symbol.FunctionName == selectedDefunBranch.FunctionName 109 select new { Parent = node, ReplacedChildIndex = node.SubTrees.IndexOf(subtree), ReplacedChild = subtree }).FirstOrDefault(); 110 } 105 111 } 106 112 } -
trunk/sources/HeuristicLab.Encodings.SymbolicExpressionTreeEncoding/3.3/ArchitectureAlteringOperators/SubroutineDuplicater.cs
r3338 r3360 48 48 IntValue maxFunctionDefiningBranches, IntValue maxFunctionArguments, 49 49 out bool success) { 50 success = Duplicate RandomSubroutine(random, symbolicExpressionTree, grammar, maxTreeSize.Value, maxTreeHeight.Value, maxFunctionDefiningBranches.Value, maxFunctionArguments.Value);50 success = DuplicateSubroutine(random, symbolicExpressionTree, grammar, maxTreeSize.Value, maxTreeHeight.Value, maxFunctionDefiningBranches.Value, maxFunctionArguments.Value); 51 51 } 52 52 53 public static bool Duplicate RandomSubroutine(53 public static bool DuplicateSubroutine( 54 54 IRandom random, 55 55 SymbolicExpressionTree symbolicExpressionTree, … … 66 66 return false; 67 67 var selectedBranch = functionDefiningBranches.SelectRandom(random); 68 var clonedBranch = (DefunTreeNode)selectedBranch.Clone(); 69 clonedBranch.Name = allowedFunctionNames.Except(UsedFunctionNames(symbolicExpressionTree)).First(); 70 foreach (var node in symbolicExpressionTree.IterateNodesPrefix()) { 71 var invokeFunctionNode = node as InvokeFunctionTreeNode; 72 // find all invokations of the old function 73 if (invokeFunctionNode != null && invokeFunctionNode.InvokedFunctionName == selectedBranch.Name) { 74 // add the new function name to the list of known functions in the branches that used the originating function 75 var branch = symbolicExpressionTree.GetTopLevelBranchOf(invokeFunctionNode); 76 branch.AddDynamicSymbol(clonedBranch.Name, clonedBranch.NumberOfArguments); 77 // flip coin wether to replace with newly defined function 78 if (random.NextDouble() < 0.5) { 79 invokeFunctionNode.InvokedFunctionName = clonedBranch.Name; 80 } 68 var duplicatedDefunBranch = (DefunTreeNode)selectedBranch.Clone(); 69 string newFunctionName = allowedFunctionNames.Except(UsedFunctionNames(symbolicExpressionTree)).First(); 70 duplicatedDefunBranch.FunctionName = newFunctionName; 71 symbolicExpressionTree.Root.SubTrees.Add(duplicatedDefunBranch); 72 duplicatedDefunBranch.Grammar = (ISymbolicExpressionGrammar)selectedBranch.Grammar.Clone(); 73 // add an invoke symbol for each branch that is allowed to invoke the original function 74 foreach (var subtree in symbolicExpressionTree.Root.SubTrees) { 75 var matchingInvokeSymbol = (from symb in subtree.Grammar.Symbols.OfType<InvokeFunction>() 76 where symb.FunctionName == selectedBranch.FunctionName 77 select symb).SingleOrDefault(); 78 if (matchingInvokeSymbol != null) { 79 GrammarModifier.AddDynamicSymbol(subtree.Grammar, subtree.Symbol, duplicatedDefunBranch.FunctionName, duplicatedDefunBranch.NumberOfArguments); 81 80 } 82 81 } 83 Debug.Assert(grammar.IsValidExpression(symbolicExpressionTree)); 82 // for all invoke nodes of the original function replace the invoke of the original function with an invoke of the new function randomly 83 var originalFunctionInvocations = from node in symbolicExpressionTree.IterateNodesPrefix().OfType<InvokeFunctionTreeNode>() 84 where node.Symbol.FunctionName == selectedBranch.FunctionName 85 select node; 86 foreach (var originalFunctionInvokeNode in originalFunctionInvocations) { 87 var newInvokeSymbol = (from symb in originalFunctionInvokeNode.Grammar.Symbols.OfType<InvokeFunction>() 88 where symb.FunctionName == duplicatedDefunBranch.FunctionName 89 select symb).Single(); 90 // flip coin wether to replace with newly defined function 91 if (random.NextDouble() < 0.5) { 92 originalFunctionInvokeNode.Symbol = newInvokeSymbol; 93 } 94 } 84 95 return true; 85 }86 87 private static bool ContainsNode(SymbolicExpressionTreeNode branch, SymbolicExpressionTreeNode node) {88 if (branch == node) return true;89 else foreach (var subtree in branch.SubTrees) {90 if (ContainsNode(subtree, node)) return true;91 }92 return false;93 96 } 94 97 … … 96 99 return from node in symbolicExpressionTree.IterateNodesPrefix() 97 100 where node.Symbol is Defun 98 select ((DefunTreeNode)node). Name;101 select ((DefunTreeNode)node).FunctionName; 99 102 } 100 101 102 103 } 103 104 }
Note: See TracChangeset
for help on using the changeset viewer.