/// <summary>
        /// Parse an ADF branch
        /// </summary>
        /// <param name="adfNode"></param>
        /// <param name="WhichADF"></param>
        /// <param name="Program"></param>
        /// <returns></returns>
        private GPProgramBranchADF LoadBranchADF(XmlNode adfNode, short WhichADF, GPProgram Program)
        {
            //
            // First step, parse out the number of arguments
            XmlNode xmlNode        = adfNode.SelectSingleNode("ParameterCount");
            byte    ParameterCount = Convert.ToByte(xmlNode.InnerText);

            //
            // Create the Branch tree
            GPProgramBranchADF adf = new GPProgramBranchADF(Program, 0, WhichADF, ParameterCount);

            //
            // Get the root ADF node
            xmlNode  = adfNode.SelectSingleNode("GPNode");
            adf.Root = ReadGPNode(xmlNode);

            adf.UpdateStats();

            return(adf);
        }
Beispiel #2
0
        /// <summary>
        /// This method performs crossover on the ADF branch.
        /// 90% of the time internal nodes are selected and 10% of the time
        /// leaf nodes are selected.
        /// TODO: Parameterize those percentages
        ///
        /// If either one of the selected nodes is a function that accepts only
        /// terminals as parameters, no crossover is performed.
        ///
        /// </summary>
        /// <param name="sibling"></param>
        public override void Crossover(GPProgramBranch sibling)
        {
            GPProgramBranchADF rightADF = (GPProgramBranchADF)sibling;

            //
            // 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(m_Branch.CountNodes);
                findLeft = FindNode(null, m_Branch.Root, NodeLeft);
                if (TypeLeft < 0.90 && (findLeft.Node is GPNodeFunction))
                {
                    DoneLeft = true;
                }
                else if (TypeLeft >= 0.90 && (findLeft.Node is GPNodeTerminal))
                {
                    DoneLeft = true;
                }
                else if (m_Branch.CountNodes == 1)
                {
                    DoneLeft = true;
                }
            }

            //
            // If the node is a function that only accepts terminal inputs, then crossover is not allowed
            if (findLeft.Node is GPNodeFunction && ((GPNodeFunction)findLeft.Node).TerminalParameters)
            {
                return;
            }
            if (findLeft.Parent != null && findLeft.Parent is GPNodeFunction && ((GPNodeFunction)findLeft.Parent).TerminalParameters)
            {
                return;
            }

            //
            // 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(rightADF.CountNodes);
                findRight = FindNode(null, rightADF.Root, NodeRight);
                if (TypeRight < 0.90 && (findRight.Node is GPNodeFunction))
                {
                    DoneRight = true;
                }
                else if (TypeRight >= 0.90 && (findRight.Node is GPNodeTerminal))
                {
                    DoneRight = true;
                }
                else if (rightADF.CountNodes == 1)
                {
                    DoneRight = true;
                }
            }

            //
            // If the node is a function that only accepts terminal inputs, then crossover is not allowed
            if (findRight.Node is GPNodeFunction && ((GPNodeFunction)findRight.Node).TerminalParameters)
            {
                return;
            }
            if (findRight.Parent != null && findRight.Parent is GPNodeFunction && ((GPNodeFunction)findRight.Parent).TerminalParameters)
            {
                return;
            }

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

            if (findRight.Parent == null)
            {
                rightADF.Root = findLeft.Node;
            }
            else
            {
                findRight.Parent.Children[findRight.ChildNumber] = findLeft.Node;
            }

            //
            // Update the stats for these trees
            m_Branch.UpdateStats();
            rightADF.UpdateStats();
        }