예제 #1
0
        /// <summary>
        /// Perform the genetic operation of editing upon this program
        /// </summary>
        public void Edit()
        {
            //
            // Go through each of the program structures and perform editing
            m_RPB.Edit(this);
            m_RPB.UpdateStats();

            foreach (GPProgramBranchADF adf in m_listADF)
            {
                adf.Edit(this);
                adf.UpdateStats();
            }

            foreach (GPProgramBranchADL adl in m_listADL)
            {
                adl.Edit(this);
                adl.UpdateStats();
            }

            foreach (GPProgramBranchADR adr in m_listADR)
            {
                adr.Edit(this);
                adr.UpdateStats();
            }
        }
예제 #2
0
        /// <summary>
        /// Parse the RPB branch
        /// </summary>
        /// <param name="rpbNode"></param>
        /// <param name="ADFList"></param>
        /// <param name="Program"></param>
        /// <returns></returns>
        private GPProgramBranchRPB LoadBranchRPB(XmlNode rpbNode, List <GPProgramBranchADF> ADFList, GPProgram Program)
        {
            //
            // Start out with the input dimension
            XmlNode xmlNode = rpbNode.SelectSingleNode("ParameterCount");

            Program.InputDimension = Convert.ToInt16(xmlNode.InnerText);

            //
            // Create the Branch tree
            GPProgramBranchRPB rpb = new GPProgramBranchRPB(Program, ADFList.Count, 0, GPEnums.TreeBuild.Undef);

            //
            // Get the root of the branch
            xmlNode  = rpbNode.SelectSingleNode("GPNode");
            rpb.Root = ReadGPNode(xmlNode);

            rpb.UpdateStats();

            return(rpb);
        }
        /// <summary>
        /// This method performs crossover on the result producing 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)
        {
            GPProgramBranchRPB rightRPB = (GPProgramBranchRPB)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 (TypeLeft >= 0.90 && (findLeft.Node is GPNodeFunction) && ((GPNodeFunction)findLeft.Node).Children.Count == 0)
                {
                    //
                    // This if statement accounts for the possibility of functions that
                    // are constant values...because I didn't use a terminal type for them
                    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(rightRPB.CountNodes);
                findRight = FindNode(null, rightRPB.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 (TypeRight >= 0.90 && (findRight.Node is GPNodeFunction) && ((GPNodeFunction)findRight.Node).Children.Count == 0)
                {
                    //
                    // This if statement accounts for the possibility of functions that
                    // are constant values...because I didn't use a terminal type for them
                    DoneRight = true;
                }
                else if (rightRPB.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)
            {
                rightRPB.Root = findLeft.Node;
            }
            else
            {
                findRight.Parent.Children[findRight.ChildNumber] = findLeft.Node;
            }

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