public override void CalculateImpactAndReplacementValues(ISymbolicDataAnalysisModel model, ISymbolicExpressionTreeNode node,
      IDataAnalysisProblemData problemData, IEnumerable<int> rows, out double impactValue, out double replacementValue, out double newQualityForImpactsCalculation,
      double qualityForImpactsCalculation = Double.NaN) {
      var classificationModel = (ISymbolicClassificationModel)model;
      var classificationProblemData = (IClassificationProblemData)problemData;

      if (double.IsNaN(qualityForImpactsCalculation))
        qualityForImpactsCalculation = CalculateQualityForImpacts(classificationModel, classificationProblemData, rows);

      replacementValue = CalculateReplacementValue(classificationModel, node, classificationProblemData, rows);
      var constantNode = new ConstantTreeNode(new Constant()) { Value = replacementValue };

      var cloner = new Cloner();
      var tempModel = cloner.Clone(classificationModel);
      var tempModelNode = (ISymbolicExpressionTreeNode)cloner.GetClone(node);

      var tempModelParentNode = tempModelNode.Parent;
      int i = tempModelParentNode.IndexOfSubtree(tempModelNode);
      tempModelParentNode.RemoveSubtree(i);
      tempModelParentNode.InsertSubtree(i, constantNode);

      OnlineCalculatorError errorState;
      var dataset = classificationProblemData.Dataset;
      var targetClassValues = dataset.GetDoubleValues(classificationProblemData.TargetVariable, rows);
      var estimatedClassValues = tempModel.GetEstimatedClassValues(dataset, rows);
      newQualityForImpactsCalculation = OnlineAccuracyCalculator.Calculate(targetClassValues, estimatedClassValues, out errorState);
      if (errorState != OnlineCalculatorError.None) newQualityForImpactsCalculation = 0.0;

      impactValue = qualityForImpactsCalculation - newQualityForImpactsCalculation;
    }
コード例 #2
0
    private string FormatRecursively(ISymbolicExpressionTreeNode node, int indentLength, ref int nodeId) {
      // save id of current node
      int currentNodeId = nodeId;
      // increment id for next node
      nodeId++;

      StringBuilder strBuilder = new StringBuilder();
      if (Indent) strBuilder.Append(' ', indentLength);

      // get label for node and map if necessary
      string nodeLabel = node.ToString();
      if (symbolNameMap.ContainsKey(nodeLabel)) {
        nodeLabel = symbolNameMap[nodeLabel];
      }

      strBuilder.Append("node" + currentNodeId + "[label=\"" + nodeLabel + "\"");
      // leaf nodes should have box shape
      if (node.SubtreeCount == 0) {
        strBuilder.AppendLine(", shape=\"box\"];");
      } else {
        strBuilder.AppendLine("];");
      }

      // internal nodes or leaf nodes?
      foreach (ISymbolicExpressionTreeNode subTree in node.Subtrees) {
        // add an edge 
        if (Indent) strBuilder.Append(' ', indentLength);
        strBuilder.AppendLine("node" + currentNodeId + " -- node" + nodeId + ";");
        // format the whole subtree
        strBuilder.Append(FormatRecursively(subTree, indentLength + 2, ref nodeId));
      }

      return strBuilder.ToString();
    }
コード例 #3
0
    public static void Create(IRandom random, ISymbolicExpressionTreeNode seedNode, int maxDepth) {
      // make sure it is possible to create a trees smaller than maxDepth
      if (seedNode.Grammar.GetMinimumExpressionDepth(seedNode.Symbol) > maxDepth)
        throw new ArgumentException("Cannot create trees of depth " + maxDepth + " or smaller because of grammar constraints.", "maxDepth");

      var arity = SampleArity(random, seedNode);
      // throw an exception if the seedNode happens to be a terminal, since in this case we cannot grow a tree
      if (arity <= 0)
        throw new ArgumentException("Cannot grow tree. Seed node shouldn't have arity zero.");

      var allowedSymbols = seedNode.Grammar.AllowedSymbols.Where(s => s.InitialFrequency > 0.0).ToList();

      for (var i = 0; i < arity; i++) {
        var possibleSymbols = allowedSymbols.Where(s => seedNode.Grammar.IsAllowedChildSymbol(seedNode.Symbol, s, i)).ToList();
        var weights = possibleSymbols.Select(s => s.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);
        seedNode.AddSubtree(tree);
      }

      // Only iterate over the non-terminal nodes (those which have arity > 0)
      // Start from depth 2 since the first two levels are formed by the rootNode and the seedNode
      foreach (var subTree in seedNode.Subtrees)
        if (subTree.Grammar.GetMaximumSubtreeCount(subTree.Symbol) > 0)
          RecursiveCreate(random, subTree, 2, maxDepth);
    }
コード例 #4
0
    /// <summary>
    /// Genotype-to-Phenotype mapper (iterative breath-first approach, by using a queue -> FIFO).
    /// </summary>
    /// <param name="startNode">first node of the tree with arity 1</param>
    /// <param name="genotype">integer vector, which should be mapped to a tree</param>
    /// <param name="grammar">grammar to determine the allowed child symbols for each node</param>
    /// <param name="maxSubtreeCount">maximum allowed subtrees (= number of used genomes)</param>
    /// <param name="random">random number generator</param>
    private void MapBreathFirstIteratively(ISymbolicExpressionTreeNode startNode,
                                          IntegerVector genotype,
                                          ISymbolicExpressionGrammar grammar,
                                          int maxSubtreeCount, IRandom random) {

      Queue<Tuple<ISymbolicExpressionTreeNode, int>> queue
        = new Queue<Tuple<ISymbolicExpressionTreeNode, int>>(); // tuples of <node, arity>

      int genotypeIndex = 0;
      queue.Enqueue(new Tuple<ISymbolicExpressionTreeNode, int>(startNode, 1));

      while (queue.Count > 0) {

        Tuple<ISymbolicExpressionTreeNode, int> current = queue.Dequeue();

        // foreach subtree of the current node, create a new node and enqueue it, if it is no terminal node
        for (int i = 0; i < current.Item2; ++i) {

          if (genotypeIndex >= maxSubtreeCount) {
            // if all genomes were used, only add terminal nodes to the remaining subtrees
            current.Item1.AddSubtree(GetRandomTerminalNode(current.Item1, grammar, random));
          } else {
            var newNode = GetNewChildNode(current.Item1, genotype, grammar, genotypeIndex, random);
            int arity = SampleArity(random, newNode, grammar);

            current.Item1.AddSubtree(newNode);
            genotypeIndex++;
            if (arity > 0) {
              // new node has subtrees so enqueue the node 
              queue.Enqueue(new Tuple<ISymbolicExpressionTreeNode, int>(newNode, arity));
            }
          }
        }
      }
    }
 private void FormatRecursively(ISymbolicExpressionTreeNode node, StringBuilder strBuilder) {
   // TODO: adapt to interpreter semantics. The HL interpreter also allows Boolean operations on reals
   if (node.Subtrees.Any()) {
     if (node.Symbol is Addition) {
       FormatOperator(node, "+", strBuilder);
     } else if (node.Symbol is And) {
       FormatOperator(node, "&&", strBuilder);
     } else if (node.Symbol is Average) {
       FormatFunction(node, "Average", strBuilder);
     } else if (node.Symbol is Cosine) {
       FormatFunction(node, "Math.Cos", strBuilder);
     } else if (node.Symbol is Division) {
       FormatDivision(node, strBuilder);
     } else if (node.Symbol is Exponential) {
       FormatFunction(node, "Math.Exp", strBuilder);
     } else if (node.Symbol is GreaterThan) {
       FormatOperator(node, ">", strBuilder);
     } else if (node.Symbol is IfThenElse) {
       FormatFunction(node, "EvaluateIf", strBuilder);
     } else if (node.Symbol is LessThan) {
       FormatOperator(node, "<", strBuilder);
     } else if (node.Symbol is Logarithm) {
       FormatFunction(node, "Math.Log", strBuilder);
     } else if (node.Symbol is Multiplication) {
       FormatOperator(node, "*", strBuilder);
     } else if (node.Symbol is Not) {
       FormatOperator(node, "!", strBuilder);
     } else if (node.Symbol is Or) {
       FormatOperator(node, "||", strBuilder);
     } else if (node.Symbol is Xor) {
       FormatOperator(node, "^", strBuilder);
     } else if (node.Symbol is Sine) {
       FormatFunction(node, "Math.Sin", strBuilder);
     } else if (node.Symbol is Subtraction) {
       FormatSubtraction(node, strBuilder);
     } else if (node.Symbol is Tangent) {
       FormatFunction(node, "Math.Tan", strBuilder);
     } else if (node.Symbol is Square) {
       FormatSquare(node, strBuilder);
     } else if (node.Symbol is SquareRoot) {
       FormatFunction(node, "Math.Sqrt", strBuilder);
     } else if (node.Symbol is Power) {
       FormatFunction(node, "Math.Pow", strBuilder);
     } else if (node.Symbol is Root) {
       FormatRoot(node, strBuilder);
     } else {
       throw new NotSupportedException("Formatting of symbol: " + node.Symbol + " not supported for C# symbolic expression tree formatter.");
     }
   } else {
     if (node is VariableTreeNode) {
       var varNode = node as VariableTreeNode;
       strBuilder.AppendFormat("{0} * {1}", varNode.VariableName, varNode.Weight.ToString("g17", CultureInfo.InvariantCulture));
     } else if (node is ConstantTreeNode) {
       var constNode = node as ConstantTreeNode;
       strBuilder.Append(constNode.Value.ToString("g17", CultureInfo.InvariantCulture));
     } else {
       throw new NotSupportedException("Formatting of symbol: " + node.Symbol + " not supported for C# symbolic expression tree formatter.");
     }
   }
 }
 public string FormatOnlyExpression(ISymbolicExpressionTreeNode expressionNode) {
   var stringBuilder = new StringBuilder();
   stringBuilder.AppendLine("  for " + CurrentIndexVariable + " = 1:1:rows");
   stringBuilder.AppendLine("    estimated(" + CurrentIndexVariable + ") = " + FormatRecursively(expressionNode.GetSubtree(0)) + ";");
   stringBuilder.AppendLine("  end;");
   return stringBuilder.ToString();
 }
 private static string FormatRecursively(ISymbolicExpressionTreeNode node) {
   StringBuilder strBuilder = new StringBuilder();
   if (node.Subtrees.Count() > 0) {
     // node
     var symbol = node.Symbol as CFGSymbol;
     if (symbol != null) {
       var partsEnumerator = symbol.GetTerminalParts().GetEnumerator();
       var subtreeEnumerator = node.Subtrees.GetEnumerator();
       while (partsEnumerator.MoveNext() && subtreeEnumerator.MoveNext()) {
         strBuilder.Append(partsEnumerator.Current);
         strBuilder.Append(FormatRecursively(subtreeEnumerator.Current));
       }
       strBuilder.Append(partsEnumerator.Current);
     } else {
       // ProgramRoot or StartSymbol
       foreach (var subtree in node.Subtrees) {
         strBuilder.Append(FormatRecursively(subtree));
       }
     }
   } else {
     // leaf
     var symbol = node.Symbol as CFGSymbol;
     if (symbol != null) {
       var parts = symbol.GetTerminalParts();
       strBuilder.Append(parts.First());
     }
   }
   return strBuilder.ToString();
 }
 public static void RenderNode(TextWriter writer, ISymbolicExpressionTreeNode node, string prefix) {
   string label = node.ToString();
   writer.Write(label);
   if (node.SubtreeCount > 0) {
     var padding = prefix + new string(' ', label.Length);
     for (int i = 0; i != node.SubtreeCount; ++i) {
       char connector, extender = ' ';
       if (i == 0) {
         if (node.SubtreeCount > 1) {
           connector = RenderChars.JunctionDown;
           extender = RenderChars.VerticalLine;
         } else {
           connector = RenderChars.HorizontalLine;
           extender = ' ';
         }
       } else {
         writer.Write(padding);
         if (i == node.SubtreeCount - 1) {
           connector = RenderChars.CornerRight;
           extender = ' ';
         } else {
           connector = RenderChars.JunctionRight;
           extender = RenderChars.VerticalLine;
         }
       }
       writer.Write(string.Concat(connector, RenderChars.HorizontalLine));
       var newPrefix = string.Concat(padding, extender, ' ');
       RenderNode(writer, node.GetSubtree(i), newPrefix);
     }
   } else
     writer.WriteLine();
 }
 private string FormatRecursively(ISymbolicExpressionTreeNode node, int indentLength) {
   StringBuilder strBuilder = new StringBuilder();
   if (Indent) strBuilder.Append(' ', indentLength);
   if (node.Subtrees.Count() > 0) { // internal node
     strBuilder.Append("(");
     if (node.Symbol is Addition) {
       strBuilder.AppendLine("+");
     } else if (node.Symbol is And) {
       strBuilder.AppendLine("&&");
     } else if (node.Symbol is Average) {
       strBuilder.AppendLine("avg");
     } else if (node.Symbol is Cosine) {
       strBuilder.AppendLine("cos");
     } else if (node.Symbol is Division) {
       strBuilder.AppendLine("/");
     } else if (node.Symbol is Exponential) {
       strBuilder.AppendLine("exp");
     } else if (node.Symbol is GreaterThan) {
       strBuilder.AppendLine(">");
     } else if (node.Symbol is IfThenElse) {
       strBuilder.AppendLine("if");
     } else if (node.Symbol is LessThan) {
       strBuilder.AppendLine("<");
     } else if (node.Symbol is Logarithm) {
       strBuilder.AppendLine("ln");
     } else if (node.Symbol is Multiplication) {
       strBuilder.AppendLine("*");
     } else if (node.Symbol is Not) {
       strBuilder.AppendLine("!");
     } else if (node.Symbol is Or) {
       strBuilder.AppendLine("||");
     } else if (node.Symbol is Sine) {
       strBuilder.AppendLine("sin");
     } else if (node.Symbol is Subtraction) {
       strBuilder.AppendLine("-");
     } else if (node.Symbol is Tangent) {
       strBuilder.AppendLine("tan");
     } else {
       throw new NotSupportedException("Formatting of symbol: " + node.Symbol + " not supported for external evaluation.");
     }
     // each subtree expression on a new line
     // and closing ')' also on new line
     foreach (var subtree in node.Subtrees) {
       strBuilder.AppendLine(FormatRecursively(subtree, indentLength + 2));
     }
     if (Indent) strBuilder.Append(' ', indentLength);
     strBuilder.Append(")");
   } else {
     if (node is VariableTreeNode) {
       var varNode = node as VariableTreeNode;
       strBuilder.AppendFormat("(* {0} {1})", varNode.VariableName, varNode.Weight.ToString("g17", CultureInfo.InvariantCulture));
     } else if (node is ConstantTreeNode) {
       var constNode = node as ConstantTreeNode;
       strBuilder.Append(constNode.Value.ToString("g17", CultureInfo.InvariantCulture));
     } else {
       throw new NotSupportedException("Formatting of symbol: " + node.Symbol + " not supported for external evaluation.");
     }
   }
   return strBuilder.ToString();
 }
コード例 #10
0
    public static int CompareNodes(ISymbolicExpressionTreeNode a, ISymbolicExpressionTreeNode b) {
      var ta = a as SymbolicExpressionTreeTerminalNode;
      var tb = b as SymbolicExpressionTreeTerminalNode;

      if (ta == null)
        return tb == null ? String.CompareOrdinal(a.Symbol.Name, b.Symbol.Name) : -1;

      if (tb == null)
        return 1;

      // at this point we know a and b are both terminals
      var va = a as VariableTreeNode;
      var vb = b as VariableTreeNode;

      if (va != null)
        return vb == null ? -1 : CompareVariables(va, vb);

      if (vb != null)
        return 1;

      // at this point we know a and b are not variables
      var ca = a as ConstantTreeNode;
      var cb = b as ConstantTreeNode;

      if (ca != null && cb != null)
        return ca.Value.CompareTo(cb.Value);

      // for other unknown terminal types, compare strings
      return string.CompareOrdinal(a.ToString(), b.ToString());
    }
    public VariableNodeEditDialog(ISymbolicExpressionTreeNode node) {
      InitializeComponent();
      oldValueTextBox.TabStop = false; // cannot receive focus using tab key

      NewNode = (VariableTreeNode)node; // will throw an invalid cast exception if node is not of the correct type
      InitializeFields();
    }
コード例 #12
0
    public static IEnumerable<ISymbolicExpressionTreeNode> FindMatches(ISymbolicExpressionTreeNode root, ISymbolicExpressionTreeNode subtree, SymbolicExpressionTreeNodeEqualityComparer comp) {
      var fragmentLength = subtree.GetLength();
      // below, we use ">=" for Match(n, subtree, comp) >= fragmentLength because in case of relaxed conditions, 
      // we can have multiple matches of the same node

      return root.IterateNodesBreadth().Where(n => n.GetLength() >= fragmentLength && Match(n, subtree, comp) == fragmentLength);
    }
コード例 #13
0
        public static string InterpretChild(ISymbolicExpressionTreeNode node)
        {
            if (node.SubtreeCount != 1)
            {
                throw new ArgumentException(string.Format("Expected exactly one child in {0}.", node.Symbol), "node");
            }

            return(Interpret(node.GetSubtree(0)));
        }
        /// <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;
            }
        }
コード例 #15
0
        public string FormatOnlyExpression(ISymbolicExpressionTreeNode expressionNode)
        {
            var stringBuilder = new StringBuilder();

            stringBuilder.AppendLine("  for " + CurrentIndexVariable + " = 1:1:rows");
            stringBuilder.AppendLine("    estimated(" + CurrentIndexVariable + ") = " + FormatRecursively(expressionNode.GetSubtree(0)) + ";");
            stringBuilder.AppendLine("  end;");
            return(stringBuilder.ToString());
        }
コード例 #16
0
        public static string InterpretFunc1(string functionId, ISymbolicExpressionTreeNode node)
        {
            if (node.SubtreeCount != 1)
            {
                throw new ArgumentException(string.Format("Expected 1 child in {0}.", node.Symbol.Name), "node");
            }

            return(string.Format("{0}({1})", functionId, Interpret(node.GetSubtree(0))));
        }
コード例 #17
0
        // version 1
        // only use primary cut point
        private void SelectBranchFromNodes1(ISymbolicExpressionTreeNode statementNode, IList <CutPoint> crossoverPoints0, IList <IEnumerable <ISymbolicExpressionTreeNode> > allowedBranchesPerCutpoint, IRandom random, List <string> variables, string variableSettings, ICFGPythonProblemData problemData, out ISymbolicExpressionTreeNode selectedBranch, out CutPoint selectedCutPoint)
        {
            var jsonOutput = new Dictionary <ISymbolicExpressionTreeNode, JObject>();

            var primaryCutPoint = crossoverPoints0[0];

            primaryCutPoint.Parent.RemoveSubtree(primaryCutPoint.ChildIndex); // removes parent from child
            for (int i = 0; i < crossoverPoints0.Count; i++)
            {
                var cutPoint = crossoverPoints0[i];
                primaryCutPoint.Parent.InsertSubtree(primaryCutPoint.ChildIndex, cutPoint.Child); // this will affect cutPoint.Parent
                var jsonCur = SemanticOperatorHelper.EvaluateStatementNode(statementNode, PyProcess, random, problemData, variables, variableSettings, Timeout);
                primaryCutPoint.Parent.RemoveSubtree(primaryCutPoint.ChildIndex);                 // removes intermediate parent from node
                cutPoint.Child.Parent = cutPoint.Parent;                                          // restore parent

                if (!String.IsNullOrWhiteSpace((string)jsonCur["exception"]))
                {
                    continue;
                }
                foreach (var possibleBranch in allowedBranchesPerCutpoint[i])
                {
                    JObject jsonPossibleBranch;
                    if (!jsonOutput.ContainsKey(possibleBranch))
                    {
                        var parent = possibleBranch.Parent;                                               // save parent
                        primaryCutPoint.Parent.InsertSubtree(primaryCutPoint.ChildIndex, possibleBranch); // this will affect node.Parent
                        jsonPossibleBranch = SemanticOperatorHelper.EvaluateStatementNode(statementNode, PyProcess, random, problemData, variables, variableSettings, Timeout);
                        primaryCutPoint.Parent.RemoveSubtree(primaryCutPoint.ChildIndex);                 // removes intermediate parent from node
                        possibleBranch.Parent = parent;                                                   // restore parent
                        jsonOutput.Add(possibleBranch, jsonPossibleBranch);
                    }
                    else
                    {
                        jsonPossibleBranch = jsonOutput[possibleBranch];
                    }

                    if (!String.IsNullOrWhiteSpace((string)jsonPossibleBranch["exception"]))
                    {
                        continue;
                    }

                    if (!JToken.EqualityComparer.Equals(jsonCur, jsonPossibleBranch))
                    {
                        primaryCutPoint.Parent.InsertSubtree(primaryCutPoint.ChildIndex, primaryCutPoint.Child); // restore primaryCutPoint
                        selectedBranch   = possibleBranch;
                        selectedCutPoint = cutPoint;
                        return;
                    }
                }
            }

            primaryCutPoint.Parent.InsertSubtree(primaryCutPoint.ChildIndex, primaryCutPoint.Child); // restore primaryCutPoint
            // no difference was found with any comparison, select random
            selectedBranch   = allowedBranchesPerCutpoint[0].SampleRandom(random);
            selectedCutPoint = crossoverPoints0[0];
        }
コード例 #18
0
        /// <summary>
        /// Takes two parent individuals P0 and P1.
        /// Randomly choose a node i from the first parent, then test all nodes j from the second parent to determine the best child that would be obtained by swapping i for j.
        /// </summary>
        public static ISymbolicExpressionTree Cross(IRandom random, ISymbolicExpressionTree parent0, ISymbolicExpressionTree parent1, IExecutionContext context,
                                                    ISymbolicDataAnalysisSingleObjectiveEvaluator <T> evaluator, T problemData, List <int> rows, int maxDepth, int maxLength)
        {
            var crossoverPoints0 = new List <CutPoint>();

            parent0.Root.ForEachNodePostfix((n) => {
                if (n.Parent != null && n.Parent != parent0.Root)
                {
                    crossoverPoints0.Add(new CutPoint(n.Parent, n));
                }
            });

            CutPoint crossoverPoint0 = crossoverPoints0.SampleRandom(random);
            int      level           = parent0.Root.GetBranchLevel(crossoverPoint0.Child);
            int      length          = parent0.Root.GetLength() - crossoverPoint0.Child.GetLength();

            var allowedBranches = new List <ISymbolicExpressionTreeNode>();

            parent1.Root.ForEachNodePostfix((n) => {
                if (n.Parent != null && n.Parent != parent1.Root)
                {
                    if (n.GetDepth() + level <= maxDepth && n.GetLength() + length <= maxLength && crossoverPoint0.IsMatchingPointType(n))
                    {
                        allowedBranches.Add(n);
                    }
                }
            });

            if (allowedBranches.Count == 0)
            {
                return(parent0);
            }

            // create symbols in order to improvize an ad-hoc tree so that the child can be evaluated
            ISymbolicExpressionTreeNode selectedBranch = null;
            var nodeQualities = new List <Tuple <ISymbolicExpressionTreeNode, double> >();
            var originalChild = crossoverPoint0.Child;

            foreach (var node in allowedBranches)
            {
                var parent = node.Parent;
                Swap(crossoverPoint0, node); // the swap will set the nodes parent to crossoverPoint0.Parent
                IExecutionContext childContext = new ExecutionContext(context, evaluator, context.Scope);
                double            quality      = evaluator.Evaluate(childContext, parent0, problemData, rows);
                Swap(crossoverPoint0, originalChild); // swap the child back (so that the next swap will not affect the currently swapped node from parent1)
                nodeQualities.Add(new Tuple <ISymbolicExpressionTreeNode, double>(node, quality));
                node.Parent = parent;                 // restore correct parent
            }

            nodeQualities.Sort((a, b) => a.Item2.CompareTo(b.Item2));
            selectedBranch = evaluator.Maximization ? nodeQualities.Last().Item1 : nodeQualities.First().Item1;

            // swap the node that would create the best offspring
            Swap(crossoverPoint0, selectedBranch);
            return(parent0);
        }
        public Dictionary <ISymbolicExpressionTreeNode, ISymbolicExpressionTreeNode> ComputeBottomUpMapping(ISymbolicExpressionTreeNode n1, ISymbolicExpressionTreeNode n2)
        {
            var comparer       = new SymbolicExpressionTreeNodeComparer(); // use a node comparer because it's faster than calling node.ToString() (strings are expensive) and comparing strings
            var compactedGraph = Compact(n1, n2);

            var forwardMap = new Dictionary <ISymbolicExpressionTreeNode, ISymbolicExpressionTreeNode>(); // nodes of t1 => nodes of t2
            var reverseMap = new Dictionary <ISymbolicExpressionTreeNode, ISymbolicExpressionTreeNode>(); // nodes of t2 => nodes of t1

            // visit nodes in order of decreasing height to ensure correct mapping
            var nodes1 = n1.IterateNodesPrefix().OrderByDescending(x => x.GetDepth()).ToList();
            var nodes2 = n2.IterateNodesPrefix().ToList();

            for (int i = 0; i < nodes1.Count; ++i)
            {
                var v = nodes1[i];
                if (forwardMap.ContainsKey(v))
                {
                    continue;
                }
                var kv = compactedGraph[v];
                ISymbolicExpressionTreeNode w = null;
                for (int j = 0; j < nodes2.Count; ++j)
                {
                    var t = nodes2[j];
                    if (reverseMap.ContainsKey(t) || compactedGraph[t] != kv)
                    {
                        continue;
                    }
                    w = t;
                    break;
                }
                if (w == null)
                {
                    continue;
                }

                // at this point we know that v and w are isomorphic, however, the mapping cannot be done directly
                // (as in the paper) because the trees are unordered (subtree order might differ). the solution is
                // to sort subtrees from under commutative labels (this will work because the subtrees are isomorphic!)
                // while iterating over the two subtrees
                var vv  = IterateBreadthOrdered(v, comparer).ToList();
                var ww  = IterateBreadthOrdered(w, comparer).ToList();
                int len = Math.Min(vv.Count, ww.Count);
                for (int j = 0; j < len; ++j)
                {
                    var s = vv[j];
                    var t = ww[j];
                    Debug.Assert(!reverseMap.ContainsKey(t));

                    forwardMap[s] = t;
                    reverseMap[t] = s;
                }
            }

            return(forwardMap);
        }
コード例 #20
0
    private void SwapVariableWithTree(VariableTreeNode variableNode, ISymbolicExpressionTreeNode treeNode) {
      var parent = variableNode.Parent;
      int index = parent.IndexOfSubtree(variableNode);
      parent.RemoveSubtree(index);

      if (!variableNode.Weight.IsAlmost(1.0))
        treeNode = CreateNodeFromWeight(treeNode, variableNode);

      parent.InsertSubtree(index, treeNode);
    }
コード例 #21
0
        public static ISymbolicExpressionTreeNode GetStatementNode(ISymbolicExpressionTreeNode parent, IEnumerable <string> statementProductionNames)
        {
            ISymbolicExpressionTreeNode statement = parent;

            while (statement != null && !statementProductionNames.Contains(statement.Symbol.Name))
            {
                statement = statement.Parent;
            }
            return(statement);
        }
コード例 #22
0
 public void SortSubtrees(ISymbolicExpressionTreeNode node) {
   if (node.SubtreeCount == 0) return;
   var subtrees = node.Subtrees as List<ISymbolicExpressionTreeNode> ?? node.Subtrees.ToList();
   if (IsSymmetric(node.Symbol)) {
     var comparer = new SymbolicExpressionTreeNodeComparer();
     subtrees.Sort(comparer);
   }
   foreach (var s in subtrees)
     SortSubtrees(s);
 }
コード例 #23
0
        public static double ComputeSimilarity(ISymbolicExpressionTreeNode t1, ISymbolicExpressionTreeNode t2, bool simplify = false, bool strict = false)
        {
            var lh = t1.Hash(simplify, strict);
            var rh = t2.Hash(simplify, strict);

            Array.Sort(lh);
            Array.Sort(rh);

            return(ComputeSimilarity(lh, rh));
        }
コード例 #24
0
        private ISymbolicExpressionTreeNode ParseArgument(Queue <Token> tokens)
        {
            Token argTok = tokens.Dequeue();

            Debug.Assert(argTok.StringValue == "ARG");
            Argument argument = new Argument((int)tokens.Dequeue().DoubleValue);
            ISymbolicExpressionTreeNode argNode = argument.CreateTreeNode();

            return(argNode);
        }
コード例 #25
0
ファイル: Interpreter.cs プロジェクト: lulzzz/HeuristicLab
        public static string InterpretOnBulletMissed(ISymbolicExpressionTreeNode node)
        {
            string code = string.Join(Environment.NewLine, node.Subtrees.Select(Interpret));

            return(string.Format(
                       @"public void onBulletMissed(BulletMissedEvent e) {{
{0}
execute();
}}", code));
        }
コード例 #26
0
 private void FormatIf(ISymbolicExpressionTreeNode node, StringBuilder strBuilder)
 {
     strBuilder.Append("If[Greater[");
     FormatRecursively(node.GetSubtree(0), strBuilder);
     strBuilder.Append(", 0], ");
     FormatRecursively(node.GetSubtree(1), strBuilder);
     strBuilder.Append(", ");
     FormatRecursively(node.GetSubtree(2), strBuilder);
     strBuilder.Append("]");
 }
コード例 #27
0
        private ISymbolicExpressionTreeNode ParseInvoke(Queue <Token> tokens)
        {
            Token invokeTok = tokens.Dequeue();

            Debug.Assert(invokeTok.StringValue == "CALL");
            InvokeFunction invokeSym = new InvokeFunction(tokens.Dequeue().StringValue);
            ISymbolicExpressionTreeNode invokeNode = invokeSym.CreateTreeNode();

            return(invokeNode);
        }
コード例 #28
0
ファイル: Interpreter.cs プロジェクト: lulzzz/HeuristicLab
        public static string InterpretOnBulletHit(ISymbolicExpressionTreeNode node)
        {
            var Prefix = "public void onBulletHit(BulletHitEvent e) {";
            var Suffix =
                @"execute();
}";
            string code = string.Join(Environment.NewLine, node.Subtrees.Select(Interpret));

            return(Prefix + code + Environment.NewLine + Suffix);
        }
コード例 #29
0
        private static int SampleArity(IRandom random, ISymbolicExpressionTreeNode node, int targetLength, int maxDepth)
        {
            // select actualArity randomly with the constraint that the sub-trees in the minimal arity can become large enough
            int minArity = node.Grammar.GetMinimumSubtreeCount(node.Symbol);
            int maxArity = node.Grammar.GetMaximumSubtreeCount(node.Symbol);

            if (maxArity > targetLength)
            {
                maxArity = targetLength;
            }
            if (minArity == maxArity)
            {
                return(minArity);
            }

            // the min number of sub-trees has to be set to a value that is large enough so that the largest possible tree is at least tree length
            // if 1..3 trees are possible and the largest possible first sub-tree is smaller larger than the target length then minArity should be at least 2
            long aggregatedLongestExpressionLength = 0;

            for (int i = 0; i < maxArity; i++)
            {
                aggregatedLongestExpressionLength += (from s in node.Grammar.GetAllowedChildSymbols(node.Symbol, i)
                                                      where s.InitialFrequency > 0.0
                                                      select node.Grammar.GetMaximumExpressionLength(s, maxDepth)).Max();
                if (i > minArity && aggregatedLongestExpressionLength < targetLength)
                {
                    minArity = i + 1;
                }
                else
                {
                    break;
                }
            }

            // the max number of sub-trees has to be set to a value that is small enough so that the smallest possible tree is at most tree length
            // if 1..3 trees are possible and the smallest possible first sub-tree is already larger than the target length then maxArity should be at most 0
            long aggregatedShortestExpressionLength = 0;

            for (int i = 0; i < maxArity; i++)
            {
                aggregatedShortestExpressionLength += (from s in node.Grammar.GetAllowedChildSymbols(node.Symbol, i)
                                                       where s.InitialFrequency > 0.0
                                                       select node.Grammar.GetMinimumExpressionLength(s)).Min();
                if (aggregatedShortestExpressionLength > targetLength)
                {
                    maxArity = i;
                    break;
                }
            }
            if (minArity > maxArity)
            {
                return(-1);
            }
            return(random.Next(minArity, maxArity + 1));
        }
コード例 #30
0
 private void FormatSubtraction(ISymbolicExpressionTreeNode node, StringBuilder strBuilder)
 {
     if (node.SubtreeCount == 1)
     {
         strBuilder.Append("-");
         FormatRecursively(node.GetSubtree(0), strBuilder);
         return;
     }
     //Default case: more than 1 child
     FormatOperator(node, "-", strBuilder);
 }
コード例 #31
0
        private void removeNodeToolStripMenuItem_Click(object sender, EventArgs e)
        {
            var node = currSelected.Content;

            if (node == tempNode)
            {
                tempNode = null;
            }
            ModifyTree(Tree, node.Parent, node, null, removeSubtree: false);
            currSelected = null; // because the currently selected node was just deleted
        }
コード例 #32
0
        public static string InterpretBinaryOperator(string opSy, ISymbolicExpressionTreeNode node)
        {
            if (node.SubtreeCount < 2)
            {
                throw new ArgumentException(string.Format("Expected at least two children in {0}.", node.Symbol), "node");
            }

            string result = string.Join(opSy, node.Subtrees.Select(Interpret));

            return("(" + result + ")");
        }
コード例 #33
0
        public static ulong[] Hash(this ISymbolicExpressionTreeNode node, bool simplify = false, bool strict = false)
        {
            var hashNodes = simplify ? node.MakeNodes(strict).Simplify(HashFunction) : node.MakeNodes(strict).Sort(HashFunction);
            var hashes    = new ulong[hashNodes.Length];

            for (int i = 0; i < hashes.Length; ++i)
            {
                hashes[i] = hashNodes[i].CalculatedHashValue;
            }
            return(hashes);
        }
コード例 #34
0
ファイル: OpCodes.cs プロジェクト: lulzzz/HeuristicLab
 public static byte MapSymbolToOpCode(ISymbolicExpressionTreeNode treeNode)
 {
     if (symbolToOpcode.TryGetValue(treeNode.Symbol.GetType(), out byte opCode))
     {
         return(opCode);
     }
     else
     {
         throw new NotSupportedException("Symbol: " + treeNode.Symbol);
     }
 }
コード例 #35
0
        private ISymbolicExpressionTreeNode CreateNodeFromWeight(ISymbolicExpressionTreeNode transformationTree, VariableTreeNode variableNode)
        {
            var multiplicationNode = new SymbolicExpressionTreeNode(new Multiplication());

            multiplicationNode.AddSubtree(new ConstantTreeNode(new Constant())
            {
                Value = variableNode.Weight
            });
            multiplicationNode.AddSubtree(transformationTree);
            return(multiplicationNode);
        }
コード例 #36
0
        public ISymbolicExpressionTree Parse(string str)
        {
            ISymbolicExpressionTreeNode root  = programRootSymbol.CreateTreeNode();
            ISymbolicExpressionTreeNode start = startSymbol.CreateTreeNode();
            var allTokens = GetAllTokens(str).ToArray();
            ISymbolicExpressionTreeNode mainBranch = ParseS(new Queue <Token>(allTokens));

            // only a main branch was given => insert the main branch into the default tree template
            root.AddSubtree(start);
            start.AddSubtree(mainBranch);
            return(new SymbolicExpressionTree(root));
        }
コード例 #37
0
        private JObject GenerateOriginalJson(CutPoint crossoverPoint0, IEnumerable <string> statementProductionNames, ISymbolicExpressionTree parent0, string variableSettings, ItemArray <PythonStatementSemantic> semantic0, ICFGPythonProblemData problemData, IRandom random, List <string> variables)
        {
            ISymbolicExpressionTreeNode statementOriginal = SemanticOperatorHelper.GetStatementNode(crossoverPoint0.Child, statementProductionNames); // statementOriginal is not always the same as statement
            var statementPos0 = parent0.IterateNodesPrefix().ToList().IndexOf(statementOriginal);

            if (String.IsNullOrEmpty(variableSettings))
            {
                var curSemantics = semantic0.First(x => x.TreeNodePrefixPos == statementPos0);
                variableSettings = SemanticOperatorHelper.SemanticToPythonVariableSettings(curSemantics.Before, problemData.Variables.GetVariableTypes());
            }
            return(SemanticOperatorHelper.EvaluateStatementNode(statementOriginal, PyProcess, random, problemData, variables, variableSettings, Timeout));
        }
コード例 #38
0
        private void removeSubtreeToolStripMenuItem_Click(object sender, EventArgs e)
        {
            var node = currSelected.Content;

            if (node.IterateNodesPostfix().Contains(tempNode))
            {
                tempNode = null;
            }
            ModifyTree(Tree, node.Parent, node, null, removeSubtree: true);
            currSelected = null;      // because the currently selected node was just deleted
            contextMenuStrip.Close(); // avoid display of submenus since the action has already been performed
        }
コード例 #39
0
 private void FormatSubtraction(ISymbolicExpressionTreeNode node, StringBuilder strBuilder)
 {
     strBuilder.Append("Subtract[");
     FormatRecursively(node.GetSubtree(0), strBuilder);
     strBuilder.Append(", Times[-1");
     foreach (var t in node.Subtrees)
     {
         strBuilder.Append(",");
         FormatRecursively(t, strBuilder);
     }
     strBuilder.Append("]]");
 }
 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;
         }
     }
 }
コード例 #41
0
ファイル: Interpreter.cs プロジェクト: lulzzz/HeuristicLab
        public static string InterpretRun(ISymbolicExpressionTreeNode node)
        {
            string code = string.Join(Environment.NewLine, node.Subtrees.Select(Interpret));

            return(string.Format(
                       @"public void run() {{
  setAdjustGunForRobotTurn(true);
  turnRadarRightRadians(Double.POSITIVE_INFINITY);
{0}
  execute();
}}", code));
        }
コード例 #42
0
 private void FormatAverage(ISymbolicExpressionTreeNode node, StringBuilder strBuilder)
 {
     // mean function needs a list of values
     strBuilder.Append("Mean[{");
     FormatRecursively(node.GetSubtree(0), strBuilder);
     for (int i = 1; i < node.SubtreeCount; i++)
     {
         strBuilder.Append(",");
         FormatRecursively(node.GetSubtree(i), strBuilder);
     }
     strBuilder.Append("}]");
 }
コード例 #43
0
        // version 2
        // check the statement node of every cut point in the parent
        // takes longer, but really checks for differences
        private void SelectBranchFromNodes2(IEnumerable <string> statementProductionNames, IList <CutPoint> crossoverPoints0, IList <IEnumerable <ISymbolicExpressionTreeNode> > allowedBranchesPerCutpoint, IRandom random, List <string> variables, string variableSettings, ICFGPythonProblemData problemData, out ISymbolicExpressionTreeNode selectedBranch, out CutPoint selectedCutPoint)
        {
            for (int i = 0; i < crossoverPoints0.Count; i++)
            {
                var cutPoint = crossoverPoints0[i];
                ISymbolicExpressionTreeNode curStatementNode = SemanticOperatorHelper.GetStatementNode(cutPoint.Child, statementProductionNames);
                var jsonCur = SemanticOperatorHelper.EvaluateStatementNode(curStatementNode, PyProcess, random, problemData, variables, variableSettings, Timeout);

                if (!String.IsNullOrWhiteSpace((string)jsonCur["exception"]))
                {
                    continue;
                }
                cutPoint.Parent.RemoveSubtree(cutPoint.ChildIndex); // removes parent from node
                foreach (var possibleBranch in allowedBranchesPerCutpoint[i])
                {
                    JObject jsonPossibleBranch;
                    if (curStatementNode == cutPoint.Child)
                    {
                        // shouldn't actually happen
                        jsonPossibleBranch = SemanticOperatorHelper.EvaluateStatementNode(possibleBranch, PyProcess, random, problemData, variables, variableSettings, Timeout);
                    }
                    else
                    {
                        var parent = possibleBranch.Parent;                                 // save parent
                        cutPoint.Parent.InsertSubtree(cutPoint.ChildIndex, possibleBranch); // this will affect node.Parent
                        jsonPossibleBranch = SemanticOperatorHelper.EvaluateStatementNode(curStatementNode, PyProcess, random, problemData, variables, variableSettings, Timeout);
                        cutPoint.Parent.RemoveSubtree(cutPoint.ChildIndex);                 // removes intermediate parent from node
                        possibleBranch.Parent = parent;                                     // restore parent
                    }

                    if (!String.IsNullOrWhiteSpace((string)jsonPossibleBranch["exception"]))
                    {
                        continue;
                    }
                    if (JToken.EqualityComparer.Equals(jsonCur, jsonPossibleBranch))
                    {
                        continue;
                    }                                                                   // equal json, therefore continue

                    cutPoint.Parent.InsertSubtree(cutPoint.ChildIndex, cutPoint.Child); // restore cutPoint
                    selectedBranch   = possibleBranch;
                    selectedCutPoint = cutPoint;
                    return;
                }
                cutPoint.Parent.InsertSubtree(cutPoint.ChildIndex, cutPoint.Child); // restore cutPoint
            }

            // no difference was found with any comparison, select randomly
            // only select form the first cut point, as the other cut points might not have allowedBranchesPerCutpoint
            selectedBranch   = allowedBranchesPerCutpoint[0].SampleRandom(random);
            selectedCutPoint = crossoverPoints0[0];
        }
コード例 #44
0
        public static void Create(IRandom random, ISymbolicExpressionTreeNode seedNode, int maxDepth)
        {
            // make sure it is possible to create a trees smaller than maxDepth
            if (seedNode.Grammar.GetMinimumExpressionDepth(seedNode.Symbol) > maxDepth)
            {
                throw new ArgumentException("Cannot create trees of depth " + maxDepth + " or smaller because of grammar constraints.", "maxDepth");
            }


            int arity = seedNode.Grammar.GetMaximumSubtreeCount(seedNode.Symbol);

            // Throw an exception if the seedNode happens to be a terminal, since in this case we cannot grow a tree.
            if (arity <= 0)
            {
                throw new ArgumentException("Cannot grow tree. Seed node shouldn't have arity zero.");
            }

            var allowedSymbols = seedNode.Grammar.AllowedSymbols
                                 .Where(s => s.InitialFrequency > 0.0 && seedNode.Grammar.GetMaximumSubtreeCount(s) > 0)
                                 .ToList();

            for (var i = 0; i < arity; i++)
            {
                var possibleSymbols = allowedSymbols
                                      .Where(s => seedNode.Grammar.IsAllowedChildSymbol(seedNode.Symbol, s, i) &&
                                             seedNode.Grammar.GetMinimumExpressionDepth(s) <= maxDepth &&
                                             seedNode.Grammar.GetMaximumExpressionDepth(s) >= maxDepth)
                                      .ToList();
                var weights = possibleSymbols.Select(s => s.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);
                }
                seedNode.AddSubtree(tree);
            }

            // Only iterate over the non-terminal nodes (those which have arity > 0)
            // Start from depth 2 since the first two levels are formed by the rootNode and the seedNode
            foreach (var subTree in seedNode.Subtrees)
            {
                if (subTree.Grammar.GetMaximumSubtreeCount(subTree.Symbol) > 0)
                {
                    RecursiveCreate(random, subTree, 2, maxDepth);
                }
            }
        }
 private static string FormatRecursively(ISymbolicExpressionTreeNode node) {
   StringBuilder strBuilder = new StringBuilder();
   if (node.Subtrees.Count() > 0) {
     // node
     foreach (var subtree in node.Subtrees) {
       strBuilder.Append(FormatRecursively(subtree));
     }
   } else {
     // leaf
     strBuilder.Append(node.ToString());
   }
   return strBuilder.ToString();
 }
コード例 #46
0
 ///<summary>
 /// Finds the longest common subsequence in quadratic time and linear space
 /// Variant of:
 /// D. S. Hirschberg. A linear space algorithm for or computing maximal common subsequences. 1975.
 /// http://dl.acm.org/citation.cfm?id=360861
 /// </summary>
 /// <returns>Number of pairs that were matched</returns>
 public static int Match(ISymbolicExpressionTreeNode a, ISymbolicExpressionTreeNode b, ISymbolicExpressionTreeNodeSimilarityComparer comp) {
   if (!comp.Equals(a, b)) return 0;
   int m = a.SubtreeCount;
   int n = b.SubtreeCount;
   if (m == 0 || n == 0) return 1;
   var matrix = new int[m + 1, n + 1];
   for (int i = 1; i <= m; ++i) {
     var ai = a.GetSubtree(i - 1);
     for (int j = 1; j <= n; ++j) {
       var bj = b.GetSubtree(j - 1);
       int match = Match(ai, bj, comp);
       matrix[i, j] = Math.Max(Math.Max(matrix[i, j - 1], matrix[i - 1, j]), matrix[i - 1, j - 1] + match);
     }
   }
   return matrix[m, n] + 1;
 }
コード例 #47
0
 public static ISymbolicExpressionTreeNode Difference(this ISymbolicExpressionTreeNode node, ISymbolicExpressionTreeNode other) {
   var a = node.IterateNodesPrefix().ToList();
   var b = other.IterateNodesPrefix().ToList();
   var list = new List<ISymbolicExpressionTreeNode>();
   for (int i = 0, j = 0; i < a.Count && j < b.Count; ++i, ++j) {
     var s1 = a[i].ToString();
     var s2 = b[j].ToString();
     if (s1 == s2) continue;
     list.Add(a[i]);
     // skip subtrees since the parents are already different
     i += a[i].SubtreeCount;
     j += b[j].SubtreeCount;
   }
   ISymbolicExpressionTreeNode result = list.Count > 0 ? LowestCommonAncestor(node, list) : null;
   return result;
 }
コード例 #48
0
    /// <summary>
    /// Randomly returns a terminal node for the given <paramref name="parentNode"/>.
    /// (A terminal has got a minimum and maximum arity of 0.)
    /// </summary>
    /// <param name="parentNode">parent node for which a child node is returned randomly</param>
    /// <param name="grammar">grammar to determine the allowed child symbols for parentNode</param>
    /// <param name="random">random number generator</param>
    /// <returns>randomly chosen terminal node with arity 0 or null, if no terminal node exists</returns>
    protected ISymbolicExpressionTreeNode GetRandomTerminalNode(ISymbolicExpressionTreeNode parentNode,
                                                                ISymbolicExpressionGrammar grammar,
                                                                IRandom random) {
      // only select specific symbols, which can be interpreted ...
      var possibleSymbolsList = (from s in grammar.GetAllowedChildSymbols(parentNode.Symbol)
                                 where s.InitialFrequency > 0.0
                                 where s.MaximumArity == 0
                                 where s.MinimumArity == 0
                                 select s).ToList();

      // no terminal node exists for the given parent node
      if (!possibleSymbolsList.Any()) return null;

      var newNode = possibleSymbolsList.SampleRandom(random).CreateTreeNode();
      if (newNode.HasLocalParameters) newNode.ResetLocalParameters(random);
      return newNode;
    }
コード例 #49
0
 private static IEnumerable<Instruction> Compile(ISymbolicExpressionTreeNode branch, Func<ISymbolicExpressionTreeNode, byte> opCodeMapper, IEnumerable<Func<Instruction, Instruction>> postInstructionCompiledHooks) {
   foreach (var node in branch.IterateNodesPrefix()) {
     Instruction instr = new Instruction();
     int subtreesCount = node.SubtreeCount;
     if (subtreesCount > 255) throw new ArgumentException("Number of subtrees is too big (>255)");
     instr.nArguments = (byte)subtreesCount;
     instr.opCode = opCodeMapper(node);
     if (node.Symbol is Argument) {
       var argNode = (ArgumentTreeNode)node;
       instr.data = (ushort)argNode.Symbol.ArgumentIndex;
     }
     instr.dynamicNode = node;
     foreach (var hook in postInstructionCompiledHooks) {
       instr = hook(instr);
     }
     yield return instr;
   }
 }
    protected static double CalculateReplacementValue(ISymbolicExpressionTreeNode node, ISymbolicExpressionTree sourceTree, ISymbolicDataAnalysisExpressionTreeInterpreter interpreter,
      IDataset dataset, IEnumerable<int> rows) {
      //optimization: constant nodes return always the same value
      ConstantTreeNode constantNode = node as ConstantTreeNode;
      if (constantNode != null) return constantNode.Value;

      var rootSymbol = new ProgramRootSymbol().CreateTreeNode();
      var startSymbol = new StartSymbol().CreateTreeNode();
      rootSymbol.AddSubtree(startSymbol);
      startSymbol.AddSubtree((ISymbolicExpressionTreeNode)node.Clone());

      var tempTree = new SymbolicExpressionTree(rootSymbol);
      // clone ADFs of source tree
      for (int i = 1; i < sourceTree.Root.SubtreeCount; i++) {
        tempTree.Root.AddSubtree((ISymbolicExpressionTreeNode)sourceTree.Root.GetSubtree(i).Clone());
      }
      return interpreter.GetSymbolicExpressionTreeValues(tempTree, dataset, rows).Median();
    }
    public Dictionary<ISymbolicExpressionTreeNode, ISymbolicExpressionTreeNode> ComputeBottomUpMapping(ISymbolicExpressionTreeNode n1, ISymbolicExpressionTreeNode n2) {
      var comparer = new SymbolicExpressionTreeNodeComparer(); // use a node comparer because it's faster than calling node.ToString() (strings are expensive) and comparing strings
      var compactedGraph = Compact(n1, n2);

      var forwardMap = new Dictionary<ISymbolicExpressionTreeNode, ISymbolicExpressionTreeNode>(); // nodes of t1 => nodes of t2
      var reverseMap = new Dictionary<ISymbolicExpressionTreeNode, ISymbolicExpressionTreeNode>(); // nodes of t2 => nodes of t1

      // visit nodes in order of decreasing height to ensure correct mapping
      var nodes1 = n1.IterateNodesPrefix().OrderByDescending(x => x.GetDepth()).ToList();
      var nodes2 = n2.IterateNodesPrefix().ToList();
      for (int i = 0; i < nodes1.Count; ++i) {
        var v = nodes1[i];
        if (forwardMap.ContainsKey(v))
          continue;
        var kv = compactedGraph[v];
        ISymbolicExpressionTreeNode w = null;
        for (int j = 0; j < nodes2.Count; ++j) {
          var t = nodes2[j];
          if (reverseMap.ContainsKey(t) || compactedGraph[t] != kv)
            continue;
          w = t;
          break;
        }
        if (w == null) continue;

        // at this point we know that v and w are isomorphic, however, the mapping cannot be done directly
        // (as in the paper) because the trees are unordered (subtree order might differ). the solution is 
        // to sort subtrees from under commutative labels (this will work because the subtrees are isomorphic!)
        // while iterating over the two subtrees
        var vv = IterateBreadthOrdered(v, comparer).ToList();
        var ww = IterateBreadthOrdered(w, comparer).ToList();
        int len = Math.Min(vv.Count, ww.Count);
        for (int j = 0; j < len; ++j) {
          var s = vv[j];
          var t = ww[j];
          Debug.Assert(!reverseMap.ContainsKey(t));

          forwardMap[s] = t;
          reverseMap[t] = s;
        }
      }

      return forwardMap;
    }
    public bool Equals(ISymbolicExpressionTreeNode a, ISymbolicExpressionTreeNode b) {
      if (!(a is SymbolicExpressionTreeTerminalNode))
        // if a and b are non terminal nodes, check equality of symbol names
        return !(b is SymbolicExpressionTreeTerminalNode) && a.Symbol.Name.Equals(b.Symbol.Name);
      var va = a as VariableTreeNode;
      if (va != null) {
        var vb = b as VariableTreeNode;
        if (vb == null) return false;

        return (!MatchVariableNames || va.VariableName.Equals(vb.VariableName)) && (!MatchVariableWeights || va.Weight.Equals(vb.Weight));
      }
      var ca = a as ConstantTreeNode;
      if (ca != null) {
        var cb = b as ConstantTreeNode;
        if (cb == null) return false;
        return (!MatchConstantValues || ca.Value.Equals(cb.Value));
      }
      return false;
    }
 /// <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 string FormatRecursively(ISymbolicExpressionTreeNode node) {
      StringBuilder strBuilder = new StringBuilder();
      currentLag = 0;
      FormatBegin(node, strBuilder);

      if (node.SubtreeCount > 0) {
        strBuilder.Append(FormatRecursively(node.GetSubtree(0)));
      }
      int i = 1;
      foreach (SymbolicExpressionTreeNode subTree in node.Subtrees.Skip(1)) {
        FormatSep(node, strBuilder, i);
        // format the whole subtree
        strBuilder.Append(FormatRecursively(subTree));
        i++;
      }

      FormatEnd(node, strBuilder);

      return strBuilder.ToString();
    }
コード例 #55
0
 private string FormatRecursively(ISymbolicExpressionTreeNode node, int indentLength) {
   StringBuilder strBuilder = new StringBuilder();
   if (Indent) strBuilder.Append(' ', indentLength);
   strBuilder.Append("(");
   // internal nodes or leaf nodes?
   if (node.Subtrees.Count() > 0) {
     // symbol on same line as '('
     strBuilder.AppendLine(node.ToString());
     // each subtree expression on a new line
     // and closing ')' also on new line
     foreach (var subtree in node.Subtrees) {
       strBuilder.AppendLine(FormatRecursively(subtree, indentLength + 2));
     }
     if (Indent) strBuilder.Append(' ', indentLength);
     strBuilder.Append(")");
   } else {
     // symbol in the same line with as '(' and ')'
     strBuilder.Append(node.ToString());
     strBuilder.Append(")");
   }
   return strBuilder.ToString();
 }
 // the argumentTrees list contains already expanded trees used as arguments for invocations
 private ISymbolicExpressionTreeNode MacroExpand(ISymbolicExpressionTreeNode root, ISymbolicExpressionTreeNode node, IList<ISymbolicExpressionTreeNode> argumentTrees) {
   List<ISymbolicExpressionTreeNode> subtrees = new List<ISymbolicExpressionTreeNode>(node.Subtrees);
   while (node.SubtreeCount > 0) node.RemoveSubtree(0);
   if (node.Symbol is InvokeFunction) {
     var invokeSym = node.Symbol as InvokeFunction;
     var defunNode = FindFunctionDefinition(root, invokeSym.FunctionName);
     var macroExpandedArguments = new List<ISymbolicExpressionTreeNode>();
     foreach (var subtree in subtrees) {
       macroExpandedArguments.Add(MacroExpand(root, subtree, argumentTrees));
     }
     return MacroExpand(root, defunNode, macroExpandedArguments);
   } else if (node.Symbol is Argument) {
     var argSym = node.Symbol as Argument;
     // return the correct argument sub-tree (already macro-expanded)
     return (SymbolicExpressionTreeNode)argumentTrees[argSym.ArgumentIndex].Clone();
   } else {
     // recursive application
     foreach (var subtree in subtrees) {
       node.AddSubtree(MacroExpand(root, subtree, argumentTrees));
     }
     return node;
   }
 }
コード例 #57
0
    /// <summary>
    /// Returns a randomly chosen child node for the given <paramref name="parentNode"/>.
    /// </summary>
    /// <param name="parentNode">parent node to find a child node randomly for</param>
    /// <param name="genotype">integer vector, which should be mapped to a tree</param>
    /// <param name="grammar">grammar used to define the allowed child symbols</param>
    /// <param name="genotypeIndex">index in the integer vector; can be greater than vector length</param>
    /// <param name="random">random number generator</param>
    /// <returns>randomly chosen child node or null, if no child node exits</returns>
    protected ISymbolicExpressionTreeNode GetNewChildNode(ISymbolicExpressionTreeNode parentNode,
                                                          IntegerVector genotype,
                                                          ISymbolicExpressionGrammar grammar,
                                                          int genotypeIndex,
                                                          IRandom random) {

      // only select specific symbols, which can be interpreted ...
      IEnumerable<ISymbol> symbolList = (from s in grammar.GetAllowedChildSymbols(parentNode.Symbol)
                                         where s.InitialFrequency > 0.0
                                         select s).ToList();

      int prodRuleCount = symbolList.Count();

      // no child node exists for the given parent node
      if (prodRuleCount < 1) return null;

      // genotypeIndex % genotype.Length, if wrapping is allowed
      int prodRuleIndex = genotype[genotypeIndex] % prodRuleCount;

      var newNode = symbolList.ElementAt(prodRuleIndex).CreateTreeNode();
      if (newNode.HasLocalParameters) newNode.ResetLocalParameters(random);
      return newNode;
    }
コード例 #58
0
ファイル: CutPoint.cs プロジェクト: t-h-e/HeuristicLab
    public bool IsMatchingPointType(ISymbolicExpressionTreeNode newChild) {
      var parent = this.Parent;
      if (newChild == null) {
        // make sure that one subtree can be removed and that only the last subtree is removed 
        return grammar.GetMinimumSubtreeCount(parent.Symbol) < parent.SubtreeCount &&
          this.ChildIndex == parent.SubtreeCount - 1;
      } else {
        // check syntax constraints of direct parent - child relation
        if (!grammar.ContainsSymbol(newChild.Symbol) ||
            !grammar.IsAllowedChildSymbol(parent.Symbol, newChild.Symbol, this.ChildIndex))
          return false;

        bool result = true;
        // check point type for the whole branch
        newChild.ForEachNodePostfix((n) => {
          result =
            result &&
            grammar.ContainsSymbol(n.Symbol) &&
            n.SubtreeCount >= grammar.GetMinimumSubtreeCount(n.Symbol) &&
            n.SubtreeCount <= grammar.GetMaximumSubtreeCount(n.Symbol);
        });
        return result;
      }
    }
コード例 #59
0
    private static int SampleArity(IRandom random, ISymbolicExpressionTreeNode node) {
      var minArity = node.Grammar.GetMinimumSubtreeCount(node.Symbol);
      var maxArity = node.Grammar.GetMaximumSubtreeCount(node.Symbol);

      return random.Next(minArity, maxArity + 1);
    }
コード例 #60
0
    private static void RecursiveCreate(IRandom random, ISymbolicExpressionTreeNode root, int currentDepth, int maxDepth) {
      var arity = SampleArity(random, root);
      if (arity == 0)
        return;

      var allowedSymbols = root.Grammar.AllowedSymbols.Where(s => s.InitialFrequency > 0.0).ToList();

      for (var i = 0; i < arity; i++) {
        var possibleSymbols = allowedSymbols.Where(s => root.Grammar.IsAllowedChildSymbol(root.Symbol, s, i) &&
                                                        root.Grammar.GetMinimumExpressionDepth(s) - 1 <= maxDepth - currentDepth).ToList();

        if (!possibleSymbols.Any())
          throw new InvalidOperationException("No symbols are available for the tree.");

        var weights = possibleSymbols.Select(s => s.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);
        root.AddSubtree(tree);
      }

      if (maxDepth > currentDepth)
        foreach (var subTree in root.Subtrees)
          if (subTree.Grammar.GetMaximumSubtreeCount(subTree.Symbol) != 0)
            RecursiveCreate(random, subTree, currentDepth + 1, maxDepth);
    }