/// <summary>
        /// Compare two nodes.
        /// </summary>
        /// <param name="result">The result of previous comparisons.</param>
        /// <param name="node1">The first node to compare.</param>
        /// <param name="node2">The second node to compare.</param>
        /// <returns>The result.</returns>
        private double CompareNode(double result, TreeGenomeNode node1,
                                   TreeGenomeNode node2)
        {
            double newResult = result;

            int node1Size = node1.Children.Count;
            int node2Size = node2.Children.Count;
            int childNodeCount = Math.Max(node1Size, node2Size);

            for (int i = 0; i < childNodeCount; i++)
            {
                if (i < node1Size && i < node2Size)
                {
                    TreeGenomeNode childNode1 = node1.Children[i];
                    TreeGenomeNode childNode2 = node2.Children[i];
                    newResult = CompareNode(newResult, childNode1, childNode2);
                }
                else
                {
                    newResult++;
                }
            }

            return newResult;
        }
Exemple #2
0
        /// <summary>
        /// Grow the tree randomly by the specified max depth.
        /// </summary>
        /// <param name="rnd">A random number generator.</param>
        /// <param name="maxDepth">The max depth.</param>
        /// <returns>The tree.</returns>
        public TreeGenomeNode Grow(IGenerateRandom rnd, int maxDepth)
        {
            if (maxDepth == 1)
            {
                return(new TreeGenomeNode(ChooseRandomLeafOpcode(rnd)));
            }
            var result     = new TreeGenomeNode(ChooseRandomNodeOpcode(rnd));
            int childCount = DetermineChildCount(result.Opcode);

            for (int i = 0; i < childCount; i++)
            {
                result.Children.Add(Grow(rnd, maxDepth - 1));
            }
            return(result);
        }
Exemple #3
0
        /// <summary>
        /// 
        /// </summary>
        /// <param name="rnd"></param>
        /// <param name="parent"></param>
        /// <param name="current"></param>
        /// <param name="index"></param>
        /// <param name="reservoir"></param>
        private void InternalSampleRandomNode(IGenerateRandom rnd, TreeGenomeNode parent, TreeGenomeNode current,
            int[] index, RandomNodeResult reservoir)
        {
            int currentIndex = index[0];
            index[0]++;

            // determine if we replace the reservoir
            int j = rnd.NextInt(0, currentIndex + 1);
            if (j == 0)
            {
                reservoir.Parent = parent;
                reservoir.Child = current;
            }

            // traverse on to the children
            foreach (TreeGenomeNode child in current.Children)
            {
                InternalSampleRandomNode(rnd, current, child, index, reservoir);
            }
        }
Exemple #4
0
        /// <summary>
        ///
        /// </summary>
        /// <param name="rnd"></param>
        /// <param name="parent"></param>
        /// <param name="current"></param>
        /// <param name="index"></param>
        /// <param name="reservoir"></param>
        private void InternalSampleRandomNode(IGenerateRandom rnd, TreeGenomeNode parent, TreeGenomeNode current,
                                              int[] index, RandomNodeResult reservoir)
        {
            int currentIndex = index[0];

            index[0]++;

            // determine if we replace the reservoir
            int j = rnd.NextInt(0, currentIndex + 1);

            if (j == 0)
            {
                reservoir.Parent = parent;
                reservoir.Child  = current;
            }

            // traverse on to the children
            foreach (TreeGenomeNode child in current.Children)
            {
                InternalSampleRandomNode(rnd, current, child, index, reservoir);
            }
        }
Exemple #5
0
        /// <inheritdoc />
        public void PerformOperation(IGenerateRandom rnd, IGenome[] parents, int parentIndex, IGenome[] offspring,
                                     int offspringIndex)
        {
            var              parent1   = (TreeGenome)parents[parentIndex];
            EvaluateTree     eval      = parent1.Evaluator;
            var              off1      = (TreeGenome)_owner.Population.GenomeFactory.Factor(parent1);
            RandomNodeResult off1Point = eval.SampleRandomNode(rnd, off1.Root);

            int            len            = rnd.NextInt(1, _maxGraftLength + 1);
            TreeGenomeNode randomSequence = eval.Grow(rnd, len);

            if (off1Point.Parent == null)
            {
                off1.Root = randomSequence;
            }
            else
            {
                int idx = off1Point.Parent.Children.IndexOf(off1Point.Child);
                off1Point.Parent.Children[idx] = randomSequence;
            }

            offspring[0] = off1;
        }
 /// <summary>
 ///     Create a copy of this node.
 /// </summary>
 /// <returns>A copy (clone) of this node.</returns>
 public TreeGenomeNode Copy()
 {
     var result = new TreeGenomeNode(_opcode);
     foreach (TreeGenomeNode child in _children)
     {
         result.Children.Add(child.Copy());
     }
     return result;
 }
Exemple #7
0
 /// <summary>
 /// Evaluate the specified node.
 /// </summary>
 /// <param name="node">The node to evaluate.</param>
 /// <param name="varValues">The variable values.</param>
 /// <returns>The result of the evaluation.</returns>
 public abstract double Evaluate(TreeGenomeNode node, double[] varValues);
Exemple #8
0
 /// <summary>
 /// Grow the tree randomly by the specified max depth. 
 /// </summary>
 /// <param name="rnd">A random number generator.</param>
 /// <param name="maxDepth">The max depth.</param>
 /// <returns>The tree.</returns>
 public TreeGenomeNode Grow(IGenerateRandom rnd, int maxDepth)
 {
     if (maxDepth == 1)
     {
         return new TreeGenomeNode(ChooseRandomLeafOpcode(rnd));
     }
     var result = new TreeGenomeNode(ChooseRandomNodeOpcode(rnd));
     int childCount = DetermineChildCount(result.Opcode);
     for (int i = 0; i < childCount; i++)
     {
         result.Children.Add(Grow(rnd, maxDepth - 1));
     }
     return result;
 }
Exemple #9
0
 /// <summary>
 /// Evaluate the specified node. 
 /// </summary>
 /// <param name="node">The node to evaluate.</param>
 /// <param name="varValues">The variable values.</param>
 /// <returns>The result of the evaluation.</returns>
 public abstract double Evaluate(TreeGenomeNode node, double[] varValues);
Exemple #10
0
 /// <summary>
 /// Choose a random node from the tree.  Uses reservoir sampling. 
 /// </summary>
 /// <param name="rnd">Random number generator.</param>
 /// <param name="root">The root of the tree.</param>
 /// <returns>A random node.</returns>
 public RandomNodeResult SampleRandomNode(IGenerateRandom rnd, TreeGenomeNode root)
 {
     var index = new int[1];
     var reservoir = new RandomNodeResult();
     index[0] = 0;
     InternalSampleRandomNode(rnd, null, root, index, reservoir);
     return reservoir;
 }
 /// <inheritdoc />
 public override double Evaluate(TreeGenomeNode node, double[] varValues)
 {
     switch (node.Opcode)
     {
         case OPCODE_NEG:
             return -(Evaluate(node.Children[0], varValues));
         case OPCODE_ADD:
             return Evaluate(node.Children[0], varValues) + Evaluate(node.Children[1], varValues);
         case OPCODE_SUB:
             return Evaluate(node.Children[0], varValues) - Evaluate(node.Children[1], varValues);
         case OPCODE_DIV:
             return Evaluate(node.Children[0], varValues) / Evaluate(node.Children[1], varValues);
         case OPCODE_MUL:
             return Evaluate(node.Children[0], varValues) * Evaluate(node.Children[1], varValues);
         case OPCODE_POWER:
             return Math.Pow(Evaluate(node.Children[0], varValues), Evaluate(node.Children[1], varValues));
         case OPCODE_SQRT:
             return Math.Sqrt(Evaluate(node.Children[0], varValues));
         default:
             int index = node.Opcode - OPCODE_VAR_CONST;
             if (index >= (constValues.Length + varCount))
             {
                 throw new AIFHError("Invalid opcode: " + node.Opcode);
             }
             if (index < varCount)
             {
                 return varValues[index];
             }
             return constValues[index - varCount];
     }
 }
        /// <summary>
        ///     Display an expression as normal infix.
        /// </summary>
        /// <param name="node">The root node.</param>
        /// <returns>The infix string.</returns>
        public String DisplayExpressionNormal(TreeGenomeNode node)
        {
            var result = new StringBuilder();

            if (DetermineChildCount(node.Opcode) == 0)
            {
                result.Append(GetOpcodeText(node.Opcode));
            }
            else
            {
                int childCount = DetermineChildCount(node.Opcode);

                if (childCount == 0)
                {
                    result.Append(GetOpcodeText(node.Opcode));
                }
                else
                {
                    String name = GetOpcodeText(node.Opcode);

                    if (name.Length > 1)
                    {
                        result.Append(name);
                        result.Append("(");
                        bool first = true;
                        foreach (TreeGenomeNode child in node.Children)
                        {
                            if (!first)
                            {
                                result.Append(",");
                            }
                            result.Append(DisplayExpressionNormal(child));
                            first = false;
                        }
                        result.Append(")");
                    }
                    else
                    {
                        result.Append("(");
                        if (childCount == 2)
                        {
                            result.Append(DisplayExpressionNormal(node.Children[0]));
                            result.Append(name);
                            result.Append(DisplayExpressionNormal(node.Children[1]));
                            result.Append(")");
                        }
                        else
                        {
                            result.Append(name);
                            result.Append(DisplayExpressionNormal(node.Children[0]));
                            result.Append(")");
                        }
                    }
                }
            }


            return result.ToString();
        }
        /// <summary>
        ///     Display an expression as LISP (the programming language)
        /// </summary>
        /// <param name="node">The root node.</param>
        /// <returns>The LISP for the expression.</returns>
        public String DisplayExpressionLISP(TreeGenomeNode node)
        {
            var result = new StringBuilder();

            if (DetermineChildCount(node.Opcode) == 0)
            {
                result.Append(GetOpcodeText(node.Opcode));
            }
            else
            {
                result.Append("(");
                result.Append(GetOpcodeText(node.Opcode));
                foreach (TreeGenomeNode child in node.Children)
                {
                    result.Append(" ");
                    result.Append(DisplayExpressionLISP(child));
                }
                result.Append(")");
            }

            return result.ToString();
        }