private static void DeletionByRandomRegeneration(IRandom random, ISymbolicExpressionTree symbolicExpressionTree, DefunTreeNode selectedDefunBranch) { // find first invocation and replace it with a randomly generated tree // can't find all invocations in one step because once we replaced a top level invocation // the invocations below it are removed already var invocationCutPoint = (from node in symbolicExpressionTree.IterateNodesPrefix() from subtree in node.Subtrees.OfType <InvokeFunctionTreeNode>() where subtree.Symbol.FunctionName == selectedDefunBranch.FunctionName select new CutPoint(node, subtree)).FirstOrDefault(); while (invocationCutPoint != null) { // deletion by random regeneration ISymbolicExpressionTreeNode replacementTree = null; var allowedSymbolsList = invocationCutPoint.Parent.Grammar.GetAllowedChildSymbols(invocationCutPoint.Parent.Symbol, invocationCutPoint.ChildIndex).ToList(); var weights = allowedSymbolsList.Select(s => s.InitialFrequency); #pragma warning disable 612, 618 var selectedSymbol = allowedSymbolsList.SelectRandom(weights, random); #pragma warning restore 612, 618 int minPossibleLength = invocationCutPoint.Parent.Grammar.GetMinimumExpressionLength(selectedSymbol); int maxLength = Math.Max(minPossibleLength, invocationCutPoint.Child.GetLength()); int minPossibleDepth = invocationCutPoint.Parent.Grammar.GetMinimumExpressionDepth(selectedSymbol); int maxDepth = Math.Max(minPossibleDepth, invocationCutPoint.Child.GetDepth()); replacementTree = selectedSymbol.CreateTreeNode(); if (replacementTree.HasLocalParameters) { replacementTree.ResetLocalParameters(random); } invocationCutPoint.Parent.RemoveSubtree(invocationCutPoint.ChildIndex); invocationCutPoint.Parent.InsertSubtree(invocationCutPoint.ChildIndex, replacementTree); ProbabilisticTreeCreator.PTC2(random, replacementTree, maxLength, maxDepth); invocationCutPoint = (from node in symbolicExpressionTree.IterateNodesPrefix() from subtree in node.Subtrees.OfType <InvokeFunctionTreeNode>() where subtree.Symbol.FunctionName == selectedDefunBranch.FunctionName select new CutPoint(node, subtree)).FirstOrDefault(); } }
private static bool TryCreateFullTreeFromSeed(IRandom random, ISymbolicExpressionTreeNode root, int targetLength, int maxDepth) { List <TreeExtensionPoint> extensionPoints = new List <TreeExtensionPoint>(); int currentLength = 0; int actualArity = SampleArity(random, root, targetLength, maxDepth); if (actualArity < 0) { return(false); } for (int i = 0; i < actualArity; i++) { // insert a dummy sub-tree and add the pending extension to the list var dummy = new SymbolicExpressionTreeNode(); root.AddSubtree(dummy); var x = new TreeExtensionPoint { Parent = root, ChildIndex = i, ExtensionPointDepth = 0 }; FillExtensionLengths(x, maxDepth); extensionPoints.Add(x); } //necessary to use long data type as the extension point length could be int.MaxValue long minExtensionPointsLength = extensionPoints.Select(x => (long)x.MinimumExtensionLength).Sum(); long maxExtensionPointsLength = extensionPoints.Select(x => (long)x.MaximumExtensionLength).Sum(); // while there are pending extension points and we have not reached the limit of adding new extension points while (extensionPoints.Count > 0 && minExtensionPointsLength + currentLength <= targetLength) { int randomIndex = random.Next(extensionPoints.Count); TreeExtensionPoint nextExtension = extensionPoints[randomIndex]; extensionPoints.RemoveAt(randomIndex); ISymbolicExpressionTreeNode parent = nextExtension.Parent; int argumentIndex = nextExtension.ChildIndex; int extensionDepth = nextExtension.ExtensionPointDepth; if (parent.Grammar.GetMinimumExpressionDepth(parent.Symbol) > maxDepth - extensionDepth) { ReplaceWithMinimalTree(random, root, parent, argumentIndex); int insertedTreeLength = parent.GetSubtree(argumentIndex).GetLength(); currentLength += insertedTreeLength; minExtensionPointsLength -= insertedTreeLength; maxExtensionPointsLength -= insertedTreeLength; } else { //remove currently chosen extension point from calculation minExtensionPointsLength -= nextExtension.MinimumExtensionLength; maxExtensionPointsLength -= nextExtension.MaximumExtensionLength; var symbols = from s in parent.Grammar.GetAllowedChildSymbols(parent.Symbol, argumentIndex) where s.InitialFrequency > 0.0 where parent.Grammar.GetMinimumExpressionDepth(s) <= maxDepth - extensionDepth where parent.Grammar.GetMinimumExpressionLength(s) <= targetLength - currentLength - minExtensionPointsLength select s; if (maxExtensionPointsLength < targetLength - currentLength) { symbols = from s in symbols where parent.Grammar.GetMaximumExpressionLength(s, maxDepth - extensionDepth) >= targetLength - currentLength - maxExtensionPointsLength select s; } var allowedSymbols = symbols.ToList(); if (allowedSymbols.Count == 0) { return(false); } var weights = allowedSymbols.Select(x => x.InitialFrequency).ToList(); #pragma warning disable 612, 618 var selectedSymbol = allowedSymbols.SelectRandom(weights, random); #pragma warning restore 612, 618 ISymbolicExpressionTreeNode newTree = selectedSymbol.CreateTreeNode(); if (newTree.HasLocalParameters) { newTree.ResetLocalParameters(random); } parent.RemoveSubtree(argumentIndex); parent.InsertSubtree(argumentIndex, newTree); var topLevelNode = newTree as SymbolicExpressionTreeTopLevelNode; if (topLevelNode != null) { topLevelNode.SetGrammar((ISymbolicExpressionTreeGrammar)root.Grammar.Clone()); } currentLength++; actualArity = SampleArity(random, newTree, targetLength - currentLength, maxDepth - extensionDepth); if (actualArity < 0) { return(false); } for (int i = 0; i < actualArity; i++) { // insert a dummy sub-tree and add the pending extension to the list var dummy = new SymbolicExpressionTreeNode(); newTree.AddSubtree(dummy); var x = new TreeExtensionPoint { Parent = newTree, ChildIndex = i, ExtensionPointDepth = extensionDepth + 1 }; FillExtensionLengths(x, maxDepth); extensionPoints.Add(x); maxExtensionPointsLength += x.MaximumExtensionLength; minExtensionPointsLength += x.MinimumExtensionLength; } } } // fill all pending extension points while (extensionPoints.Count > 0) { int randomIndex = random.Next(extensionPoints.Count); TreeExtensionPoint nextExtension = extensionPoints[randomIndex]; extensionPoints.RemoveAt(randomIndex); ISymbolicExpressionTreeNode parent = nextExtension.Parent; int a = nextExtension.ChildIndex; ReplaceWithMinimalTree(random, root, parent, a); } return(true); }