/// <summary> /// Compute the fitness of the entire Population and return the value of /// the best program in the Population. /// </summary> public void EvaluateFitness(int Generation) { // // First time through the fitness object doesn't exist, so have to create it if (m_Fitness == null) { m_Fitness = new GPFitness( this, this.Training, GPEnums.RESULTS_TOLERANCE, m_FunctionSet.UseInputHistory); } m_BestProgram = m_Fitness.Compute(Generation, m_Population); // // Always simplify a program before it is transmitted. m_BestProgram.ConvertToTree(this.FunctionSet, false); m_BestProgram.Edit(); m_BestProgram.ConvertToArray(this.FunctionSet); // // Obtain the Population stats m_Population.ComputeComplexity( out m_PopulationComplexityMin, out m_PopulationComplexityMax, out m_PopulationComplexityAve); }
/// <summary> /// Select two parents, based upon fitness, for a crossover operation. /// Place the two children into the new Population. /// </summary> /// <param name="PopNew">Population to add the newly created program to</param> private void Crossover(GPPopulation PopNew, GPFitnessObjectiveBase FitnessSelection) { GPProgram Child1 = (GPProgram)FitnessSelection.Programs(ExecProgramSelection()).Clone(); GPProgram Child2 = (GPProgram)FitnessSelection.Programs(ExecProgramSelection()).Clone(); // // Convert to trees Child1.ConvertToTree(m_ModelerConfig.FunctionSet, false); Child2.ConvertToTree(m_ModelerConfig.FunctionSet, false); // // Perform the crossover m_TreeFactory.Attach(Child1); Child2 = m_TreeFactory.Crossover(Child2); // // Convert to arrays Child1.ConvertToArray(m_ModelerConfig.FunctionSet); Child2.ConvertToArray(m_ModelerConfig.FunctionSet); // // Add them to the new Population PopNew.Programs.Add(Child1); if (PopNew.Count < m_PopCurrent.Count) { PopNew.Programs.Add(Child2); } }
/// <summary> /// Parse an ADR branch /// </summary> /// <param name="adrNode"></param> /// <param name="WhichADR"></param> /// <param name="Program"></param> /// <returns>ADR program branch</returns> private GPProgramBranchADR LoadBranchADR(XmlNode adrNode, short WhichADR, GPProgram Program) { // // First step, parse out the number of arguments XmlNode xmlNode = adrNode.SelectSingleNode("ParameterCount"); byte ParameterCount = Convert.ToByte(xmlNode.InnerText); // // Create the Branch tree GPProgramBranchADR adr = new GPProgramBranchADR(Program, 0, WhichADR, ParameterCount); // // There are four branches to read, do each of them separately xmlNode = adrNode.SelectSingleNode("RCB"); adr.RCB = ReadGPNode(xmlNode.SelectSingleNode("GPNode")); xmlNode = adrNode.SelectSingleNode("RBB"); adr.RBB = ReadGPNode(xmlNode.SelectSingleNode("GPNode")); xmlNode = adrNode.SelectSingleNode("RUB"); adr.RUB = ReadGPNode(xmlNode.SelectSingleNode("GPNode")); xmlNode = adrNode.SelectSingleNode("RGB"); adr.RGB = ReadGPNode(xmlNode.SelectSingleNode("GPNode")); adr.UpdateStats(); return(adr); }
/// <summary> /// This method creates the initial class header and declaration /// that is required before any methods can be written. /// </summary> /// <param name="Program">Source program</param> /// <returns>True/False upon success or failure</returns> public override bool WriteHeader(GPProgram Program) { m_Writer.WriteLine("import java.util.*;"); m_Writer.WriteLine(); return(base.WriteHeader(Program)); }
/// <summary> /// Execute the recursion /// </summary> public double EvaluateAsDouble(GPProgram tree) { if (m_RecursionCount >= MAXRECURSIONS || Unwind) { Unwind = true; m_RecursionCount--; double Result = m_RGB.EvaluateAsDouble(tree, this); if (m_RecursionCount == 0) { Unwind = false; } return(Result); } m_RecursionCount++; if (m_RCB.EvaluateAsDouble(tree, this) > 0.0) { m_RBB.EvaluateAsDouble(tree, this); m_RUB.EvaluateAsDouble(tree, this); } m_RecursionCount--; return(m_RGB.EvaluateAsDouble(tree, this)); }
public GPLanguageWriterFortran(GPProgram Program, bool TimeSeries, SortedDictionary <String, GPLanguageWriter.tagUserDefinedFunction> FunctionSet) : base(Program, TimeSeries) { m_FunctionSet = FunctionSet; // // Prepare a list of all possible Fortran intrinsics. This way, if the user // ever defines a function that is the same as an intrinsic, the intrinsic is // used instead of making a mess of things by declaring a user defined function // of the same name. FunctionIntrinsics = new SortedList <string, string>(); FunctionIntrinsics.Add("SIN", "SIN"); FunctionIntrinsics.Add("ASIN", "ASIN"); FunctionIntrinsics.Add("SINH", "SINH"); FunctionIntrinsics.Add("COS", "COS"); FunctionIntrinsics.Add("ACOS", "ACOS"); FunctionIntrinsics.Add("COSH", "COSH"); FunctionIntrinsics.Add("TAN", "TAN"); FunctionIntrinsics.Add("ATAN", "ATAN"); FunctionIntrinsics.Add("TANH", "TANH"); FunctionIntrinsics.Add("ATAN2", "ATAN2"); FunctionIntrinsics.Add("EXP", "EXP"); FunctionIntrinsics.Add("LOG", "LOG"); FunctionIntrinsics.Add("LOG10", "LOG10"); FunctionIntrinsics.Add("SQRT", "SQRT"); FunctionIntrinsics.Add("ABS", "ABS"); FunctionIntrinsics.Add("IABS", "IABS"); FunctionIntrinsics.Add("NINT", "NINT"); FunctionIntrinsics.Add("ANINT", "ANINT"); FunctionIntrinsics.Add("MIN", "MIN"); FunctionIntrinsics.Add("MAX", "MAX"); FunctionIntrinsics.Add("FLOOR", "FLOOR"); FunctionIntrinsics.Add("CEILING", "CEILING"); }
/// <summary> /// Constructor where the settings for creating the Function are specified. /// </summary> /// <param name="parent">Reference to the program this Function belongs to</param> /// <param name="InitialDepth">Max depth an new tree can be constructed</param> /// <param name="WhichFunction">Numeric indicator of "which" Function this is in the program</param> /// <param name="NumberArgs">Count of arguments this Function will accept</param> public GPProgramBranchADRoot(GPProgram parent, int InitialDepth, short WhichFunction, byte NumberArgs) : base(parent, InitialDepth) { this.WhichFunction = WhichFunction; this.NumberArgs = NumberArgs; m_ParamResults = new double[NumberArgs]; }
private const int MAXRECURSIONS = 25; // TODO: Think about parameterizing this /// <summary> /// Perform the genetic operation of editing on this program branch /// </summary> public override void Edit(GPProgram tree) { this.RCB.Edit(tree, this); this.RBB.Edit(tree, this); this.RUB.Edit(tree, this); this.RGB.Edit(tree, this); }
/// <summary> /// C#/Java represent the program as a class that can be incorporated into /// another program. This method writes the class header for the "Program". /// </summary> /// <param name="Program">The program object we are translating</param> /// <returns>True/False upon success or failure</returns> public override bool WriteHeader(GPProgram Program) { m_Writer.WriteLine("public class GeneticProgram"); m_Writer.WriteLine("{"); m_Writer.WriteLine(); // // Write the indexed memory m_Writer.WriteLine("\tpublic double[] m_Memory = null;"); // // Write the input history m_Writer.WriteLine("\tprivate " + ListType + "<" + ListType + "<" + DoubleType + ">> InputHistory;"); m_Writer.WriteLine(); // // Write the constructor - have it initialize the indexed memory and Input History m_Writer.WriteLine("\tpublic GeneticProgram()"); m_Writer.WriteLine("\t{"); m_Writer.WriteLine("\t\tm_Memory=new double[" + m_Program.CountMemory + "];"); m_Writer.WriteLine("\t\tInputHistory = new " + ListType + "<" + ListType + "<" + DoubleType + ">>();"); m_Writer.WriteLine("\t}"); m_Writer.WriteLine(); return(true); }
/// <summary> /// Converts the program to the XML String representation /// </summary> /// <param name="Program"></param> /// <returns>XML String representation of the program</returns> private String CreateProgramString(GPProgram Program) { String ProgramString = ""; // // Serialize the program to an XML string Program.ConvertToTree(this.FunctionSet, false); GPLanguageWriterXML ProgramWriterXML = new GPLanguageWriterXML(Program, this.Training.TimeSeries); using (MemoryStream ms = new MemoryStream()) { ProgramWriterXML.Write(ms); ms.Seek(0, SeekOrigin.Begin); using (StreamReader reader = new StreamReader(ms)) { ProgramString = reader.ReadToEnd(); } } // // Convert it back to an array. I forgot to do this and it kept messing // things up as the modeling continued. Program.ConvertToArray(this.FunctionSet); return(ProgramString); }
/// <summary> /// Perform the genetic operation of editing on this program branch /// </summary> public override void Edit(GPProgram tree) { this.LIB.Edit(tree, this); this.LCB.Edit(tree, this); this.LBB.Edit(tree, this); this.LUB.Edit(tree, this); }
/// <summary> /// Parse an ADL branch /// </summary> /// <param name="adlNode"></param> /// <param name="WhichADL"></param> /// <param name="Program"></param> /// <returns></returns> private GPProgramBranchADL LoadBranchADL(XmlNode adlNode, short WhichADL, GPProgram Program) { // // First step, parse out the number of arguments XmlNode xmlNode = adlNode.SelectSingleNode("ParameterCount"); byte ParameterCount = Convert.ToByte(xmlNode.InnerText); // // Create the Branch tree GPProgramBranchADL adl = new GPProgramBranchADL(Program, 0, WhichADL, ParameterCount); // // There are four branches to read, do each of them separately xmlNode = adlNode.SelectSingleNode("LIB"); adl.LIB = ReadGPNode(xmlNode.SelectSingleNode("GPNode")); xmlNode = adlNode.SelectSingleNode("LCB"); adl.LCB = ReadGPNode(xmlNode.SelectSingleNode("GPNode")); xmlNode = adlNode.SelectSingleNode("LBB"); adl.LBB = ReadGPNode(xmlNode.SelectSingleNode("GPNode")); xmlNode = adlNode.SelectSingleNode("LUB"); adl.LUB = ReadGPNode(xmlNode.SelectSingleNode("GPNode")); adl.UpdateStats(); return(adl); }
/// <summary> /// VB.NET represents the program as a class that can be incorporated into /// another program. This method writes the class header for the "Program". /// </summary> /// <param name="Program">The program object we are translating</param> /// <returns>True/False upon success or failure</returns> public override bool WriteHeader(GPProgram Program) { m_Writer.WriteLine("Public Class GeneticProgram"); m_Writer.WriteLine(); // // Write the indexed memory m_Writer.WriteLine("\tPrivate m_Memory(" + m_Program.CountMemory + ") As Double"); m_Writer.WriteLine(); // // Write the input history m_Writer.WriteLine("\tPrivate InputHistory As List(Of List(Of Double))"); m_Writer.WriteLine(); // // Write the constructor - Have it initialize the time series array m_Writer.WriteLine("\tPublic Sub New()"); m_Writer.WriteLine(); m_Writer.WriteLine("\t\tInputHistory = New List(Of List(Of Double))()"); m_Writer.WriteLine(); m_Writer.WriteLine("\tEnd Sub"); m_Writer.WriteLine(); return(true); }
/// <summary> /// TODO: /// </summary> /// <param name="Program">The program object we are translating</param> /// <returns>True/False upon success or failure</returns> public override bool WriteHeader(GPProgram Program) { // // Write prototypes for everything m_Writer.WriteLine("//"); m_Writer.WriteLine("// Function Prototypes"); m_Writer.WriteLine("double SetMem(double p0,double p1);"); m_Writer.WriteLine("double GetMem(double p0);"); // // Write the user defined method prototypes foreach (KeyValuePair <String, GPLanguageWriter.tagUserDefinedFunction> kvp in m_FunctionSet) { StringBuilder Prototype = new StringBuilder(); WriteUserFunctionPrototype(kvp.Value, Prototype); m_Writer.WriteLine(Prototype.ToString() + ";"); } m_Writer.WriteLine(); // // Declare the indexed memory m_Writer.WriteLine(); m_Writer.WriteLine("//"); m_Writer.WriteLine("// Indexed Memory"); m_Writer.WriteLine("double m_Memory[" + m_Program.CountMemory + "];"); m_Writer.WriteLine(); return(true); }
/// <summary> /// Select a program based upon fitness to reproduce into the next generation. /// </summary> /// <param name="PopNew">Population to add the reproduced program into</param> private void Reproduce(GPPopulation PopNew, GPFitnessObjectiveBase FitnessSelection) { GPProgram Copy = (GPProgram)FitnessSelection.Programs(ExecProgramSelection()).Clone(); // // Add this copied child into the new Population PopNew.Programs.Add(Copy); }
/// <summary> /// This method creates the initial class header and declaration /// that is required before any methods can be written. /// </summary> /// <param name="Program">Source program</param> /// <returns>True/False upon success or failure</returns> public override bool WriteHeader(GPProgram Program) { m_Writer.WriteLine("using System;"); m_Writer.WriteLine("using System.Collections.Generic;"); m_Writer.WriteLine(); return(base.WriteHeader(Program)); }
/// <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]); }
/// <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> /// Accept a new seed program that should be inserted into the next /// Population generation. /// </summary> /// <param name="xmlBytes"></param> public void AddSeedProgram(byte[] xmlBytes) { String ProgramXML = DecompressProgram(xmlBytes); GPProgramReaderXML xmlReader = new GPProgramReaderXML(ProgramXML, m_FunctionSet); GPProgram Program = xmlReader.Construct(); if (Program != null) { Program.ConvertToArray(m_FunctionSet); m_SeedPrograms.Add(Program); } }
/// <summary> /// Construct a GPProgram object from an XML program description /// </summary> /// <param name="ProgramXML">Program XML string</param> /// <returns>True/False depending upon success or failure</returns> public bool ProgramFromXML(String ProgramXML) { GPProgramReaderXML xmlReader = new GPProgramReaderXML(ProgramXML, m_FunctionSet); m_Program = xmlReader.Construct(); if (m_Program == null) { return(false); } return(true); }
// // Write out the size of memory in the header public override bool WriteHeader(GPProgram Program) { m_xmlWriter.WriteStartElement("Header"); // // Record the size of memory to use m_xmlWriter.WriteStartElement("MemoryCount"); m_xmlWriter.WriteValue(m_Program.CountMemory); m_xmlWriter.WriteEndElement(); m_xmlWriter.WriteEndElement(); return(true); }
/// <summary> /// TODO: /// </summary> /// <param name="Program">The program object we are translating</param> /// <returns>True/False upon success or failure</returns> public override bool WriteHeader(GPProgram Program) { // // Program declaration WriteFortranString(" PROGRAM GeneticProgram"); // // Declare the indexed memory - damn common block! WriteFortranString(""); WriteFortranString(" REAL Memory(" + m_Program.CountMemory + ")"); WriteFortranString(" COMMON /idxmemory/ Memory"); // // Declare the ADF counters if (Program.ADF.Count > 0) { m_Writer.Write(" INTEGER "); foreach (GPProgramBranchADF adf in Program.ADF) { if (adf.WhichFunction > 0) { m_Writer.Write(","); } m_Writer.Write("CountADF" + adf.WhichFunction); } WriteFortranString(""); m_Writer.Write(" COMMON /ADF/ "); foreach (GPProgramBranchADF adf in Program.ADF) { if (adf.WhichFunction > 0) { m_Writer.Write(","); } m_Writer.Write("CountADF" + adf.WhichFunction); } WriteFortranString(""); } WriteFortranString(""); WriteFortranString(" STOP"); WriteFortranString(" END"); WriteFortranString(""); return(true); }
/// <summary> /// Write the needed support methods and then close off the main program class /// </summary> /// <param name="Program">Program being translated</param> /// <returns>True/False upon success or failure</returns> public override bool WriteTrailer(GPProgram Program) { // // Write the built=in support methods WriteSetMem(); WriteGetMem(); // // Write the user defined methods foreach (KeyValuePair <String, GPLanguageWriter.tagUserDefinedFunction> kvp in m_FunctionSet) { String FunctionCode = WriteUserFunction((GPLanguageWriter.tagUserDefinedFunction)kvp.Value); m_Writer.Write(FunctionCode); } return(true); }
/// <summary> /// Cloneable interface /// </summary> /// <returns>Clone of the object</returns> public Object Clone() { // // Clone the RPB GPProgramBranchRPB rpb = (GPProgramBranchRPB)m_RPB.Clone(); rpb.Parent = this; // // copy the main tree GPProgram tree = new GPProgram(rpb); m_Memory = new double[this.CountMemory]; // // Handle the ADFs tree.m_listADF = new List <GPProgramBranchADF>(); foreach (GPProgramBranchADF adf in m_listADF) { GPProgramBranchADF copy = (GPProgramBranchADF)adf.Clone(); copy.Parent = this; tree.m_listADF.Add(copy); } // // Handle the ADLs tree.m_listADL = new List <GPProgramBranchADL>(); foreach (GPProgramBranchADL adl in m_listADL) { GPProgramBranchADL copy = (GPProgramBranchADL)adl.Clone(); copy.Parent = this; tree.m_listADL.Add(copy); } // // Handle the ADRs tree.m_listADR = new List <GPProgramBranchADR>(); foreach (GPProgramBranchADR adr in m_listADR) { GPProgramBranchADR copy = (GPProgramBranchADR)adr.Clone(); copy.Parent = this; tree.m_listADR.Add(copy); } return(tree); }
/// <summary> /// Performs the fitness computation over the Population /// </summary> /// <param name="Generation"></param> /// <param name="Population"></param> /// <returns></returns> public GPProgram Compute(int Generation, GPPopulation Population) { m_Abort = false; // // Go through the Population and compute the fitness of each // program, returning the best program index. BestProgram = EvaluatePopulation(Generation, Population); m_BestProgramRef = Population.Programs[BestProgram]; if (!m_Abort) { m_FitnessSelection.PrepareFitness(this.FitnessMeasure, Population); } // // return the best program return(m_BestProgramRef); }
/// <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> /// 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> /// 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); }
private const int MAXITERATIONS = 25; // TODO: Think about parameterizing this /// <summary> //// Run this loop /// </summary> public double EvaluateAsDouble(GPProgram tree) { // // Loop initialization m_LIB.EvaluateAsDouble(tree, this); int LoopIndex = 0; // // Go into the loop double Result = 0.0; while ((LoopIndex < MAXITERATIONS) && (m_LCB.EvaluateAsDouble(tree, this) > 0.0)) { Result = m_LBB.EvaluateAsDouble(tree, this); m_LUB.EvaluateAsDouble(tree, this); LoopIndex++; } return(Result); }