/// <summary>
        /// Internal method to get the mutation done.  This method returns a reference
        /// to the root node of the branch.  If the first node is selected for mutation,
        /// that node will change, therefore, it needs to be updated in the calling method.
        /// </summary>
        /// <param name="BranchRoot">Root node of the recursion branch we are mutating</param>
        /// <param name="CountNodes">Number of nodes in the branch</param>
        /// <param name="DepthInitial">Initial depth the branch was created with</param>
        private void Mutate(ref GPNode BranchRoot, int NodeCount, int DepthInitial)
        {
            //
            // Step 1: Select a node randomly
            int NodeLabel = GPUtilities.rngNextInt(NodeCount);

            //
            // Step 2: Find this node, its parent and which child of the parent it is
            GPProgramBranchFactory.FindResult find = FindNode(null, BranchRoot, NodeLabel);
            //
            // Step 3: Build a new subtree that will replace the selected node
            GPNode SubTreeNew = BuildInternal(GPEnums.TreeBuild.Grow, DepthInitial, BranchRoot == m_BranchADR.m_RBB);

            //
            // If the parent of the result is null, then we are replacing the root node,
            // otherwise we are replacing a child of the parent.
            if (find.Parent == null)
            {
                BranchRoot = SubTreeNew;
            }
            else
            {
                find.Parent.Children[find.ChildNumber] = SubTreeNew;
            }
        }
Пример #2
0
        /// <summary>
        /// Counts the number of leaf nodes in the branch
        /// </summary>
        /// <param name="node">Root of the tree</param>
        /// <returns>Number of leaf nodes in the branch</returns>
        protected ushort DoCountLeafNodes(GPNode node)
        {
            if (node == null)
            {
                return(0);
            }
            //
            // If a terminal node, that's it, plus, it's also a leaf node by definition
            if (node is GPNodeTerminal)
            {
                return(1);
            }

            //
            // Otherwise, we have a functional node, so count up leafs in the children
            GPNodeFunction nodeFunc   = (GPNodeFunction)node;
            ushort         countChild = 0;

            for (int nChild = 0; nChild < nodeFunc.Children.Count; nChild++)
            {
                countChild += DoCountLeafNodes(nodeFunc.Children[nChild]);
            }
            //
            // If this is a functional node with no children, it is a terminal, so count it.
            if (nodeFunc.Children.Count == 0)
            {
                return((ushort)(countChild + 1));
            }
            return(countChild);
        }
Пример #3
0
        /// <summary>
        /// Converts the tree into an array based representation.  The purpose
        /// of the array representation is that it takes up FAR LESS memory and
        /// allows for a larger popuplation.  This comes at the expense of some
        /// compute time, however.
        /// </summary>
        /// <param name="FunctionSet"></param>
        public void ConvertToArray(IGPFunctionSet FunctionSet)
        {
            //
            // If the array already exists, reuse it.  The reason it would already exist
            // is if the conversion to a tree was don't for fitness computations and not
            // for altering the tree sturcture.  A simple optimization technique
            if (m_TreeArrayNew != null)
            {
                m_Root = null;
                return;
            }

            //
            // Allocate the nodes we need
            try
            {
                m_TreeArrayNew = new List <byte>(m_CountNodes);
            }
            catch (Exception)
            {
                System.Console.WriteLine("ConvertToArray: " + m_CountNodes);
                return;
            }

            //
            // Use a recursive technique to work through the nodes and get
            // them stored into the array
            m_ArrayPos = 0;
            StoreNode(m_Root, FunctionSet);

            //
            // Get rid of the tree
            m_Root = null;
        }
Пример #4
0
        /// <summary>
        /// Computes the max depth of the tree
        /// </summary>
        /// <param name="node">Root of the tree</param>
        /// <returns>Depth of the tree</returns>
        protected int ComputeDepth(GPNode node)
        {
            int nMaxChild = 0;

            if (node == null)
            {
                return(0);
            }

            //
            // Only need to probe further if we have a function node with children
            if (node is GPNodeFunction)
            {
                GPNodeFunction nodeFunc = (GPNodeFunction)node;

                //
                // Determine the child with the maximum depth
                for (int nChild = 0; nChild < nodeFunc.Children.Count; nChild++)
                {
                    int nCurrentChild = ComputeDepth(nodeFunc.Children[nChild]);
                    if (nCurrentChild > nMaxChild)
                    {
                        nMaxChild = nCurrentChild;
                    }
                }
            }

            return(nMaxChild + 1);              // +1 is the current node depth
        }
        /// <summary>
        /// This method randomly creates a new GPNode appropriate for an ADR branch.
        /// </summary>
        private GPNode CreateNode(GPEnums.TreeBuild TreeBuild, int Depth, bool UseRecursion)
        {
            //
            // For the 'full' type growth, we want to select a function
            // at every node except for the final leaf nodes, which will be chosen
            // from the list of terminals.
            if (TreeBuild == GPEnums.TreeBuild.Full && Depth > 0)
            {
                //
                // Allow the recursion to call ADFs
                // TODO: Add ability to call ADLs (low priority)
                return(CreateNodeFunction(false, 0, false, 0, UseRecursion, 0));
            }
            //
            // If the depth is 0, then this MUST be a terminal node, no choice
            if (Depth == 0)
            {
                return(CreateNodeTerminal());
            }
            //
            // We should only get here for the 'grow' type approach, here we make a uniform
            // random selection from among the combined list of operations and terminals
            // to decide the node type.
            double rnd        = GPUtilities.rngNextDouble();
            double cumulative = m_Config.Profile.ProbabilityTerminalD;

            //
            // Start with terminal probability
            if (rnd <= cumulative)
            {
                return(CreateNodeTerminal());
            }
            //
            // Next, probability of it being a function
            cumulative += m_Config.Profile.ProbabilityFunctionD;
            if (rnd <= cumulative)
            {
                //
                // Same note as above - can allow other ADFs to be called from here
                //return CreateNodeFunction(true, 0, false, 0, true,0);
                // TODO: Add ability to call ADLs (low priority)
                GPNode node = CreateNodeFunction(false, 0, false, 0, UseRecursion, 0);
                if (node is GPNodeFunctionADR)
                {
                    return(node);
                }
                return(node);
            }

            //
            // Throw an exception that something really, really bad happened!

            return(null);
        }
Пример #6
0
        /// <summary>
        /// Counts the number of nodes in the branch.  While the nodes are
        /// being counted, give each one a label so it can be later used for
        /// searching.  This method also takes care of getting the count of ADF
        /// and ADL nodes updated.
        /// </summary>
        /// <param name="node"></param>
        /// <returns></returns>
        protected ushort DoCountNodes(GPNode node)
        {
            //
            // Reset all the stats to zip
            m_CountADFNodes = 0;
            m_CountADLNodes = 0;
            m_CountADRNodes = 0;
            m_CountLabel    = 0;
            DoCountNodesInternal(node);

            return(m_CountLabel);
        }
        /// <summary>
        /// Handles mutation of the RPB branch.  A node is randomly selected
        /// for mutation and a new branch is built from that location.
        /// </summary>
        public override void Mutate()
        {
            //
            // Step 1: Select a node randomly
            int NodeLabel = GPUtilities.rngNextInt(m_Branch.CountNodes);

            //
            // Step 2: Find this node, its parent and which child of the parent it is
            GPProgramBranchFactory.FindResult find = FindNode(null, m_Branch.Root, NodeLabel);
            //
            // Step 3: Build a new subtree that will replace the selected node
            // Assign a current depth of 2, to allow a terminal to mutate into the location
            GPNode newSubtree = null;

            if (find.Node is GPNodeFunction)
            {
                newSubtree = BuildInternal(GPEnums.TreeBuild.Grow, m_Branch.DepthInitial, 2, ((GPNodeFunction)find.Node).TerminalParameters);
            }
            else
            {
                //
                // Now, even if this node is a terminal, it's parent might be a function that can only accept
                // terminal parameters.  If that is the case, can only mutate by create a new terminal node
                if (find.Parent is GPNodeFunction)
                {
                    newSubtree = BuildInternal(GPEnums.TreeBuild.Grow, m_Branch.DepthInitial, 2, ((GPNodeFunction)find.Parent).TerminalParameters);
                }
                else
                {
                    newSubtree = BuildInternal(GPEnums.TreeBuild.Grow, m_Branch.DepthInitial, 2, false);
                }
            }
            //
            // If the parent of the result is null, then we are replacing the root node,
            // otherwise we are replacing a child of the parent.
            if (find.Parent == null)
            {
                m_Branch.Root = newSubtree;
            }
            else
            {
                find.Parent.Children[find.ChildNumber] = newSubtree;
            }

            //
            // Update the stats for this tree
            m_Branch.UpdateStats();
        }
Пример #8
0
        //
        // Create the Element entry for a single node in the progam
        private void WriteProgramNode(GPNode node)
        {
            m_xmlWriter.WriteStartElement("GPNode");

            //
            // Terminal or function node?
            if (node is GPNodeTerminal)
            {
                GPNodeTerminal nodeTerminal = (GPNodeTerminal)node;

                m_xmlWriter.WriteAttributeString("Type", "Terminal");
                //
                // Write the type
                m_xmlWriter.WriteStartElement("Terminal");
                m_xmlWriter.WriteValue(nodeTerminal.ToValueTypeString());
                m_xmlWriter.WriteEndElement();
                //
                // Write the value
                m_xmlWriter.WriteStartElement("Value");
                if (node is GPNodeTerminalADRoot)
                {
                    m_xmlWriter.WriteValue(((GPNodeTerminalADRoot)node).WhichParameter);
                }
                else if (node is GPNodeTerminalUserDefined)
                {
                    m_xmlWriter.WriteValue(((GPNodeTerminalUserDefined)node).WhichUserDefined);
                }
                else if (node is GPNodeTerminalInteger)
                {
                    m_xmlWriter.WriteValue(((GPNodeTerminalInteger)node).Value);
                }
                else if (node is GPNodeTerminalDouble)
                {
                    m_xmlWriter.WriteValue(((GPNodeTerminalDouble)node).ToString());
                }
                m_xmlWriter.WriteEndElement();
            }
            else
            if (node is GPNodeFunction)
            {
                m_xmlWriter.WriteAttributeString("Type", "Function");

                WriteFunctionNodeBody(node);
            }

            m_xmlWriter.WriteEndElement();
        }
Пример #9
0
        /// <summary>
        /// Restores the program from the array representation back into a tree structure.
        /// </summary>
        /// <param name="FunctionSet"></param>
        /// <param name="ForFitness"></param>
        public void ConvertToTree(IGPFunctionSet FunctionSet, bool ForFitness)
        {
            //
            // Recursively build the tree out of the array
            m_ArrayPos = 0;
            GPNode root = ConvertNode(FunctionSet);

            m_Root = root;

            //
            // Remove the array - unless this is for a fitness computation
            if (!ForFitness)
            {
                m_TreeArrayNew = null;
            }

            this.UpdateStats();
        }
        /// <summary>
        /// Internal method to get the mutation done.  This method returns a reference
        /// to the root node of the branch.  If the first node is selected for mutation,
        /// that node will change, therefore, it needs to be updated in the calling method.
        /// </summary>
        /// <param name="BranchRoot">Root node of the loop branch we are mutating</param>
        /// <param name="CountNodes">Number of nodes in the branch</param>
        /// <param name="DepthInitial">Initial depth the branch was created with</param>
        private void Mutate(ref GPNode BranchRoot, int NodeCount, int DepthInitial)
        {
            //
            // Step 1: Select a node randomly
            int NodeLabel = GPUtilities.rngNextInt(NodeCount);

            //
            // Step 2: Find this node, its parent and which child of the parent it is
            GPProgramBranchFactory.FindResult find = FindNode(null, BranchRoot, NodeLabel);
            //
            // Step 3: Build a new subtree that will replace the selected node
            GPNode newSubtree = null;

            if (find.Node is GPNodeFunction)
            {
                newSubtree = BuildInternal(GPEnums.TreeBuild.Grow, DepthInitial, ((GPNodeFunction)find.Node).TerminalParameters);
            }
            else
            {
                //
                // Now, even if this node is a terminal, it's parent might be a function that can only accept
                // terminal parameters.  If that is the case, can only mutate by creating a new terminal node
                if (find.Parent is GPNodeFunction)
                {
                    newSubtree = BuildInternal(GPEnums.TreeBuild.Grow, DepthInitial, ((GPNodeFunction)find.Parent).TerminalParameters);
                }
                else
                {
                    newSubtree = BuildInternal(GPEnums.TreeBuild.Grow, DepthInitial, false);
                }
            }

            //
            // If the parent of the result is null, then we are replacing the root node,
            // otherwise we are replacing a child of the parent.
            if (find.Parent == null)
            {
                BranchRoot = newSubtree;
            }
            else
            {
                find.Parent.Children[find.ChildNumber] = newSubtree;
            }
        }
Пример #11
0
        /// <summary>
        /// Unfortunately, this is essentially a linear search, I should really label each
        /// node so we have a BST tree to speed up the search.
        /// </summary>
        /// <param name="parent"></param>
        /// <param name="node"></param>
        /// <param name="nFindLabel"></param>
        /// <returns></returns>
        protected FindResult FindNode(GPNode parent, GPNode node, int nFindLabel)
        {
            //
            // Termination Criteria: If FindLabel and the node label match
            if (node.Label == nFindLabel)
            {
                FindResult find = new FindResult();

                find.Parent = (GPNodeFunction)parent;
                find.Node   = node;
                //
                // Figure out which child of the parent this is
                if (parent != null)
                {
                    GPNodeFunction nodeFunc = (GPNodeFunction)parent;
                    for (int nChild = 0; nChild < nodeFunc.Children.Count; nChild++)
                    {
                        if (node == nodeFunc.Children[nChild])
                        {
                            find.ChildNumber = nChild;
                        }
                    }
                }
                return(find);
            }

            //
            // Search the children
            if (node is GPNodeFunction)
            {
                GPNodeFunction nodeFunc = (GPNodeFunction)node;
                for (int nChild = 0; nChild < nodeFunc.Children.Count; nChild++)
                {
                    FindResult find = FindNode(nodeFunc, nodeFunc.Children[nChild], nFindLabel);
                    if (find != null)
                    {
                        return(find);
                    }
                }
            }

            return(null);
        }
Пример #12
0
        /// <summary>
        /// Writes a function for the passed in loop branch
        /// </summary>
        /// <param name="adl">Parent ADL tree</param>
        /// <param name="ADLBranch">Root name for the function</param>
        /// <param name="BranchRoot">Root GPNode of the loop branch</param>
        private void WriteADLBranch(GPProgramBranchADL adl, String ADLBranch, GPNode BranchRoot)
        {
            //
            // Write the function declaration
            m_Writer.WriteLine(BuildADLPrototype(adl, ADLBranch, "GeneticProgram::"));
            m_Writer.WriteLine("{");

            m_Writer.Write("\tdouble Result=");

            WriteProgramBody(BranchRoot);
            m_Writer.WriteLine(";");

            //
            // Close the function
            m_Writer.WriteLine();
            m_Writer.WriteLine("return Result;");
            m_Writer.WriteLine("}");
            m_Writer.WriteLine();
        }
Пример #13
0
        /// <summary>
        /// Internal recursive method that does the actual work of counting the
        /// nodes in the tree.
        /// </summary>
        /// <param name="node"></param>
        private void DoCountNodesInternal(GPNode node)
        {
            if (node == null)
            {
                return;
            }
            //
            // If we made it this far, count the node
            node.Label = m_CountLabel++;

            //
            // Update the ADF and ADL counts
            if (node is GPNodeFunctionADF)
            {
                m_CountADFNodes++;
            }
            if (node is GPNodeFunctionADL)
            {
                m_CountADLNodes++;
            }
            if (node is GPNodeFunctionADR)
            {
                m_CountADRNodes++;
            }

            //
            // If a terminal node, that's it, just count the node
            if (node is GPNodeTerminal)
            {
                return;
            }

            //
            // Otherwise, we have a functional node, so count up the children
            GPNodeFunction nodeFunc = (GPNodeFunction)node;

            for (int nChild = 0; nChild < nodeFunc.Children.Count; nChild++)
            {
                DoCountNodesInternal(nodeFunc.Children[nChild]);
            }
        }
        /// <summary>
        /// Custom build function that creates the result producing branch
        /// of the genetic program.
        /// </summary>
        /// <param name="TreeBuild"></param>
        /// <param name="MaxDepth"></param>
        /// <param name="CurrentDepth"></param>
        /// <param name="TerminalParameters"></param>
        /// <returns></returns>
        private GPNode BuildInternal(GPEnums.TreeBuild TreeBuild, int MaxDepth, int CurrentDepth, bool TerminalParameters)
        {
            //
            // Randomly create this node
            GPNode newNode = CreateNode(TreeBuild, MaxDepth, CurrentDepth, TerminalParameters);

            //
            // If we just created a function, build its children
            if (newNode is GPNodeFunction)
            {
                GPNodeFunction node = (GPNodeFunction)newNode;
                //
                // Need to generate the appropriate number of nodes for the operation
                for (int Child = 0; Child < node.NumberArgs; Child++)
                {
                    node.Children.Add(BuildInternal(TreeBuild, MaxDepth - 1, CurrentDepth + 1, node.TerminalParameters));
                }
            }

            return(newNode);
        }
Пример #15
0
        /// <summary>
        /// Writes a function for the passed in loop branch
        /// </summary>
        /// <param name="adl">Parent ADL tree</param>
        /// <param name="BranchName">Root name for the function</param>
        /// <param name="BranchRoot">Root GPNode of the loop branch</param>
        private void WriteADLBranch(GPProgramBranchADL adl, String BranchName, GPNode BranchRoot)
        {
            WriteFunctionPrototype(BranchName + adl.WhichFunction, adl.NumberArgs, "p");

            //
            // Add the common blocks
            WriteFortranString("      REAL Memory(" + m_Program.CountMemory + ")");
            WriteFortranString("      COMMON /idxmemory/ Memory");
            //
            // Declare the function types
            WriteFortranString("      REAL SetMem");
            WriteFortranString("      REAL GetMem");
            foreach (KeyValuePair <String, GPLanguageWriter.tagUserDefinedFunction> kvp in m_FunctionSet)
            {
                if (!IsFortranIntrinsic(kvp.Key))
                {
                    WriteFortranString("      REAL " + ((GPLanguageWriter.tagUserDefinedFunction)kvp.Value).Name);
                }
            }
            //
            // Declare any ADFs
            foreach (GPProgramBranchADF adf in m_Program.ADF)
            {
                WriteFortranString("      REAL ADF" + adf.WhichFunction);
            }

            m_Writer.Write("      " + BranchName + adl.WhichFunction + "=");
            WriteFortranString("");

            WriteProgramBody(BranchRoot);
            WriteFortranString("");
            WriteFortranString("");

            //
            // Close the function
            WriteFortranString("");
            WriteFortranString("      RETURN");
            WriteFortranString("      END");
            WriteFortranString("");
        }
Пример #16
0
        /// <summary>
        /// Writes a function for the passed in loop branch
        /// </summary>
        /// <param name="adl">Parent ADL tree</param>
        /// <param name="BranchName">Root name for the function</param>
        /// <param name="BranchRoot">Root GPNode of the loop branch</param>
        private void WriteADLBranch(GPProgramBranchADL adl, String BranchName, GPNode BranchRoot)
        {
            //
            // Write the function declaration
            m_Writer.Write("double " + BranchName + adl.WhichFunction + "(");
            //
            // Write the function parameters
            WriteADLParameters(adl, true);
            m_Writer.WriteLine(")");
            m_Writer.WriteLine("{");

            m_Writer.Write("\tdouble Result=");

            WriteProgramBody(BranchRoot);
            m_Writer.WriteLine(";");

            //
            // Close the function
            m_Writer.WriteLine();
            m_Writer.WriteLine("return Result;");
            m_Writer.WriteLine("}");
            m_Writer.WriteLine();
        }
Пример #17
0
        /// <summary>
        /// Writes a function for the passed in loop branch
        /// </summary>
        /// <param name="adl">Parent ADL tree</param>
        /// <param name="BranchName">Root name for the function</param>
        /// <param name="BranchRoot">Root GPNode of the loop branch</param>
        private void WriteADLBranch(GPProgramBranchADL adl, String BranchName, GPNode BranchRoot)
        {
            //
            // Write the function declaration
            m_Writer.Write("\tPrivate Function " + BranchName + adl.WhichFunction + "(");
            //
            // Write the function parameters
            WriteADLParameters(adl, true);
            m_Writer.WriteLine(") As Double");
            m_Writer.WriteLine();

            m_Writer.WriteLine("\t\tDim Result As Double");
            m_Writer.Write("\t\tResult=");

            WriteProgramBody(BranchRoot);
            m_Writer.WriteLine();

            //
            // Close the function
            m_Writer.WriteLine();
            m_Writer.WriteLine("\t\tReturn Result");
            m_Writer.WriteLine("\tEnd Function");
            m_Writer.WriteLine();
        }
Пример #18
0
 /// <summary>
 /// Perform the genetic operation of editing on the program branch.  If
 /// anything custom needs to be done, derived classes can override.
 /// </summary>
 public virtual void Edit(GPProgram tree)
 {
     m_Root = m_Root.Edit(tree, this);
 }
Пример #19
0
        /// <summary>
        /// Given a tree node, the node is translated into code, this method is
        /// recursively called for each of the node's children.
        /// </summary>
        /// <param name="node">The node to translate</param>
        protected void WriteProgramBody(GPNode node)
        {
            //
            // Recursively work through the nodes
            if (node is GPNodeTerminal)
            {
                m_Writer.Write(((GPNodeTerminal)node).ToString());
                //
                // There are no children, so don't need to make a recursive call
            }
            else if (node is GPNodeFunction)
            {
                if (node is GPNodeFunctionADF)
                {
                    GPNodeFunctionADF adf = (GPNodeFunctionADF)node;
                    m_Writer.Write(" _\n\t\tADF" + adf.WhichFunction);
                    m_Writer.Write("(");
                    //
                    // The parameters to the ADF are its children
                    for (int Param = 0; Param < adf.NumberArgs; Param++)
                    {
                        if (Param > 0)
                        {
                            m_Writer.Write(",");
                        }
                        WriteProgramBody(((GPNodeFunction)node).Children[Param]);
                    }

                    m_Writer.Write(") _\n\t\t");
                }
                else if (node is GPNodeFunctionADL)
                {
                    GPNodeFunctionADL adl = (GPNodeFunctionADL)node;
                    m_Writer.Write(" _\n\t\tADL" + adl.WhichFunction);
                    m_Writer.Write("(");
                    //
                    // The parameters to the ADL are its children
                    for (int Param = 0; Param < adl.NumberArgs; Param++)
                    {
                        if (Param > 0)
                        {
                            m_Writer.Write(",");
                        }
                        WriteProgramBody(((GPNodeFunction)node).Children[Param]);
                    }
                    m_Writer.Write(") _\n\t\t");
                }
                else if (node is GPNodeFunctionSetMem)
                {
                    m_Writer.Write(" _\n\t\tSetMem(");
                    WriteProgramBody(((GPNodeFunction)node).Children[0]);
                    m_Writer.Write(",");
                    WriteProgramBody(((GPNodeFunction)node).Children[1]);
                    m_Writer.Write(")");
                }
                else if (node is GPNodeFunctionGetMem)
                {
                    m_Writer.Write(" _\n\t\tGetMem(");
                    WriteProgramBody(((GPNodeFunction)node).Children[0]);
                    m_Writer.Write(")");
                }
                else
                {
                    m_Writer.Write(" _\n\t\t" + node.ToString() + "(");
                    //
                    // The parameters to the function are its children
                    for (short Param = 0; Param < m_FunctionSet[node.ToString().ToUpper()].Arity; Param++)
                    {
                        if (Param > 0)
                        {
                            m_Writer.Write(",");
                        }
                        WriteProgramBody(((GPNodeFunction)node).Children[Param]);
                    }
                    m_Writer.Write(")");
                }
            }
            else
            {
                Console.WriteLine("Have an undefined node we are tying to write");
            }
        }
Пример #20
0
        /// <summary>
        /// Converts a tree node into an array based representation.  For functions
        /// an byte lookup is used into the FunctionSet, for terminals, the type
        /// is recorded along with whatever extra data may be needed.
        /// TODO: Get rid of the unsafe code.  I know there is a bit conversion
        /// function, I just couldn't find it quickly.
        /// </summary>
        /// <param name="Node">The node to convert</param>
        /// <param name="FunctionSet"></param>
        private void StoreNode(GPNode Node, IGPFunctionSet FunctionSet)
        {
            //
            // Figure out what kind of node we have and store it accordingly.
            if (Node is GPNodeFunction)
            {
                GPNodeFunction NodeFunction = (GPNodeFunction)Node;
                if (NodeFunction is GPNodeFunctionADF)
                {
                    GPNodeFunctionADF adf = (GPNodeFunctionADF)NodeFunction;
                    //
                    // For an ADF node,record it as value 255 and then store the which
                    // ADF it refers to and the number of arguments.
                    m_TreeArrayNew.Add((byte)255);
                    m_TreeArrayNew.Add((byte)adf.WhichFunction);
                    m_TreeArrayNew.Add(adf.NumberArgs);
                }
                else if (NodeFunction is GPNodeFunctionADL)
                {
                    GPNodeFunctionADL adl = (GPNodeFunctionADL)NodeFunction;
                    //
                    // For an ADL node,record it as value 254 and then store the which
                    // ADL it refers to and the number of arguments.
                    m_TreeArrayNew.Add((byte)254);
                    m_TreeArrayNew.Add((byte)adl.WhichFunction);
                    m_TreeArrayNew.Add(adl.NumberArgs);
                }
                else if (NodeFunction is GPNodeFunctionADR)
                {
                    GPNodeFunctionADR adr = (GPNodeFunctionADR)NodeFunction;
                    //
                    // For an ADR node,record it as value 253 and then store the which
                    // ADR it refers to and the number of arguments.
                    m_TreeArrayNew.Add((byte)253);
                    m_TreeArrayNew.Add((byte)adr.WhichFunction);
                    m_TreeArrayNew.Add(adr.NumberArgs);
                }
                else
                {
                    //
                    // Store the index of the function and then the number of children
                    // for this function
                    m_TreeArrayNew.Add((byte)FunctionSet.IndexOfKey(NodeFunction.ToStringUpper()));
                    m_TreeArrayNew.Add((byte)((GPNodeFunction)Node).Children.Count);
                }

                //
                // Store each of the children
                foreach (GPNode NodeChild in NodeFunction.Children)
                {
                    StoreNode(NodeChild, FunctionSet);
                }
            }
            else             // Terminal Node
            {
                //
                // Depending upon the type of the terminal, set the appropriate value
                if (Node is GPNodeTerminalADFParam)
                {
                    m_TreeArrayNew.Add(200);
                    m_TreeArrayNew.Add((byte)((GPNodeTerminalADFParam)Node).WhichParameter);
                }
                else if (Node is GPNodeTerminalUserDefined)
                {
                    m_TreeArrayNew.Add(201);
                    m_TreeArrayNew.Add((byte)((GPNodeTerminalUserDefined)Node).WhichUserDefined);
                }
                else if (Node is GPNodeTerminalDouble)
                {
                    m_TreeArrayNew.Add(202);
                    double dValue = ((GPNodeTerminalDouble)Node).Value;
                    unsafe
                    {
                        byte *ptr = (byte *)&dValue;
                        for (int pos = 0; pos < sizeof(double); pos++)
                        {
                            m_TreeArrayNew.Add(ptr[pos]);
                        }
                    }
                }
                else if (Node is GPNodeTerminalInteger)
                {
                    m_TreeArrayNew.Add(203);
                    int dValue = ((GPNodeTerminalInteger)Node).Value;
                    unsafe
                    {
                        byte *ptr = (byte *)&dValue;
                        for (int pos = 0; pos < sizeof(int); pos++)
                        {
                            m_TreeArrayNew.Add(ptr[pos]);
                        }
                    }
                }
            }
        }
        /// <summary>
        /// Internal method that actually does the crossover operation.  90% of the
        /// time a functional node is selected, 10% of the time a terminal is selected.
        /// TODO: Think about parameterizing those percentages
        /// </summary>
        /// <param name="LeftBranchRoot">Root node of the left sibling</param>
        /// <param name="LeftNodeCount">Number of nodes in the left sibling</param>
        /// <param name="RightBranchRoot">Root node of the right sibling</param>
        /// <param name="RightNodeCount">Number of nodes in the right sibling</param>
        private void Crossover(ref GPNode LeftBranchRoot, int LeftNodeCount, ref GPNode RightBranchRoot, int RightNodeCount)
        {
            //
            // Step 1: Find a node in the left tree
            double TypeLeft = GPUtilities.rngNextDouble();

            GPProgramBranchFactory.FindResult findLeft = null;
            bool DoneLeft = false;

            while (!DoneLeft)
            {
                int NodeLeft = GPUtilities.rngNextInt(LeftNodeCount);
                findLeft = FindNode(null, LeftBranchRoot, NodeLeft);
                if (TypeLeft < 0.90 && (findLeft.Node is GPNodeFunction))
                {
                    DoneLeft = true;
                }
                else if (TypeLeft >= 0.90 && (findLeft.Node is GPNodeTerminal))
                {
                    DoneLeft = true;
                }
                else if (LeftNodeCount == 1)
                {
                    DoneLeft = true;
                }
            }

            //
            // Step 2: Find a node in the right tree
            double TypeRight = GPUtilities.rngNextDouble();

            GPProgramBranchFactory.FindResult findRight = null;
            bool DoneRight = false;

            while (!DoneRight)
            {
                int NodeRight = GPUtilities.rngNextInt(RightNodeCount);
                findRight = FindNode(null, RightBranchRoot, NodeRight);
                if (TypeRight < 0.90 && (findRight.Node is GPNodeFunction))
                {
                    DoneRight = true;
                }
                else if (TypeRight >= 0.90 && (findRight.Node is GPNodeTerminal))
                {
                    DoneRight = true;
                }
                else if (RightNodeCount == 1)
                {
                    DoneRight = true;
                }
            }

            //
            // Step 3: Swap the references
            if (findLeft.Parent == null)
            {
                LeftBranchRoot = findRight.Node;
            }
            else
            {
                findLeft.Parent.Children[findLeft.ChildNumber] = findRight.Node;
            }

            if (findRight.Parent == null)
            {
                RightBranchRoot = findLeft.Node;
            }
            else
            {
                findRight.Parent.Children[findRight.ChildNumber] = findLeft.Node;
            }
        }
Пример #22
0
        /// <summary>
        /// Given a tree node, the node is translated into code, this method is
        /// recursively called for each of the node's children.
        /// </summary>
        /// <param name="node">The node to translate</param>
        protected void WriteProgramBody(GPNode node)
        {
            //
            // Recursively work through the nodes
            if (node is GPNodeTerminal)
            {
                if (node is GPNodeTerminalDouble || node is GPNodeTerminalInteger)
                {
                    //
                    // Put doubles on their own line, helps prevent the lines
                    // from getting too long
                    m_Writer.WriteLine();
                    m_Writer.Write("     . ");
                }
                m_Writer.Write(((GPNodeTerminal)node).ToString());
                //
                // There are no children, so don't need to make a recursive call
            }
            else if (node is GPNodeFunction)
            {
                if (node is GPNodeFunctionADF)
                {
                    GPNodeFunctionADF adf = (GPNodeFunctionADF)node;
                    m_Writer.Write("\n     . ADF" + adf.WhichFunction);
                    m_Writer.Write("(");
                    //
                    // The parameters to the ADF are its children
                    for (int Param = 0; Param < adf.NumberArgs; Param++)
                    {
                        if (Param > 0)
                        {
                            m_Writer.Write(",");
                        }
                        WriteProgramBody(((GPNodeFunction)node).Children[Param]);
                    }

                    m_Writer.Write(")\n     . ");
                }
                else if (node is GPNodeFunctionADL)
                {
                    GPNodeFunctionADL adl = (GPNodeFunctionADL)node;
                    m_Writer.Write("\n     . ADL" + adl.WhichFunction);
                    m_Writer.Write("(");
                    //
                    // The parameters to the ADL are its children
                    for (int Param = 0; Param < adl.NumberArgs; Param++)
                    {
                        if (Param > 0)
                        {
                            m_Writer.Write(",");
                        }
                        WriteProgramBody(((GPNodeFunction)node).Children[Param]);
                    }
                    m_Writer.Write(")\n     . ");
                }
                else if (node is GPNodeFunctionSetMem)
                {
                    m_Writer.Write("\n     . SetMem(");
                    WriteProgramBody(((GPNodeFunction)node).Children[0]);
                    m_Writer.Write(",");
                    WriteProgramBody(((GPNodeFunction)node).Children[1]);
                    m_Writer.Write(")");
                }
                else if (node is GPNodeFunctionGetMem)
                {
                    m_Writer.Write("\n     . GetMem(");
                    WriteProgramBody(((GPNodeFunction)node).Children[0]);
                    m_Writer.Write(")");
                }
                else
                {
                    m_Writer.Write("\n     . " + node.ToString() + "(");
                    //
                    // The parameters to the function are its children
                    for (short Param = 0; Param < m_FunctionSet[node.ToString().ToUpper()].Arity; Param++)
                    {
                        if (Param > 0)
                        {
                            m_Writer.Write(",");
                        }
                        WriteProgramBody(((GPNodeFunction)node).Children[Param]);
                    }
                    m_Writer.Write(")");
                }
            }
            else
            {
                Console.WriteLine("Have an undefined node we are tying to write");
            }
        }
Пример #23
0
        //
        // Gets the function nodes written out
        private void WriteFunctionNodeBody(GPNode node)
        {
            GPNodeFunction nodeFunc = (GPNodeFunction)node;

            String sType = node.GetType().ToString();

            if (node is GPNodeFunctionADF)
            {
                GPNodeFunctionADF nodeADF = (GPNodeFunctionADF)nodeFunc;

                m_xmlWriter.WriteStartElement("Function");
                m_xmlWriter.WriteValue("ADF");
                m_xmlWriter.WriteEndElement();

                //
                // Write out "which" ADF function this is
                m_xmlWriter.WriteStartElement("WhichFunction");
                m_xmlWriter.WriteValue(nodeADF.WhichFunction);
                m_xmlWriter.WriteEndElement();

                for (int nParam = 0; nParam < nodeADF.NumberArgs; nParam++)
                {
                    WriteProgramNode(nodeADF.Children[nParam]);
                }
            }
            else if (node is GPNodeFunctionADL)
            {
                GPNodeFunctionADL nodeADL = (GPNodeFunctionADL)nodeFunc;

                m_xmlWriter.WriteStartElement("Function");
                m_xmlWriter.WriteValue("ADL");
                m_xmlWriter.WriteEndElement();

                //
                // Write out "which" ADL function this is
                m_xmlWriter.WriteStartElement("WhichFunction");
                m_xmlWriter.WriteValue(nodeADL.WhichFunction);
                m_xmlWriter.WriteEndElement();

                for (int nParam = 0; nParam < nodeADL.NumberArgs; nParam++)
                {
                    WriteProgramNode(nodeADL.Children[nParam]);
                }
            }
            else if (node is GPNodeFunctionADR)
            {
                GPNodeFunctionADR nodeADR = (GPNodeFunctionADR)nodeFunc;

                m_xmlWriter.WriteStartElement("Function");
                m_xmlWriter.WriteValue("ADR");
                m_xmlWriter.WriteEndElement();

                //
                // Write out "which" ADR function this is
                m_xmlWriter.WriteStartElement("WhichFunction");
                m_xmlWriter.WriteValue(nodeADR.WhichFunction);
                m_xmlWriter.WriteEndElement();

                for (int nParam = 0; nParam < nodeADR.NumberArgs; nParam++)
                {
                    WriteProgramNode(nodeADR.Children[nParam]);
                }
            }
            else
            {
                m_xmlWriter.WriteStartElement("Function");
                m_xmlWriter.WriteValue(nodeFunc.ToString());
                m_xmlWriter.WriteEndElement();

                //
                // Write out its children
                for (int nParam = 0; nParam < nodeFunc.NumberArgs; nParam++)
                {
                    WriteProgramNode(nodeFunc.Children[nParam]);
                }
            }
        }