/// <summary> /// Recursively work through the nodes in the tree, checking the children /// first and then checking the current node. If a node is able to be combined, /// then a new terminal node is created and it is returned, instead of the /// original subtree. /// </summary> public override GPNode Edit(GPProgram tree, GPProgramBranch execBranch) { // // Can not use a 'foreach' structure here because we need to replace // the child with whatever it returns of itself. for (int Child = 0; Child < m_Children.Count; Child++) { m_Children[Child] = m_Children[Child].Edit(tree, execBranch); } // // If all the children to this node are numbers, a simplification // can be performed. bool AllNumbers = true; foreach (GPNode child in m_Children) { if (!(child is GPNodeTerminalDouble || child is GPNodeTerminalInteger)) { AllNumbers = false; break; } } // // The test to see if there are more than 0 arguments was added because // the time series functions may not have any parameters and they shouldn't // be converted to numeric terminals. if (AllNumbers && this.NumberArgs > 0) { // // Exec the function and replace with a new terminal node double result = this.EvaluateAsDouble(tree, execBranch); // // Create a new terminal node GPNodeTerminalDouble NodeNew = new GPNodeTerminalDouble(result); return(NodeNew); } return(this); }
/// <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); }
// // Cloneable interface public override Object Clone() { GPNodeTerminalDouble obj = (GPNodeTerminalDouble)this.MemberwiseClone(); return(obj); }