/// <summary> /// The function will create a random program and will use the /// Function CreateRandomNode in order to do that. /// </summary> /// <returns>A random program</returns> protected override BaseProgram CreateRandomProgram() { // Create a new program with the wanted number of roots TreeProgram progProgram = new TreeProgram(this.m_nNumOfResults); // Create the variables array, which consists of new variables progProgram.m_arrVariables = new Variable[this.m_arrstrVariables.Count]; for (int nVariableIndex = 0; nVariableIndex < this.m_arrstrVariables.Count; nVariableIndex++) { Variable varNew = new Variable(); varNew.SetName(this.m_arrstrVariables[nVariableIndex]); progProgram.m_arrVariables[nVariableIndex] = varNew; } // Copy the all the main randomable types, concat it the variables of // The current program. ArrayList arrRandomableTypes = new ArrayList(); arrRandomableTypes.AddRange(this.m_arrAllTypes); foreach (Variable varOfProgram in progProgram.m_arrVariables) { arrRandomableTypes.Add(varOfProgram); } // Create a random node for the root for (int nRootNum = 0; nRootNum < progProgram.m_arrRoots.Length; nRootNum++) { progProgram.m_arrRoots[nRootNum] = CreateRandomNode(0, progProgram, arrRandomableTypes); } // Returns the program return(progProgram); }
/// <summary> /// The function clones the program. It also passes on all the roots /// And clone them recursively, so that all the roots sit on a different /// Memory. /// </summary> /// <returns>A cloned program</returns> public override object Clone() { // Construct a new program with the same number of roots TreeProgram progNewProgram = new TreeProgram(this.m_arrRoots.Length); // Copy basic data members progNewProgram.m_fFitness = this.m_fFitness; this.m_fReturnedResult.CopyTo(progNewProgram.m_fReturnedResult, 0); // Copy the variables progNewProgram.m_arrVariables = new Variable[this.m_arrVariables.Length]; for (int nVariableIndex = 0; nVariableIndex < this.m_arrVariables.Length; nVariableIndex++) { progNewProgram.m_arrVariables[nVariableIndex] = (Variable)this.m_arrVariables[nVariableIndex].Clone(); } // Copy the nodes recursively for (int nRootIndex = 0; nRootIndex < this.m_arrRoots.Length; nRootIndex++) { progNewProgram.m_arrRoots[nRootIndex] = (Node)this.m_arrRoots[nRootIndex].Clone(); } return(progNewProgram); }
public void SaveProgram(string strFilename, TreeProgram progProgram) { StreamWriter swWriter = new StreamWriter(strFilename); progProgram.Save(swWriter); swWriter.Close(); }
public override float action(Node[] arrNodes, TreeLanguageEvolute.TreeProgram progOwner) { Runner cRunner = ((Runner)progOwner.AdditionalInformation); cRunner.QueueRotateLeft(); return(0); }
public override float action(Node[] arrNodes, TreeProgram progOwner) { float fLeftValue = arrNodes[0].ReturnValue(progOwner); float fRightValue = arrNodes[1].ReturnValue(progOwner); return(fLeftValue % fRightValue); }
void engEngine_EvalFitnessForProgramEvent(TreeLanguageEvolute.TreeProgram progProgram, GeneticProgrammingEngine sender) { progProgram.Fitness = 0; Hashtable hsVariables = progProgram.GetVariables(); Variable varX = (Variable)hsVariables["X"]; for (int nCaseNumber = 0; nCaseNumber < 100; nCaseNumber++) { // y = 5x^3+x^2+x varX.Value = (float)GlobalRandom.m_rndRandom.NextDouble(); float fExpectedResult = (5 * varX.Value * varX.Value * varX.Value) + (3 * varX.Value * varX.Value) + varX.Value; progProgram.Run(); float fActualResult = progProgram.Result; progProgram.Fitness += Math.Abs(fExpectedResult - fActualResult); } if (progProgram.Fitness < 0.1F) { progProgram.Fitness = 0.00000001F * progProgram.Count; } }
public override float action(Node[] arrNodes, TreeLanguageEvolute.TreeProgram progOwner) { float fDummy = arrNodes[0].ReturnValue(progOwner); CACell caCurrCell = ((CACell)progOwner.AdditionalInformation); return(caCurrCell.fAvaliableEnergy); }
public override float action(Node[] arrNodes, TreeLanguageEvolute.TreeProgram progOwner) { CACell caCurrCell = ((CACell)progOwner.AdditionalInformation); float dEnergyToSubstract = (int)arrNodes[0].ReturnValue(progOwner); // Substract from the current cell and give to the other one. float dResult = SharedEvolutionFunctions.SendEnergy(caCurrCell, SharedEvolutionFunctions.DIRECTION_RIGHT, dEnergyToSubstract); return(dResult); }
/// <summary> /// The crossover function, takes two parent programs, and generates two sons /// From the two parents. /// </summary> /// <param name="progParentOne">Parent program one</param> /// <param name="progParentTwo">Parent program two</param> /// <param name="progSonOne">Son program one</param> /// <param name="progSonTwo">Son program two</param> protected override void Crossover(BaseProgram baseProgParentOne, BaseProgram baseProgParentTwo, out BaseProgram baseProgSonOne, out BaseProgram baseProgSonTwo) { TreeProgram progParentOne = (TreeProgram)baseProgParentOne; TreeProgram progParentTwo = (TreeProgram)baseProgParentTwo; TreeProgram progSonOne; TreeProgram progSonTwo; // Get the global random ... ImprovedRandom rndRandom = GlobalRandom.m_rndRandom; progSonOne = (TreeProgram)progParentOne.Clone(); progSonTwo = (TreeProgram)progParentTwo.Clone(); // Generate new sons more and more, until the new sons tree limit's are // Good enough and stand the tree limits. Or just do this for the first time // That sons are being generated. for (int nRootNum = 0; nRootNum < progSonOne.m_arrRoots.Length; nRootNum++) { bool bGeneratedNewSons = false; while (((progSonOne.m_arrRoots[nRootNum].Depth > this.m_nMaxOverallTreeDepth) || (progSonTwo.m_arrRoots[nRootNum].Depth > this.m_nMaxOverallTreeDepth)) || !bGeneratedNewSons) { // Clone both parent roots progSonOne.m_arrRoots[nRootNum] = (Node)progParentOne.m_arrRoots[nRootNum].Clone(); progSonTwo.m_arrRoots[nRootNum] = (Node)progParentTwo.m_arrRoots[nRootNum].Clone(); // Random two nodes as a crossover points in the two sons (which are // Now supposed to be a cloned version of the parents) int nSelectNodeInParentOne = rndRandom.Next( NodeHelper.CountNodes(progSonOne.m_arrRoots[nRootNum])); int nSelectNodeInParentTwo = rndRandom.Next( NodeHelper.CountNodes(progSonTwo.m_arrRoots[nRootNum])); NodeHelper.NodeResult ndNodeToExchangeOne = NodeHelper.FindNode( progSonOne.m_arrRoots[nRootNum], nSelectNodeInParentOne); NodeHelper.NodeResult ndNodeToExchangeTwo = NodeHelper.FindNode( progSonTwo.m_arrRoots[nRootNum], nSelectNodeInParentTwo); // Exchange the crossover branches between the two sons, when it is done, // The new sons are ready to be called "new sons" and not just a clone. NodeHelper.ExchangeNodes( ndNodeToExchangeOne.ndNode, ndNodeToExchangeOne.ndNodeParent, ref progSonOne.m_arrRoots[nRootNum], ndNodeToExchangeTwo.ndNode, ndNodeToExchangeTwo.ndNodeParent, ref progSonTwo.m_arrRoots[nRootNum]); bGeneratedNewSons = true; } } baseProgSonOne = progSonOne; baseProgSonTwo = progSonTwo; }
public override float action(Node[] arrNodes, TreeLanguageEvolute.TreeProgram progOwner) { Hashtable hsVariables = progOwner.GetVariables(); float fWantedVariable = arrNodes[0].ReturnValue(progOwner); float fWantedValue = arrNodes[1].ReturnValue(progOwner); uint nWantedVariableIndex = ((uint)fWantedVariable) % (uint)hsVariables.Count; Variable varWantedVariable = progOwner.Variables[nWantedVariableIndex]; varWantedVariable.Value = fWantedValue; return(1); }
public override float action(Node[] arrNodes, TreeProgram progOwner) { float fFirstNode = arrNodes[0].ReturnValue(progOwner); float fSecondNode = arrNodes[1].ReturnValue(progOwner); if (fFirstNode > fSecondNode) { return(arrNodes[2].ReturnValue(progOwner)); } else { return(arrNodes[3].ReturnValue(progOwner)); } }
int m_nVariableIndex; // The index of the variable, // In the variable array inside the program /// <summary> /// Construct the node with a variable /// </summary> /// <param name="varVariable">The variable</param> public VariableNode(Variable varVariable, TreeProgram progOwner) { // Find the variable index in the program, when constructing the variable // Node. So that when we run the variable node, we can access the // Variable index of that program and get the variable value for (int nVariableIndex = 0; nVariableIndex < progOwner.m_arrVariables.Length; nVariableIndex++) { Variable varInProgram = progOwner.m_arrVariables[nVariableIndex]; if (varInProgram == varVariable) { this.m_nVariableIndex = nVariableIndex; } } }
public TreeProgram LoadProgram(string strFilename) { Hashtable hsAllTypes = new Hashtable(); foreach (FunctionType funcFunction in this.m_arrFunctions) { hsAllTypes[funcFunction.Name] = funcFunction; } foreach (string strVariableName in this.m_arrstrVariables) { Variable varNew = new Variable(); varNew.SetName(strVariableName); hsAllTypes[strVariableName] = varNew; } StreamReader srReader = new StreamReader(strFilename); TreeProgram progProgram = new TreeProgram(srReader, hsAllTypes); srReader.Close(); return(progProgram); }
public override float action(Node[] arrNodes, TreeProgram progOwner) { return((float)Math.Cos(arrNodes[0].ReturnValue(progOwner))); }
public override string GetName(TreeProgram progOwner) { return(this.m_fValue.ToString()); }
/// <summary> /// Returns the value /// </summary> /// <returns>Returns the value of the node</returns> public override float ReturnValue(TreeProgram progOwner) { return(this.m_fValue); }
/// <summary> /// Returns the name of the node /// </summary> public abstract string GetName(TreeProgram progOwner);
public override string GetName(TreeProgram progOwner) { return(progOwner.m_arrVariables[this.m_nVariableIndex].Name); }
/// <summary> /// The function returns the value of the node /// (Which is the value of the variable) /// </summary> /// <returns>the value of the node /// (Which is the value of the variable)</returns> public override float ReturnValue(TreeProgram progOwner) { // Return the value of the variable that this node points to return(progOwner.m_arrVariables[this.m_nVariableIndex].ReturnValue()); }
/// <summary> /// An abstract function that returns the value that is contained in this node. /// </summary> /// <returns>The value that is contained in this node</returns> public abstract float ReturnValue(TreeProgram progOwner);
public override string GetName(TreeProgram progOwner) { return(this.m_funcFunction.Name); }
/// <summary> /// Activates the function and returns the value of the function /// </summary> /// <returns> /// Activates the function and returns the value of the function /// </returns> public override float ReturnValue(TreeProgram progOwner) { return(this.m_funcFunction.action(this.m_arrSons, progOwner)); }
public override float action(Node[] arrNodes, TreeProgram progOwner) { return(arrNodes[0].ReturnValue(progOwner) * arrNodes[1].ReturnValue(progOwner)); }
public override float action(Node[] arrNodes, TreeLanguageEvolute.TreeProgram progOwner) { Runner cRunner = ((Runner)progOwner.AdditionalInformation); return(cRunner.GetSpeed()); }
/// <summary> /// The function draws a program nodes using a Graphics object. /// </summary> /// <param name="grpGraphics"> /// The graphics object used to draw the program< /// /param> /// <param name="nWidth">The width of the wanted drawing</param> /// <param name="nHeight">The height of the wanted drawing</param> /// <param name="frmParentForm">The parent Form</param> public void Draw(Graphics grpGraphics, int nWidth, int nHeight, Form frmParentForm) { const float NODE_PERCENT_SIZE = 0.1F; const int BITMAP_OF_NODE_SIZE = 400; float NODE_PIXEL_SIZE = NODE_PERCENT_SIZE * nWidth; Color NODE_COLOR = Color.Green; Color BACKGROUND_COLOR = Color.White; Color LINE_COLOR = Color.Black; Bitmap bmpPicture = new Bitmap(nWidth, nHeight); Graphics cGraphicsOnPicture = Graphics.FromImage(bmpPicture); Brush brBrush = new SolidBrush(NODE_COLOR); List <List <Node> > lstNodeLayers = new List <List <Node> >(); List <List <Rectangle> > lstNodeBoxLayers = new List <List <Rectangle> >(); List <Node> lstFirstLayer = new List <Node>(); List <Node> lstSecondLayer = new List <Node>(); lstFirstLayer.Add(this.m_arrRoots[0]); while ((lstFirstLayer.Count != 0) || (lstSecondLayer.Count != 0)) { foreach (Node ndNodeInLayer in lstFirstLayer) { if (ndNodeInLayer is FunctionNode) { FunctionNode fncNode = (FunctionNode)ndNodeInLayer; lstSecondLayer.AddRange(fncNode.m_arrSons); } } if (lstFirstLayer.Count > 0) { lstNodeLayers.Add(lstFirstLayer.GetRange(0, lstFirstLayer.Count)); } lstFirstLayer.Clear(); foreach (Node ndNodeInLayer in lstSecondLayer) { if (ndNodeInLayer is FunctionNode) { FunctionNode fncNode = (FunctionNode)ndNodeInLayer; lstFirstLayer.AddRange(fncNode.m_arrSons); } } if (lstSecondLayer.Count > 0) { lstNodeLayers.Add(lstSecondLayer.GetRange(0, lstSecondLayer.Count)); } lstSecondLayer.Clear(); } cGraphicsOnPicture.Clear(Color.White); int nNodeHeightSize = nHeight / (lstNodeLayers.Count * 2); int nStartingY = 0; Bitmap bmpOfNode = new Bitmap(BITMAP_OF_NODE_SIZE, BITMAP_OF_NODE_SIZE); Graphics grpGraphicsOfNode = Graphics.FromImage(bmpOfNode); foreach (List <Node> lstLayer in lstNodeLayers) { int nNodeWidthSize = nWidth / (lstLayer.Count * 3); int nNodeSize = Math.Min(nNodeWidthSize, nNodeHeightSize); int nStartingX = (nWidth / 2) - (nNodeSize * lstLayer.Count); List <Rectangle> lstRectLayer = new List <Rectangle>(); foreach (Node ndNode in lstLayer) { Rectangle rctDrawingRectangle = new Rectangle(nStartingX, nStartingY, nNodeSize, nNodeSize); grpGraphicsOfNode.Clear(Color.White); grpGraphicsOfNode.FillEllipse(brBrush, new Rectangle(0, 0, bmpOfNode.Width, bmpOfNode.Height)); TreeProgram.DrawStringInWholeImage(bmpOfNode, ndNode.GetName(this)); lstRectLayer.Add(rctDrawingRectangle); cGraphicsOnPicture.DrawImage(bmpOfNode, rctDrawingRectangle); nStartingX += nNodeWidthSize * 2; } lstNodeBoxLayers.Add(lstRectLayer.GetRange(0, lstRectLayer.Count)); lstRectLayer.Clear(); nStartingY += nNodeHeightSize * 2; } int nLayerIndex = 0; foreach (List <Rectangle> lstRectsLayer in lstNodeBoxLayers) { int nNodeIndex = 0; foreach (Rectangle rctRectOfNode in lstRectsLayer) { int nFatherCenterX = (rctRectOfNode.Left + rctRectOfNode.Right) / 2; int nFatherCenterY = (rctRectOfNode.Top + rctRectOfNode.Bottom) / 2; int nFatherIndex = nNodeIndex; Node ndFatherNode = lstNodeLayers[nLayerIndex][nFatherIndex]; // Go through all the sons and draw the lines to them if (ndFatherNode is FunctionNode) { FunctionNode fncFatherNode = (FunctionNode)ndFatherNode; foreach (Node ndSonNode in fncFatherNode.m_arrSons) { int nSonIndex = lstNodeLayers[nLayerIndex + 1].FindIndex( delegate(Node ndNode) { if (ndNode == ndSonNode) { return(true); } else { return(false); } } ); Rectangle rctRectSonNode = lstNodeBoxLayers[nLayerIndex + 1][nSonIndex]; int nSonCenterX = (rctRectSonNode.Left + rctRectSonNode.Right) / 2; int nSonCenterY = (rctRectSonNode.Top + rctRectSonNode.Bottom) / 2; cGraphicsOnPicture.DrawLine(new Pen(LINE_COLOR), nFatherCenterX, nFatherCenterY, nSonCenterX, nSonCenterY); } } nNodeIndex++; } nLayerIndex++; } grpGraphics.DrawImageUnscaled(bmpPicture, 0, 0); bmpPicture.Dispose(); cGraphicsOnPicture.Dispose(); }
/// <summary> /// Creates a random node in the tree. The function is recursive, and /// Creates a random node. Which means, a random function or variable will /// Be selected . If a function is selected, then another nodes for the /// Function will be created. If a variable will be selected, then /// The tree will stop evolving at this branch. /// </summary> /// <param name="nCurrentDepth">The current tree depth</param> /// <returns>A random tree node</returns> private Node CreateRandomNode(int nCurrentDepth, BaseProgram baseProgOwner, ArrayList arrRandomableTypes) { TreeProgram progOwner = (TreeProgram)baseProgOwner; // The chosen index in all the types array, to choose some random thing, // Either variable of function, to insert as a node. int nChosenTypeIndex = GlobalRandom.m_rndRandom.Next(arrRandomableTypes.Count); object objChosenType = arrRandomableTypes[nChosenTypeIndex]; // If we are above the tree limit, choose randomly until we select a variable. bool fFoundLeaf = false; while ((nCurrentDepth > this.m_nMaxInitialTreeDepth) && (fFoundLeaf == false)) { nChosenTypeIndex = GlobalRandom.m_rndRandom.Next(arrRandomableTypes.Count); objChosenType = arrRandomableTypes[nChosenTypeIndex]; if (objChosenType is FunctionType) { if (((FunctionType)objChosenType).NumberOfArguments == 0) { fFoundLeaf = true; } } else // The type is variable { fFoundLeaf = true; } } // If we are below the initial tree limit, choose randomly until we select // A function. bool fFoundBranch = false; while ((nCurrentDepth < this.m_nMinInitialTreeDepth) && (fFoundBranch == false)) { nChosenTypeIndex = GlobalRandom.m_rndRandom.Next(arrRandomableTypes.Count); objChosenType = arrRandomableTypes[nChosenTypeIndex]; if (objChosenType is FunctionType) { if (((FunctionType)objChosenType).NumberOfArguments > 0) { fFoundBranch = true; } } } // If the object chosen is a variable, create a new VariableNode if (objChosenType is Variable) { Variable vlVariable = (Variable)objChosenType; return(new VariableNode(vlVariable, progOwner)); } // If the object chosen is a value, create a new ValueNode else if (objChosenType is Value) { Value vlValue = (Value)objChosenType; return(new ValueNode(vlValue)); } // If the object chosen is a RandomMacro, create a new ValueNode which // Will be randomized. else if (objChosenType is RandomMacro) { return(new ValueNode(((RandomMacro)objChosenType).ReturnValue())); } // If the object chosen is a function, then create a function and also // Create trees for that function. else if (objChosenType is Function) { FunctionNode fncNewNode = new FunctionNode(); Function funcChosenFunction = (Function)objChosenType; fncNewNode.m_funcFunction = funcChosenFunction; fncNewNode.m_arrSons = new Node[funcChosenFunction.NumberOfArguments]; for (int nSonIndex = 0; nSonIndex < fncNewNode.m_arrSons.Length; nSonIndex++) { fncNewNode.m_arrSons[nSonIndex] = CreateRandomNode(nCurrentDepth + 1, progOwner, arrRandomableTypes); } return(fncNewNode); } // We will never normally reach here. return(null); }
public abstract float action(Node[] arrNodes, TreeProgram progOwner);