/// <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(); } }
/// <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(); }