Beispiel #1
0
        /// <summary>
        /// Cloneable interface
        /// </summary>
        /// <returns>Clone of the program branch</returns>
        public Object Clone()
        {
            GPProgramBranch obj = (GPProgramBranch)this.MemberwiseClone();

            if (m_Root != null)
            {
                obj.m_Root = (GPNode)m_Root.Clone();
            }
            obj.m_DepthInitial   = m_DepthInitial;
            obj.m_Depth          = m_Depth;
            obj.m_CountNodes     = m_CountNodes;
            obj.m_CountLeafNodes = m_CountLeafNodes;
            obj.m_CountADFNodes  = m_CountADFNodes;
            obj.m_CountADLNodes  = m_CountADLNodes;
            obj.m_CountADRNodes  = m_CountADRNodes;

            if (m_TreeArrayNew != null)
            {
                obj.m_TreeArrayNew = new List <byte>(m_TreeArrayNew.Count);
                foreach (byte Value in m_TreeArrayNew)
                {
                    obj.m_TreeArrayNew.Add(Value);
                }
            }

            return(obj);
        }
        /// <summary>
        /// Performs a crossover operation with this program and the sibling program.
        /// Crossover is performed on like branches, i.e. RCBs only crossover with sibling
        /// RCBs.
        /// </summary>
        /// <param name="sibling">Which sibling to crossover with</param>
        public override void Crossover(GPProgramBranch sibling)
        {
            GPProgramBranchADR rightADR = (GPProgramBranchADR)sibling;

            //
            // Select a branch
            byte WhichBranch = (byte)GPUtilities.rngNextInt(4);

            switch (WhichBranch)
            {
            case 0:
                Crossover(ref m_BranchADR.m_RCB, m_BranchADR.NodeCountRCB, ref rightADR.m_RCB, rightADR.NodeCountRCB);
                break;

            case 1:
                Crossover(ref m_BranchADR.m_RBB, m_BranchADR.NodeCountRBB, ref rightADR.m_RBB, rightADR.NodeCountRBB);
                break;

            case 2:
                Crossover(ref m_BranchADR.m_RUB, m_BranchADR.NodeCountRUB, ref rightADR.m_RUB, rightADR.NodeCountRUB);
                break;

            case 3:
                Crossover(ref m_BranchADR.m_RGB, m_BranchADR.NodeCountRGB, ref rightADR.m_RGB, rightADR.NodeCountRGB);
                break;
            }

            //
            // Make sure the program stats get updated for both programs
            m_Branch.UpdateStats();
            sibling.UpdateStats();
        }
Beispiel #3
0
        /// <summary>
        /// Returns the value located at the memory cell.  A mod function is used
        /// to prevent from accessing a value out of bounds.
        /// </summary>
        /// <param name="tree"></param>
        /// <param name="execBranch"></param>
        /// <returns></returns>
        public override double EvaluateAsDouble(GPProgram tree, GPProgramBranch execBranch)
        {
            //
            // return the memory value
            double p1  = Math.Abs(this.Children[0].EvaluateAsDouble(tree, execBranch));
            int    Pos = Math.Abs(((int)p1) % tree.CountMemory);

            return(GPProgram.m_Memory[Pos]);
        }
Beispiel #4
0
        /// <summary>
        /// A Function node really acts as a reference to make a call into
        /// a Function program branch.  What this method does is to first crawl
        /// through each of the Function parameter subtrees and get their values
        /// computed up.  These values are stored internal to the function
        /// to act as a sort of stack, because each of the subtrees could
        /// make calls to the same Function and we don't want the results to get
        /// overwritten.  Once all the subtrees have been evalutated, the
        /// results are written into the Function parameters and the Function program
        /// branch is called.
        /// </summary>
        /// <param name="tree">Program tree this Function belongs to</param>
        /// <param name="execBranch">Program Branch this Function is executing within</param>
        public override double EvaluateAsDouble(GPProgram tree, GPProgramBranch execBranch)
        {
            GPProgramBranchADF adf = tree.ADF[this.WhichFunction];

            base.PrepareFunctionParameters(tree, execBranch, adf);

            //
            // Evalute the Function program branch
            return(adf.EvaluateAsDouble(tree));
        }
        /// <summary>
        /// Stores the value in memory.
        /// </summary>
        /// <param name="tree"></param>
        /// <param name="execBranch"></param>
        /// <returns>The value just stored in memory</returns>
        public override double EvaluateAsDouble(GPProgram tree, GPProgramBranch execBranch)
        {
            //
            // Set the memory value
            double p1 = Math.Abs(this.Children[0].EvaluateAsDouble(tree, execBranch));
            double p2 = this.Children[1].EvaluateAsDouble(tree, execBranch);

            GPProgram.m_Memory[Math.Abs(((int)p1) % tree.CountMemory)] = p2;

            return(p2);
        }
        /// <summary>
        /// This method directs the construction of an RPB
        /// </summary>
        /// <param name="Branch"></param>
        /// <param name="TreeBuild"></param>
        /// <returns></returns>
        public override bool Build(GPProgramBranch Branch, GPEnums.TreeBuild TreeBuild)
        {
            m_Branch = Branch;
            //
            // Call the recursive method to create the tree
            m_Branch.Root = BuildInternal(TreeBuild, m_Branch.DepthInitial, 0, false);

            //
            // Update the tree stats
            m_Branch.UpdateStats();

            //
            // Convert the program into array representation
            m_Branch.ConvertToArray(m_Config.FunctionSet);

            return(true);
        }
        /// <summary>
        /// Evaluates the parameters to a function before the function is called.
        /// </summary>
        /// <param name="tree">Program tree this Function belongs to</param>
        /// <param name="execBranch">Program Branch this Function is executing within</param>
        public void PrepareFunctionParameters(GPProgram tree, GPProgramBranch execBranch, GPProgramBranchADRoot ADFunction)
        {
            //
            // Compute the parameters to the Function
            short nNumberArgs = ADFunction.NumberArgs;

            double[] argResult = new double[nNumberArgs];
            for (int nParam = 0; nParam < nNumberArgs; nParam++)
            {
                argResult[nParam] = ((GPNode)m_Children[nParam]).EvaluateAsDouble(tree, execBranch);
            }
            //
            // Place the results into the Function program branch
            for (int nParam = 0; nParam < nNumberArgs; nParam++)
            {
                ADFunction.ParamResults[nParam] = argResult[nParam];
            }
        }
        /// <summary>
        /// Construct the four branching structures
        /// </summary>
        /// <param name="Branch">Reference to the ADR branch</param>
        /// <param name="TreeBuild">Tree building technqiue</param>
        /// <returns>True if the branch was correctly constructed</returns>
        public override bool Build(GPProgramBranch Branch, GPEnums.TreeBuild TreeBuild)
        {
            m_Branch = m_BranchADR = (GPProgramBranchADR)Branch;

            //
            // We create 4 different branching structures: RCB, RBB, RUB, RGB
            m_BranchADR.RCB = BuildInternal(TreeBuild, m_Branch.DepthInitial, false);
            m_BranchADR.RBB = BuildInternal(TreeBuild, m_Branch.DepthInitial, true);
            m_BranchADR.RUB = BuildInternal(TreeBuild, m_Branch.DepthInitial, false);
            m_BranchADR.RGB = BuildInternal(TreeBuild, m_Branch.DepthInitial, false);

            //
            // Update the tree stats
            m_Branch.UpdateStats();

            //
            // Convert the program into array representation
            m_Branch.ConvertToArray(m_Config.FunctionSet);

            return(true);
        }
Beispiel #9
0
        /// <summary>
        /// Recursively work through the nodes in the tree, checking the children
        /// first and then checking the current node.  If a node is able to be combined,
        /// then a new terminal node is created and it is returned, instead of the
        /// original subtree.
        /// </summary>
        public override GPNode Edit(GPProgram tree, GPProgramBranch execBranch)
        {
            //
            // Can not use a 'foreach' structure here because we need to replace
            // the child with whatever it returns of itself.
            for (int Child = 0; Child < m_Children.Count; Child++)
            {
                m_Children[Child] = m_Children[Child].Edit(tree, execBranch);
            }

            //
            // If all the children to this node are numbers, a simplification
            // can be performed.
            bool AllNumbers = true;

            foreach (GPNode child in m_Children)
            {
                if (!(child is GPNodeTerminalDouble || child is GPNodeTerminalInteger))
                {
                    AllNumbers = false;
                    break;
                }
            }
            //
            // The test to see if there are more than 0 arguments was added because
            // the time series functions may not have any parameters and they shouldn't
            // be converted to numeric terminals.
            if (AllNumbers && this.NumberArgs > 0)
            {
                //
                // Exec the function and replace with a new terminal node
                double result = this.EvaluateAsDouble(tree, execBranch);
                //
                // Create a new terminal node
                GPNodeTerminalDouble NodeNew = new GPNodeTerminalDouble(result);

                return(NodeNew);
            }
            return(this);
        }
        /// <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();
        }
Beispiel #11
0
 /// <summary>
 /// Terminals require no editing
 /// </summary>
 public override GPNode Edit(GPProgram tree, GPProgramBranch execBranch)
 {
     return(this);
 }
 public GPProgramBranchFactory(GPProgramBranch Branch, GPModelerServer Config)
 {
     m_Branch = Branch;
     m_Config = Config;
 }
 /// <summary>
 /// Override from GPNode for implicit evaluation
 /// </summary>
 /// <param name="tree"></param>
 /// <param name="execBranch"></param>
 /// <returns></returns>
 public override double EvaluateAsDouble(GPProgram tree, GPProgramBranch execBranch)
 {
     return((double)this.Value);
 }
Beispiel #14
0
 /// <summary>
 /// Override from GPNode for implicit evaluation
 /// </summary>
 /// <param name="tree"></param>
 /// <param name="execBranch"></param>
 /// <returns>value of the terminal</returns>
 public override double EvaluateAsDouble(GPProgram tree, GPProgramBranch execBranch)
 {
     return(((GPProgramBranchADL)execBranch).ParamResults[this.WhichParameter]);
 }
Beispiel #15
0
 //
 // Override from GPNode for implicit evaluation
 public override double EvaluateAsDouble(GPProgram tree, GPProgramBranch execBranch)
 {
     return(tree.UserTerminals[this.WhichUserDefined]);
 }
 //
 // All derived classes must implement the following methods
 public abstract bool Build(GPProgramBranch Branch, GPEnums.TreeBuild TreeBuild);
 public abstract void Crossover(GPProgramBranch sibling);
Beispiel #18
0
 /// <summary>
 /// All derived classes must implement the editing genetic operator
 /// </summary>
 public abstract GPNode Edit(GPProgram tree, GPProgramBranch execBranch);
Beispiel #19
0
 /// <summary>
 /// These are the base "evaluate" methods that provide the implicit interpreter
 /// </summary>
 public abstract double EvaluateAsDouble(GPProgram tree, GPProgramBranch execBranch);