/// <summary> /// Remove, Replace or Insert subtrees /// </summary> /// <param name="tree">The symbolic expression tree</param> /// <param name="parent">The insertion point (ie, the parent node who will receive a new child)</param> /// <param name="oldChild">The subtree to be replaced</param> /// <param name="newChild">The replacement subtree</param> /// <param name="removeSubtree">Flag used to indicate if whole subtrees should be removed (default behavior), or just the subtree root</param> private void Modify(ISymbolicExpressionTree tree, ISymbolicExpressionTreeNode parent, ISymbolicExpressionTreeNode oldChild, ISymbolicExpressionTreeNode newChild, bool removeSubtree = true) { if (oldChild == null && newChild == null) { throw new ArgumentNullException("Cannot deduce operation type from the arguments. Please provide non null operands."); } if (oldChild == null) { // insertion operation parent.AddSubtree(newChild); newChild.Parent = parent; } else if (newChild == null) { // removal operation parent.RemoveSubtree(parent.IndexOfSubtree(oldChild)); if (!removeSubtree) { for (int i = oldChild.SubtreeCount - 1; i >= 0; --i) { var subtree = oldChild.GetSubtree(i); oldChild.RemoveSubtree(i); parent.AddSubtree(subtree); } } } else { // replacement operation var replacementIndex = parent.IndexOfSubtree(oldChild); parent.RemoveSubtree(replacementIndex); parent.InsertSubtree(replacementIndex, newChild); newChild.Parent = parent; if (changedNodes.ContainsKey(oldChild)) { changedNodes.Add(newChild, changedNodes[oldChild]); // so that on double click the original node is restored changedNodes.Remove(oldChild); } else { changedNodes.Add(newChild, oldChild); } } treeState = IsValid(tree) ? TreeState.Valid : TreeState.Invalid; switch (treeState) { case TreeState.Valid: this.grpViewHost.Enabled = true; UpdateModel(Content.Model.SymbolicExpressionTree); break; case TreeState.Invalid: this.grpViewHost.Enabled = false; break; } }
private void SwitchNode(ISymbolicExpressionTreeNode root, ISymbolicExpressionTreeNode oldBranch, ISymbolicExpressionTreeNode newBranch) { for (int i = 0; i < root.SubtreeCount; i++) { if (root.GetSubtree(i) == oldBranch) { root.RemoveSubtree(i); root.InsertSubtree(i, newBranch); return; } } }
private void SwitchNodeWithReplacementNode(ISymbolicExpressionTreeNode parent, int subTreeIndex) { ISymbolicExpressionTreeNode subTree = parent.GetSubtree(subTreeIndex); if (foldedNodes.ContainsKey(subTree)) { parent.RemoveSubtree(subTreeIndex); var replacementNode = foldedNodes[subTree]; parent.InsertSubtree(subTreeIndex, replacementNode); // exchange key and value foldedNodes.Remove(subTree); foldedNodes.Add(replacementNode, subTree); } }
protected static ISymbolicExpressionTreeNode GenerateAndInsertNewSubtree(IRandom random, ISymbolicExpressionTreeNode parent, List <ISymbol> allowedSymbols, int childIndex, int maxLength, int maxDepth) { var weights = allowedSymbols.Select(s => s.InitialFrequency).ToList(); #pragma warning disable 612, 618 var seedSymbol = allowedSymbols.SelectRandom(weights, random); #pragma warning restore 612, 618 // replace the old node with the new node var seedNode = seedSymbol.CreateTreeNode(); if (seedNode.HasLocalParameters) { seedNode.ResetLocalParameters(random); } parent.RemoveSubtree(childIndex); parent.InsertSubtree(childIndex, seedNode); ProbabilisticTreeCreator.PTC2(random, seedNode, maxLength, maxDepth); return(seedNode); }
/// <summary> /// Remove, Replace or Insert subtrees /// </summary> /// <param name="tree">The symbolic expression tree</param> /// <param name="parent">The insertion point (ie, the parent node who will receive a new child)</param> /// <param name="oldChild">The subtree to be replaced</param> /// <param name="newChild">The replacement subtree</param> /// <param name="removeSubtree">Flag used to indicate if whole subtrees should be removed (default behavior), or just the subtree root</param> private void Modify(ISymbolicExpressionTree tree, ISymbolicExpressionTreeNode parent, ISymbolicExpressionTreeNode oldChild, ISymbolicExpressionTreeNode newChild, bool removeSubtree = true) { if (oldChild == null && newChild == null) throw new ArgumentNullException("Cannot deduce operation type from the arguments. Please provide non null operands."); if (oldChild == null) { // insertion operation parent.AddSubtree(newChild); newChild.Parent = parent; } else if (newChild == null) { // removal operation parent.RemoveSubtree(parent.IndexOfSubtree(oldChild)); if (!removeSubtree) { for (int i = oldChild.SubtreeCount - 1; i >= 0; --i) { var subtree = oldChild.GetSubtree(i); oldChild.RemoveSubtree(i); parent.AddSubtree(subtree); } } } else { // replacement operation var replacementIndex = parent.IndexOfSubtree(oldChild); parent.RemoveSubtree(replacementIndex); parent.InsertSubtree(replacementIndex, newChild); newChild.Parent = parent; if (changedNodes.ContainsKey(oldChild)) { changedNodes.Add(newChild, changedNodes[oldChild]); // so that on double click the original node is restored changedNodes.Remove(oldChild); } else { changedNodes.Add(newChild, oldChild); } } treeState = IsValid(tree) ? TreeState.Valid : TreeState.Invalid; switch (treeState) { case TreeState.Valid: this.grpViewHost.Enabled = true; UpdateModel(Content.Model.SymbolicExpressionTree); break; case TreeState.Invalid: this.grpViewHost.Enabled = false; break; } }
private static void ReplaceWithMinimalTree(IRandom random, ISymbolicExpressionTreeNode root, ISymbolicExpressionTreeNode parent, int childIndex) { // determine possible symbols that will lead to the smallest possible tree var possibleSymbols = (from s in parent.Grammar.GetAllowedChildSymbols(parent.Symbol, childIndex) where s.InitialFrequency > 0.0 group s by parent.Grammar.GetMinimumExpressionLength(s) into g orderby g.Key select g).First().ToList(); var weights = possibleSymbols.Select(x => x.InitialFrequency).ToList(); #pragma warning disable 612, 618 var selectedSymbol = possibleSymbols.SelectRandom(weights, random); #pragma warning restore 612, 618 var tree = selectedSymbol.CreateTreeNode(); if (tree.HasLocalParameters) { tree.ResetLocalParameters(random); } parent.RemoveSubtree(childIndex); parent.InsertSubtree(childIndex, tree); var topLevelNode = tree as SymbolicExpressionTreeTopLevelNode; if (topLevelNode != null) { topLevelNode.SetGrammar((ISymbolicExpressionTreeGrammar)root.Grammar.Clone()); } for (int i = 0; i < tree.Grammar.GetMinimumSubtreeCount(tree.Symbol); i++) { // insert a dummy sub-tree and add the pending extension to the list var dummy = new SymbolicExpressionTreeNode(); tree.AddSubtree(dummy); // replace the just inserted dummy by recursive application ReplaceWithMinimalTree(random, root, tree, i); } }
/// <summary> /// 1. find a mutation point /// 2. generate new random tree /// 3. calculate semantic of old and new subtree (or of the closest parent) /// 4. do mutation if semantically different /// 5. retry until a certain number of tries is reached /// /// if no mutation has happened, do random mutation /// </summary> public static void ReplaceSemanticallyDifferentBranch(IRandom random, ISymbolicExpressionTree symbolicExpressionTree, ICFGPythonProblemData problemData, ItemArray <PythonStatementSemantic> semantics, PythonProcess pythonProcess, double timeout, int maxTreeLength, int maxTreeDepth, int maximumSemanticTries) { if (semantics == null || semantics.Length == 0) { ReplaceBranchManipulation.ReplaceRandomBranch(random, symbolicExpressionTree, maxTreeLength, maxTreeDepth); return; } var statementProductionNames = SemanticOperatorHelper.GetSemanticProductionNames(symbolicExpressionTree.Root.Grammar); var variables = problemData.Variables.GetVariableNames().ToList(); string variableSettings = problemData.VariableSettings.Count == 0 ? String.Empty : String.Join(Environment.NewLine, problemData.VariableSettings.Select(x => x.Value)); var allowedSymbols = new List <ISymbol>(); // repeat until a fitting parent and child are found (MAX_TRIES times) int tries = 0; int semanticTries = 0; do { #region find mutation point #pragma warning disable 612, 618 ISymbolicExpressionTreeNode parent = symbolicExpressionTree.Root.IterateNodesPrefix().Skip(1).Where(n => n.SubtreeCount > 0).SelectRandom(random); #pragma warning restore 612, 618 int childIndex = random.Next(parent.SubtreeCount); var child = parent.GetSubtree(childIndex); int maxLength = maxTreeLength - symbolicExpressionTree.Length + child.GetLength(); int maxDepth = maxTreeDepth - symbolicExpressionTree.Root.GetBranchLevel(child); allowedSymbols.Clear(); foreach (var symbol in parent.Grammar.GetAllowedChildSymbols(parent.Symbol, childIndex)) { // check basic properties that the new symbol must have if ((symbol.Name != child.Symbol.Name || symbol.MinimumArity > 0) && symbol.InitialFrequency > 0 && parent.Grammar.GetMinimumExpressionDepth(symbol) <= maxDepth && parent.Grammar.GetMinimumExpressionLength(symbol) <= maxLength) { allowedSymbols.Add(symbol); } } #endregion #region check for semantic difference with a new random tree if (allowedSymbols.Count > 0) { if (semanticTries <= maximumSemanticTries) { // do semantic mutation #region calculate original json output ISymbolicExpressionTreeNode statement = SemanticOperatorHelper.GetStatementNode(child, statementProductionNames); var statementPos0 = symbolicExpressionTree.IterateNodesPrefix().ToList().IndexOf(statement); if (String.IsNullOrEmpty(variableSettings)) { variableSettings = SemanticOperatorHelper.SemanticToPythonVariableSettings(semantics.First(x => x.TreeNodePrefixPos == statementPos0).Before, problemData.Variables.GetVariableTypes()); } var jsonOriginal = SemanticOperatorHelper.EvaluateStatementNode(statement, pythonProcess, random, problemData, variables, variableSettings, timeout); #endregion var seedNode = GenerateAndInsertNewSubtree(random, parent, allowedSymbols, childIndex, maxLength, maxDepth); #region calculate new json output JObject jsonReplaced; if (child == statement) { // child is executable, so is the new child jsonReplaced = SemanticOperatorHelper.EvaluateStatementNode(seedNode, pythonProcess, random, problemData, variables, variableSettings, timeout); } else { jsonReplaced = SemanticOperatorHelper.EvaluateStatementNode(statement, pythonProcess, random, problemData, variables, variableSettings, timeout); } if (JToken.EqualityComparer.Equals(jsonOriginal, jsonReplaced)) { // semantically equivalent. undo mutation parent.RemoveSubtree(childIndex); parent.InsertSubtree(childIndex, child); allowedSymbols.Clear(); } else { Console.WriteLine("never happens?"); } if (problemData.VariableSettings.Count == 0) { // reset variableSettings variableSettings = String.Empty; } semanticTries++; #endregion } else { // do random mutation GenerateAndInsertNewSubtree(random, parent, allowedSymbols, childIndex, maxLength, maxDepth); } } #endregion tries++; } while (tries < MAX_TRIES && allowedSymbols.Count == 0 && semanticTries <= maximumSemanticTries); }
public override void ReplaceBranch(IRandom random, ISymbolicExpressionTree symbolicExpressionTree, ICFGPythonProblemData problemData, ItemArray <PythonStatementSemantic> semantics, PythonProcess pythonProcess, double timeout, int maxTreeLength, int maxTreeDepth, int maximumSemanticTries) { if (semantics == null || semantics.Length == 0) { ReplaceBranchManipulation.ReplaceRandomBranch(random, symbolicExpressionTree, maxTreeLength, maxTreeDepth); SemanticallyEquivalentMutationParameter.ActualValue = new IntValue(NoSemantics); MutationTypeParameter.ActualValue = new IntValue(RandomMutation); return; } var statementProductionNames = SemanticOperatorHelper.GetSemanticProductionNames(symbolicExpressionTree.Root.Grammar); var variables = problemData.Variables.GetVariableNames().ToList(); string variableSettings = problemData.VariableSettings.Count == 0 ? String.Empty : String.Join(Environment.NewLine, problemData.VariableSettings.Select(x => x.Value)); var allowedSymbols = new List <ISymbol>(); // repeat until a fitting parent and child are found (MAX_TRIES times) int tries = 0; int semanticTries = 0; List <JObject> saveOriginalSemantics = null; List <JObject> saveReplaceSemantics = null; List <Tuple <ISymbolicExpressionTreeNode, ISymbolicExpressionTreeNode, int> > possibleChildren = null; // Item1 = parent, Item2 = seedNode, Item3 = childIndex if (UsesAdditionalSemanticMeasure()) { saveOriginalSemantics = new List <JObject>(semanticTries); saveReplaceSemantics = new List <JObject>(semanticTries); possibleChildren = new List <Tuple <ISymbolicExpressionTreeNode, ISymbolicExpressionTreeNode, int> >(semanticTries); } bool success = false; do { #region find mutation point #pragma warning disable 612, 618 ISymbolicExpressionTreeNode parent = symbolicExpressionTree.Root.IterateNodesPrefix().Skip(1).Where(n => n.SubtreeCount > 0).SelectRandom(random); #pragma warning restore 612, 618 int childIndex = random.Next(parent.SubtreeCount); var child = parent.GetSubtree(childIndex); int maxLength = maxTreeLength - symbolicExpressionTree.Length + child.GetLength(); int maxDepth = maxTreeDepth - symbolicExpressionTree.Root.GetBranchLevel(child); allowedSymbols.Clear(); foreach (var symbol in parent.Grammar.GetAllowedChildSymbols(parent.Symbol, childIndex)) { // check basic properties that the new symbol must have if ((symbol.Name != child.Symbol.Name || symbol.MinimumArity > 0) && symbol.InitialFrequency > 0 && parent.Grammar.GetMinimumExpressionDepth(symbol) <= maxDepth && parent.Grammar.GetMinimumExpressionLength(symbol) <= maxLength) { allowedSymbols.Add(symbol); } } #endregion #region check for semantic difference with a new random tree if (allowedSymbols.Count > 0) { if (semanticTries <= maximumSemanticTries) { // do semantic mutation #region calculate original json output ISymbolicExpressionTreeNode statement = SemanticOperatorHelper.GetStatementNode(child, statementProductionNames); var statementPos0 = symbolicExpressionTree.IterateNodesPrefix().ToList().IndexOf(statement); PythonStatementSemantic curSemantics = null; if (String.IsNullOrEmpty(variableSettings)) { curSemantics = semantics.First(x => x.TreeNodePrefixPos == statementPos0); variableSettings = SemanticOperatorHelper.SemanticToPythonVariableSettings(curSemantics.Before, problemData.Variables.GetVariableTypes()); } var jsonOriginal = SemanticOperatorHelper.EvaluateStatementNode(statement, pythonProcess, random, problemData, variables, variableSettings, timeout); // compare jsonOriginal to semantic after! Maybe avoid additional evaluation. #endregion var seedNode = GenerateAndInsertNewSubtree(random, parent, allowedSymbols, childIndex, maxLength, maxDepth); #region calculate new json output JObject jsonReplaced; if (child == statement) { // child is executable, so is the new child jsonReplaced = SemanticOperatorHelper.EvaluateStatementNode(seedNode, pythonProcess, random, problemData, variables, variableSettings, timeout); } else { jsonReplaced = SemanticOperatorHelper.EvaluateStatementNode(statement, pythonProcess, random, problemData, variables, variableSettings, timeout); } var exception = jsonOriginal["exception"] != null || jsonReplaced["exception"] != null; if (exception) { if (jsonOriginal["exception"] != null) { MutationExceptionsParameter.ActualValue.Add(new StringValue(jsonOriginal["exception"].ToString())); } if (jsonReplaced["exception"] != null) { MutationExceptionsParameter.ActualValue.Add(new StringValue(jsonReplaced["exception"].ToString())); } } if (curSemantics != null && !exception) { jsonOriginal = PythonSemanticComparer.ReplaceNotExecutedCases(jsonOriginal, curSemantics.Before, curSemantics.ExecutedCases); jsonReplaced = PythonSemanticComparer.ReplaceNotExecutedCases(jsonReplaced, curSemantics.Before, curSemantics.ExecutedCases); jsonOriginal = PythonSemanticComparer.ProduceDifference(jsonOriginal, curSemantics.Before); jsonReplaced = PythonSemanticComparer.ProduceDifference(jsonReplaced, curSemantics.Before); } if (!exception && SemanticMeasure(jsonOriginal, jsonReplaced)) { success = true; SemanticallyEquivalentMutationParameter.ActualValue = new IntValue(Different); TypeSelectedForSimilarityParameter.ActualValue = new StringValue("First Semantic"); MutationTypeParameter.ActualValue = new IntValue(SemanticMutation); } else { // undo mutation parent.RemoveSubtree(childIndex); parent.InsertSubtree(childIndex, child); allowedSymbols.Clear(); if (!exception && UsesAdditionalSemanticMeasure()) { saveOriginalSemantics.Add(jsonOriginal); saveReplaceSemantics.Add(jsonReplaced); possibleChildren.Add(new Tuple <ISymbolicExpressionTreeNode, ISymbolicExpressionTreeNode, int>(parent, seedNode, childIndex)); } } if (problemData.VariableSettings.Count == 0) { // reset variableSettings variableSettings = String.Empty; } semanticTries++; #endregion #region try second semantic comparison if (!success && semanticTries >= maximumSemanticTries && UsesAdditionalSemanticMeasure()) { for (int index = 0; index < saveOriginalSemantics.Count; index++) { if (AdditionalSemanticMeasure(saveOriginalSemantics[index], saveReplaceSemantics[index])) { var mutation = possibleChildren[index]; mutation.Item1.RemoveSubtree(mutation.Item3); mutation.Item1.InsertSubtree(mutation.Item3, mutation.Item2); success = true; SemanticallyEquivalentMutationParameter.ActualValue = new IntValue(Different); TypeSelectedForSimilarityParameter.ActualValue = new StringValue("Second Semantic"); MutationTypeParameter.ActualValue = new IntValue(SemanticMutation); break; } } } #endregion } else { // do random mutation #region calculate original json output ISymbolicExpressionTreeNode statement = SemanticOperatorHelper.GetStatementNode(child, statementProductionNames); var statementPos0 = symbolicExpressionTree.IterateNodesPrefix().ToList().IndexOf(statement); if (String.IsNullOrEmpty(variableSettings)) { variableSettings = SemanticOperatorHelper.SemanticToPythonVariableSettings(semantics.First(x => x.TreeNodePrefixPos == statementPos0).Before, problemData.Variables.GetVariableTypes()); } var jsonOriginal = SemanticOperatorHelper.EvaluateStatementNode(statement, pythonProcess, random, problemData, variables, variableSettings, timeout); #endregion var seedNode = GenerateAndInsertNewSubtree(random, parent, allowedSymbols, childIndex, maxLength, maxDepth); JObject jsonReplaced; if (child == statement) { // child is executable, so is the new child jsonReplaced = SemanticOperatorHelper.EvaluateStatementNode(seedNode, pythonProcess, random, problemData, variables, variableSettings, timeout); } else { jsonReplaced = SemanticOperatorHelper.EvaluateStatementNode(statement, pythonProcess, random, problemData, variables, variableSettings, timeout); } if (JToken.EqualityComparer.Equals(jsonOriginal, jsonReplaced)) { SemanticallyEquivalentMutationParameter.ActualValue = new IntValue(Equvivalent); } else { SemanticallyEquivalentMutationParameter.ActualValue = new IntValue(Different); } TypeSelectedForSimilarityParameter.ActualValue = new StringValue("Random Crossover; Reached Max Semantic Tries"); MutationTypeParameter.ActualValue = new IntValue(RandomMutation); success = true; } } #endregion tries++; } while (tries < MAX_TRIES && !success); NumberOfTriesParameter.ActualValue = new IntValue(semanticTries); if (SemanticallyEquivalentMutationParameter.ActualValue == null) { SemanticallyEquivalentMutationParameter.ActualValue = new IntValue(NoMutation); TypeSelectedForSimilarityParameter.ActualValue = new StringValue("No mutation"); MutationTypeParameter.ActualValue = new IntValue(NoMutation); } }
private static void ReplaceWithMinimalTree(IRandom random, ISymbolicExpressionTreeNode root, ISymbolicExpressionTreeNode parent, int childIndex) { // determine possible symbols that will lead to the smallest possible tree var possibleSymbols = (from s in parent.Grammar.GetAllowedChildSymbols(parent.Symbol, childIndex) where s.InitialFrequency > 0.0 group s by parent.Grammar.GetMinimumExpressionLength(s) into g orderby g.Key select g).First().ToList(); var weights = possibleSymbols.Select(x => x.InitialFrequency).ToList(); #pragma warning disable 612, 618 var selectedSymbol = possibleSymbols.SelectRandom(weights, random); #pragma warning restore 612, 618 var newTreeNode = selectedSymbol.CreateTreeNode(); if (newTreeNode.HasLocalParameters) newTreeNode.ResetLocalParameters(random); parent.RemoveSubtree(childIndex); parent.InsertSubtree(childIndex, newTreeNode); var topLevelNode = newTreeNode as SymbolicExpressionTreeTopLevelNode; if (topLevelNode != null) topLevelNode.SetGrammar((ISymbolicExpressionTreeGrammar)root.Grammar.Clone()); for (int i = 0; i < newTreeNode.Grammar.GetMinimumSubtreeCount(newTreeNode.Symbol); i++) { // insert a dummy sub-tree and add the pending extension to the list var dummy = new SymbolicExpressionTreeNode(); newTreeNode.AddSubtree(dummy); // replace the just inserted dummy by recursive application ReplaceWithMinimalTree(random, root, newTreeNode, i); } }
private void SwitchNodeWithReplacementNode(ISymbolicExpressionTreeNode parent, int subTreeIndex) { ISymbolicExpressionTreeNode subTree = parent.GetSubtree(subTreeIndex); if (foldedNodes.ContainsKey(subTree)) { parent.RemoveSubtree(subTreeIndex); var replacementNode = foldedNodes[subTree]; parent.InsertSubtree(subTreeIndex, replacementNode); // exchange key and value foldedNodes.Remove(subTree); foldedNodes.Add(replacementNode, subTree); } }
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); }
private void SwitchNode(ISymbolicExpressionTreeNode root, ISymbolicExpressionTreeNode oldBranch, ISymbolicExpressionTreeNode newBranch) { for (int i = 0; i < root.SubtreeCount; i++) { if (root.GetSubtree(i) == oldBranch) { root.RemoveSubtree(i); root.InsertSubtree(i, newBranch); return; } } }