/// <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> /// Static method to randomly create a terminal node /// TODO: Need to override this method for each type, all that if logic is stupid! /// </summary> /// <param name="bADF"></param> /// <param name="ADFArgCount"></param> /// <param name="bADL"></param> /// <param name="ADLArgCount"></param> /// <param name="bADR"></param> /// <param name="ADRArgCount"></param> /// <param name="TerminalSet"></param> /// <param name="IntegerMin"></param> /// <param name="IntegerMax"></param> /// <returns></returns> public static GPNodeTerminal Initialize( bool bADF, short ADFArgCount, bool bADL, short ADLArgCount, bool bADR, short ADRArgCount, List <GPEnums.TerminalType> TerminalSet, int IntegerMin, int IntegerMax) { short Random = 0; GPNodeTerminal node; // // Go through the terminal set and count up the number of user // define terminal types. short UserDefined = 0; for (short Terminal = 0; Terminal < TerminalSet.Count; Terminal++) { if (TerminalSet[Terminal] == GPEnums.TerminalType.UserDefined) { UserDefined++; } } // // If we have an ADF, then see if we randomly select the terminal to // be a function parameter or a random constant. The (TerminalSet.Count-UserDefined) // is to get down to just the random constant options. if (bADF) { Random = (short)GPUtilities.rngNextInt(ADFArgCount + (TerminalSet.Count - UserDefined)); if (Random < ADFArgCount) { node = new GPNodeTerminalADFParam(Random); return(node); } // // Update the random selection to be one of the random constant options Random -= ADFArgCount; Random += UserDefined; } // // If we have an ADL, do the same kind of thing as above for ADFs if (bADL) { Random = (short)GPUtilities.rngNextInt(ADLArgCount + (TerminalSet.Count - UserDefined)); if (Random < ADLArgCount) { node = new GPNodeTerminalADLParam(Random); return(node); } // // Update the random selection to be one of the random constant options Random -= ADLArgCount; Random += UserDefined; } // // Same story for ADRs if (bADR) { Random = (short)GPUtilities.rngNextInt(ADRArgCount + (TerminalSet.Count - UserDefined)); if (Random < ADRArgCount) { node = new GPNodeTerminalADRParam(Random); return(node); } // // Update the random selection to be one of the random constant options Random -= ADRArgCount; Random += UserDefined; } // // If an RPB terminal, select from anything in the terminal set if (!bADF && !bADL && !bADR) { Random = (short)GPUtilities.rngNextInt(TerminalSet.Count); } // // It is a user defined terminal if (Random < UserDefined) { return(new GPNodeTerminalUserDefined(Random)); } // // It is either an integer or double terminal if (TerminalSet[Random] == GPEnums.TerminalType.RandomDouble) { return(new GPNodeTerminalDouble(GPUtilities.rngNextDouble())); } else { return(new GPNodeTerminalInteger(GPUtilities.rngNextInt(IntegerMin, IntegerMax))); } }