/// <summary> /// Constructs a Function node based upon the XML specification /// </summary> /// <param name="FunctionNode"></param> /// <returns></returns> private GPNode CreateFunction(XmlNode FunctionNode) { XmlNode xmlType = FunctionNode.SelectSingleNode("Function"); XmlNodeList listParams = FunctionNode.SelectNodes("GPNode"); GPNodeFunction gpFunction = null; // // See if we have an ADF if (xmlType.InnerText == "ADF") { XmlNode xmlWhichADF = FunctionNode.SelectSingleNode("WhichFunction"); int WhichADF = Convert.ToInt32(xmlWhichADF.InnerText); gpFunction = new GPNodeFunctionADF(WhichADF, (byte)listParams.Count); } else if (xmlType.InnerText == "ADL") // Check for an ADL { XmlNode xmlWhichADL = FunctionNode.SelectSingleNode("WhichFunction"); int WhichADL = Convert.ToInt32(xmlWhichADL.InnerText); gpFunction = new GPNodeFunctionADL(WhichADL, (byte)listParams.Count); } else if (xmlType.InnerText == "ADR") // Check for an ADR { XmlNode xmlWhichADR = FunctionNode.SelectSingleNode("WhichFunction"); int WhichADR = Convert.ToInt32(xmlWhichADR.InnerText); gpFunction = new GPNodeFunctionADR(WhichADR, (byte)listParams.Count); } else { // // Get the correct function node type created GPNodeFunction func = (GPNodeFunction)m_FunctionSet[xmlType.InnerText.ToUpper()]; gpFunction = (GPNodeFunction)func.Clone(); } // // Build the list of parameters to this node foreach (XmlNode ParamNode in listParams) { gpFunction.Children.Add(ReadGPNode(ParamNode)); } return(gpFunction); }
/// <summary> /// Restores a node from the array representation back into a tree representation /// </summary> /// <param name="FunctionSet"></param> /// <returns>Reference to the converted tree</returns> public GPNode ConvertNode(IGPFunctionSet FunctionSet) { // // Determine the type of the node // < 200 : User Defined function // 200 to 210 : Terminal // 253 : ADR // 254 : ADL // 255 : ADF if (m_TreeArrayNew[m_ArrayPos] == 255) { m_ArrayPos++; byte WhichADF = m_TreeArrayNew[m_ArrayPos++]; byte NumberArgs = m_TreeArrayNew[m_ArrayPos++]; GPNodeFunctionADF NodeNew = new GPNodeFunctionADF(WhichADF, NumberArgs); // // Build up the children before returning for (byte Child = 0; Child < NumberArgs; Child++) { NodeNew.Children.Add(ConvertNode(FunctionSet)); } return(NodeNew); } else if (m_TreeArrayNew[m_ArrayPos] == 254) { m_ArrayPos++; byte WhichADL = m_TreeArrayNew[m_ArrayPos++]; byte NumberArgs = m_TreeArrayNew[m_ArrayPos++]; GPNodeFunctionADL NodeNew = new GPNodeFunctionADL(WhichADL, NumberArgs); // // Build up the children before returning for (byte Child = 0; Child < NumberArgs; Child++) { NodeNew.Children.Add(ConvertNode(FunctionSet)); } return(NodeNew); } else if (m_TreeArrayNew[m_ArrayPos] == 253) { m_ArrayPos++; byte WhichADR = m_TreeArrayNew[m_ArrayPos++]; byte NumberArgs = m_TreeArrayNew[m_ArrayPos++]; GPNodeFunctionADR NodeNew = new GPNodeFunctionADR(WhichADR, NumberArgs); // // Build up the children before returning for (byte Child = 0; Child < NumberArgs; Child++) { NodeNew.Children.Add(ConvertNode(FunctionSet)); } return(NodeNew); } else if (m_TreeArrayNew[m_ArrayPos] < 200) { GPNodeFunction NodeNew = (GPNodeFunction)((GPNodeFunction)FunctionSet[m_TreeArrayNew[m_ArrayPos++]]).Clone(); // // Build up this node's children first byte ChildCount = m_TreeArrayNew[m_ArrayPos++]; for (byte Child = 0; Child < ChildCount; Child++) { NodeNew.Children.Add(ConvertNode(FunctionSet)); } return(NodeNew); } else // Terminal { switch (m_TreeArrayNew[m_ArrayPos++]) { case 200: byte WhichADFParam = m_TreeArrayNew[m_ArrayPos++]; GPNodeTerminalADFParam NodeADF = new GPNodeTerminalADFParam(WhichADFParam); return(NodeADF); case 201: byte WhichUserDefined = m_TreeArrayNew[m_ArrayPos++]; GPNodeTerminalUserDefined NodeUser = new GPNodeTerminalUserDefined(WhichUserDefined); return(NodeUser); case 202: double dValue; unsafe { byte *ptr = (byte *)&dValue; for (int pos = 0; pos < sizeof(double); pos++) { ptr[pos] = m_TreeArrayNew[m_ArrayPos++]; } } GPNodeTerminalDouble NodeDouble = new GPNodeTerminalDouble(dValue); return(NodeDouble); case 203: int nValue; unsafe { byte *ptr = (byte *)&nValue; for (int pos = 0; pos < sizeof(int); pos++) { ptr[pos] = m_TreeArrayNew[m_ArrayPos++]; } } GPNodeTerminalInteger NodeInteger = new GPNodeTerminalInteger(nValue); return(NodeInteger); } } // // TODO: Throw an exception, instead of this lazy crap! :) return(null); }
/// <summary> /// Converts a tree node into an array based representation. For functions /// an byte lookup is used into the FunctionSet, for terminals, the type /// is recorded along with whatever extra data may be needed. /// TODO: Get rid of the unsafe code. I know there is a bit conversion /// function, I just couldn't find it quickly. /// </summary> /// <param name="Node">The node to convert</param> /// <param name="FunctionSet"></param> private void StoreNode(GPNode Node, IGPFunctionSet FunctionSet) { // // Figure out what kind of node we have and store it accordingly. if (Node is GPNodeFunction) { GPNodeFunction NodeFunction = (GPNodeFunction)Node; if (NodeFunction is GPNodeFunctionADF) { GPNodeFunctionADF adf = (GPNodeFunctionADF)NodeFunction; // // For an ADF node,record it as value 255 and then store the which // ADF it refers to and the number of arguments. m_TreeArrayNew.Add((byte)255); m_TreeArrayNew.Add((byte)adf.WhichFunction); m_TreeArrayNew.Add(adf.NumberArgs); } else if (NodeFunction is GPNodeFunctionADL) { GPNodeFunctionADL adl = (GPNodeFunctionADL)NodeFunction; // // For an ADL node,record it as value 254 and then store the which // ADL it refers to and the number of arguments. m_TreeArrayNew.Add((byte)254); m_TreeArrayNew.Add((byte)adl.WhichFunction); m_TreeArrayNew.Add(adl.NumberArgs); } else if (NodeFunction is GPNodeFunctionADR) { GPNodeFunctionADR adr = (GPNodeFunctionADR)NodeFunction; // // For an ADR node,record it as value 253 and then store the which // ADR it refers to and the number of arguments. m_TreeArrayNew.Add((byte)253); m_TreeArrayNew.Add((byte)adr.WhichFunction); m_TreeArrayNew.Add(adr.NumberArgs); } else { // // Store the index of the function and then the number of children // for this function m_TreeArrayNew.Add((byte)FunctionSet.IndexOfKey(NodeFunction.ToStringUpper())); m_TreeArrayNew.Add((byte)((GPNodeFunction)Node).Children.Count); } // // Store each of the children foreach (GPNode NodeChild in NodeFunction.Children) { StoreNode(NodeChild, FunctionSet); } } else // Terminal Node { // // Depending upon the type of the terminal, set the appropriate value if (Node is GPNodeTerminalADFParam) { m_TreeArrayNew.Add(200); m_TreeArrayNew.Add((byte)((GPNodeTerminalADFParam)Node).WhichParameter); } else if (Node is GPNodeTerminalUserDefined) { m_TreeArrayNew.Add(201); m_TreeArrayNew.Add((byte)((GPNodeTerminalUserDefined)Node).WhichUserDefined); } else if (Node is GPNodeTerminalDouble) { m_TreeArrayNew.Add(202); double dValue = ((GPNodeTerminalDouble)Node).Value; unsafe { byte *ptr = (byte *)&dValue; for (int pos = 0; pos < sizeof(double); pos++) { m_TreeArrayNew.Add(ptr[pos]); } } } else if (Node is GPNodeTerminalInteger) { m_TreeArrayNew.Add(203); int dValue = ((GPNodeTerminalInteger)Node).Value; unsafe { byte *ptr = (byte *)&dValue; for (int pos = 0; pos < sizeof(int); pos++) { m_TreeArrayNew.Add(ptr[pos]); } } } } }
/// <summary> /// This is a simple factory function that selects from the available /// list of functions and creates a class of that type. /// </summary> /// <param name="UseADF">Select from ADFs</param> /// <param name="StartADF">Which ADF to start choosing from</param> /// <param name="UseADL">Select from ADLs</param> /// <param name="StartADL">Which ADL to start choosing from</param> /// <param name="UseADR">Select from ADRs</param> /// <param name="StartADR">Which ADR to start choosing from</param> protected GPNode CreateNodeFunction(bool UseADF, int StartADF, bool UseADL, int StartADL, bool UseADR, int StartADR) { // // Add up all the different function types that we can choose from // *"Regular" function types sent over from the client // *ADFs // *ADLs // *ADRs int Count = m_Config.FunctionSet.Count; if (UseADF) { Count += m_Branch.Parent.ADF.Count - StartADF; } if (UseADL) { Count += m_Branch.Parent.ADL.Count - StartADL; } if (UseADR) { Count += m_Branch.Parent.ADR.Count - StartADR; } // // Randomly select from the function node choices. int Function = GPUtilities.rngNextInt(Count); // // See if we chose a "regular" function if (Function < m_Config.FunctionSet.Count) { GPNodeFunction Type = (GPNodeFunction)m_Config.FunctionSet[Function]; return((GPNodeFunction)Type.Clone()); } // // See if we chose an ADF Function -= m_Config.FunctionSet.Count; if (Function < (m_Branch.Parent.ADF.Count - StartADF)) { int WhichADF = StartADF + Function; byte NumberArgs = m_Branch.Parent.ADF[WhichADF].NumberArgs; GPNodeFunctionADF adfFunc = new GPNodeFunctionADF(WhichADF, NumberArgs); return(adfFunc); } // // See if we chose an ADL Function -= m_Config.ADFSet.Count; if (Function < (m_Branch.Parent.ADL.Count - StartADL)) { int WhichADL = StartADL + Function; byte NumberArgs = m_Branch.Parent.ADL[WhichADL].NumberArgs; GPNodeFunctionADL adlFunc = new GPNodeFunctionADL(WhichADL, NumberArgs); return(adlFunc); } // // See if we chose an ADR Function -= m_Config.ADLSet.Count; if (Function < (m_Branch.Parent.ADR.Count - StartADR)) { int WhichADR = StartADR + Function; byte NumberArgs = m_Branch.Parent.ADR[WhichADR].NumberArgs; GPNodeFunctionADR adrFunc = new GPNodeFunctionADR(WhichADR, NumberArgs); return(adrFunc); } return(null); }
/// <summary> /// Given a tree node, the node is translated into code, this method is /// recursively called for each of the node's children. /// </summary> /// <param name="node">The node to translate</param> protected void WriteProgramBody(GPNode node) { // // Recursively work through the nodes if (node is GPNodeTerminal) { m_Writer.Write(((GPNodeTerminal)node).ToString()); // // There are no children, so don't need to make a recursive call } else if (node is GPNodeFunction) { if (node is GPNodeFunctionADF) { GPNodeFunctionADF adf = (GPNodeFunctionADF)node; m_Writer.Write("\n\t\tADF" + adf.WhichFunction); m_Writer.Write("("); // // The parameters to the ADF are its children for (int Param = 0; Param < adf.NumberArgs; Param++) { if (Param > 0) { m_Writer.Write(","); } WriteProgramBody(((GPNodeFunction)node).Children[Param]); } m_Writer.Write(")\n\t\t"); } else if (node is GPNodeFunctionADL) { GPNodeFunctionADL adl = (GPNodeFunctionADL)node; m_Writer.Write("\n\t\tADL" + adl.WhichFunction); m_Writer.Write("("); // // The parameters to the ADL are its children for (int Param = 0; Param < adl.NumberArgs; Param++) { if (Param > 0) { m_Writer.Write(","); } WriteProgramBody(((GPNodeFunction)node).Children[Param]); } m_Writer.Write(")\n\t\t"); } else if (node is GPNodeFunctionADR) { GPNodeFunctionADR adr = (GPNodeFunctionADR)node; m_Writer.Write("\n\t\tADR" + adr.WhichFunction); m_Writer.Write("("); // // The parameters to the ADR are its children for (int Param = 0; Param < adr.NumberArgs; Param++) { if (Param > 0) { m_Writer.Write(","); } WriteProgramBody(((GPNodeFunction)node).Children[Param]); } m_Writer.Write(")\n\t\t"); } else if (node is GPNodeFunctionSetMem) { m_Writer.Write("\n\t\tSetMem("); WriteProgramBody(((GPNodeFunction)node).Children[0]); m_Writer.Write(","); WriteProgramBody(((GPNodeFunction)node).Children[1]); m_Writer.Write(")"); } else if (node is GPNodeFunctionGetMem) { m_Writer.Write("\n\t\tGetMem("); WriteProgramBody(((GPNodeFunction)node).Children[0]); m_Writer.Write(")"); } else { m_Writer.Write("\n\t\t" + node.ToString() + "("); // // The parameters to the function are its children for (short Param = 0; Param < m_FunctionSet[node.ToString().ToUpper()].Arity; Param++) { if (Param > 0) { m_Writer.Write(","); } WriteProgramBody(((GPNodeFunction)node).Children[Param]); } m_Writer.Write(")"); } } else { Console.WriteLine("Have an undefined node we are tying to write"); } }
// // Gets the function nodes written out private void WriteFunctionNodeBody(GPNode node) { GPNodeFunction nodeFunc = (GPNodeFunction)node; String sType = node.GetType().ToString(); if (node is GPNodeFunctionADF) { GPNodeFunctionADF nodeADF = (GPNodeFunctionADF)nodeFunc; m_xmlWriter.WriteStartElement("Function"); m_xmlWriter.WriteValue("ADF"); m_xmlWriter.WriteEndElement(); // // Write out "which" ADF function this is m_xmlWriter.WriteStartElement("WhichFunction"); m_xmlWriter.WriteValue(nodeADF.WhichFunction); m_xmlWriter.WriteEndElement(); for (int nParam = 0; nParam < nodeADF.NumberArgs; nParam++) { WriteProgramNode(nodeADF.Children[nParam]); } } else if (node is GPNodeFunctionADL) { GPNodeFunctionADL nodeADL = (GPNodeFunctionADL)nodeFunc; m_xmlWriter.WriteStartElement("Function"); m_xmlWriter.WriteValue("ADL"); m_xmlWriter.WriteEndElement(); // // Write out "which" ADL function this is m_xmlWriter.WriteStartElement("WhichFunction"); m_xmlWriter.WriteValue(nodeADL.WhichFunction); m_xmlWriter.WriteEndElement(); for (int nParam = 0; nParam < nodeADL.NumberArgs; nParam++) { WriteProgramNode(nodeADL.Children[nParam]); } } else if (node is GPNodeFunctionADR) { GPNodeFunctionADR nodeADR = (GPNodeFunctionADR)nodeFunc; m_xmlWriter.WriteStartElement("Function"); m_xmlWriter.WriteValue("ADR"); m_xmlWriter.WriteEndElement(); // // Write out "which" ADR function this is m_xmlWriter.WriteStartElement("WhichFunction"); m_xmlWriter.WriteValue(nodeADR.WhichFunction); m_xmlWriter.WriteEndElement(); for (int nParam = 0; nParam < nodeADR.NumberArgs; nParam++) { WriteProgramNode(nodeADR.Children[nParam]); } } else { m_xmlWriter.WriteStartElement("Function"); m_xmlWriter.WriteValue(nodeFunc.ToString()); m_xmlWriter.WriteEndElement(); // // Write out its children for (int nParam = 0; nParam < nodeFunc.NumberArgs; nParam++) { WriteProgramNode(nodeFunc.Children[nParam]); } } }