private static void DrawNode(Tree.Node node, Graphics g, int depth, float x, float y, float imageWidth) { const int CHAR_WIDTH = 16; const int rectHeight = 20; const float distanceYBetweenNodes = (float)rectHeight * 1.5f; int rectWidth = 40; if (depth > 12) { return; //only draw to depth 12; } if (node is Tree.FuncNode) { Tree.FuncNode functionNode = node as Tree.FuncNode; rectWidth = functionNode.Function.Name.Length * CHAR_WIDTH; g.DrawRectangle(Pens.Blue, x - (rectWidth / 2), y - (rectHeight / 2), rectWidth, rectHeight); g.DrawString(functionNode.Function.Name, Font, Brushes.Blue, x - (rectWidth / 2), y - (rectHeight / 2)); int numberOfChildren = functionNode.Children.Length; float nodeSplitting = (float)(imageWidth / 2) * (float)Math.Pow(0.5, depth) * (float)1.0; for (int i = 0; i < numberOfChildren; i++) { float childX = (x - nodeSplitting) + (((float)Math.Pow(i, 0.8) * nodeSplitting * 2) / (numberOfChildren - 1)); g.DrawLine(LinePen, x, y + rectHeight / 2, childX, y + distanceYBetweenNodes - (rectHeight / 2)); DrawNode(functionNode.Children[i], g, depth + 1, childX, y + distanceYBetweenNodes, imageWidth); } } else if (node is Tree.ValueNode) { Tree.ValueNode valueNode = node as Tree.ValueNode; rectWidth = valueNode.Value.ToString().Length *CHAR_WIDTH; g.DrawRectangle(Pens.Red, x - (rectWidth / 2), y - (rectHeight / 2), rectWidth, rectHeight); g.DrawString(valueNode.Value.ToString(), Font, Brushes.Blue, x - (rectWidth / 2), y - (rectHeight / 2)); } else if (node is Tree.VariableNode) { Tree.VariableNode variableNode = node as Tree.VariableNode; rectWidth = variableNode.Variable.Name.Length * CHAR_WIDTH; g.DrawRectangle(Pens.DarkGreen, x - (rectWidth / 2), y - (rectHeight / 2), rectWidth, rectHeight); g.DrawString(variableNode.Variable.Name.ToString(), Font, Brushes.DarkGreen, x - (rectWidth / 2), y - (rectHeight / 2)); } else { throw new ApplicationException(); } }
public Program Crossover(Program prog2) { Program prog1Clone = this.CloneProgram(); Tree.Node nodeToTake = null; // 90% of the time do function crossover. 10% of time, just choose any node if (s_Random.NextDouble() > 0.1 && prog2.m_TopNode.TreeSizeFunctionsOnly > 0) { int funcNumToMutate = s_Random.Next(prog2.m_TopNode.TreeSizeFunctionsOnly); int currentFuncNum = 0; nodeToTake = prog2.m_TopNode.GetFunctionNumber(funcNumToMutate, ref currentFuncNum).CloneTree(); } else { int nodeToTakeNum = s_Random.Next(prog2.TreeSize); int currentNodeNumProg2 = 0; nodeToTake = prog2.m_TopNode.GetNodeNumber(nodeToTakeNum, ref currentNodeNumProg2).CloneTree(); } int prog1NodeToReplace = s_Random.Next(0, prog1Clone.TreeSize); int currentNodeNum = 0; if (prog1NodeToReplace == 0) { prog1Clone.m_TopNode = nodeToTake; } else { prog1Clone.m_TopNode.SetNode(prog1NodeToReplace, nodeToTake, ref currentNodeNum); if (!Node.m_ReplacementDone) { throw new ApplicationException(); } } return(prog1Clone); }