/// <summary> /// Randomly creates a new GPNode appropriate for an ADF branch. /// </summary> private GPNode CreateNode(GPEnums.TreeBuild TreeBuild, int Depth, bool TerminalOnly) { // // If required, create a terminal node only if (TerminalOnly) { return(CreateNodeTerminal()); } // // if the depth is the Initial Max Depth (i.e. the first node in the tree) // automaticaly choose a function, don't want to waste our time with a // terminal. Also, 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 (Depth == m_Branch.Depth || (TreeBuild == GPEnums.TreeBuild.Full && Depth > 0)) { // // We can create function nodes that use other ADFs that come after this // one, this prevents recursion that we don't want from happening. // TODO: Need to decide if ADFs or ADLs should be created first and which // can call which. return(CreateNodeFunction(true, m_BranchADF.WhichFunction + 1, false, 0, false, 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, m_BranchADF.WhichFunction + 1, false, 0, false, 0)); } // // TODO: Throw an exception that something really, really bad happened! return(null); }
/// <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); }
/// <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> /// Create a brand spanking new baby program tree! /// </summary> /// <param name="Depth">Max depth the tree can be</param> /// <param name="treeBuild">Tree building technique</param> /// <returns>Newly constructed program</returns> public GPProgram Construct(int nDepth, GPEnums.TreeBuild treeBuild) { // // Create an empty program tree m_Program = new GPProgram(null); // // We start by creating the ADFs first, because we want them available // to the RPB when it is created. // // Create some ADF branches for (short ADF = 0; ADF < m_Config.ADFSet.Count; ADF++) { GPProgramBranchADF adfBranch = new GPProgramBranchADF(m_Program, nDepth, ADF, m_Config.ADFSet[ADF]); m_OperatorADF.Build(adfBranch, treeBuild); m_Program.ADF.Add(adfBranch); } // // Create some ADL branches for (short ADL = 0; ADL < m_Config.ADLSet.Count; ADL++) { GPProgramBranchADL adlBranch = new GPProgramBranchADL(m_Program, nDepth, ADL, m_Config.ADLSet[ADL]); m_OperatorADL.Build(adlBranch, treeBuild); m_Program.ADL.Add(adlBranch); } // // Create some ADR branches for (short ADR = 0; ADR < m_Config.ADRSet.Count; ADR++) { GPProgramBranchADR adrBranch = new GPProgramBranchADR(m_Program, nDepth, ADR, m_Config.ADRSet[ADR]); m_OperatorADR.Build(adrBranch, treeBuild); m_Program.ADR.Add(adrBranch); } // // Build the RPB branch m_Program.RPB = new GPProgramBranchRPB(m_Program, m_Program.ADF.Count, nDepth, treeBuild); m_OperatorRPB.Build(m_Program.RPB, treeBuild); return(m_Program); }
/// <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); }
/// <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); }
public GPProgramBranchRPB(GPProgram parent, int nNumberADF, int nInitialDepth, GPEnums.TreeBuild treeBuild) : base(parent, nInitialDepth) { }
// // All derived classes must implement the following methods public abstract bool Build(GPProgramBranch Branch, GPEnums.TreeBuild TreeBuild);