Example #1
0
        /// <summary>
        /// Returns the count of how many nodes there are in this tree
        /// And in the subtrees of this node
        /// </summary>
        /// <param name="ndNode">The root node</param>
        /// <returns>
        /// Returns the count of how many nodes there are in this tree
        /// And in the subtrees of this node
        /// </returns>
        public static int CountNodes(Node ndNode)
        {
            int nSum = 0;

            if (ndNode is FunctionNode)
            {
                FunctionNode fndNode = (FunctionNode)ndNode;
                foreach (Node ndSonNode in fndNode.m_arrSons)
                {
                    nSum += CountNodes(ndSonNode);
                }
            }

            return(nSum + 1);
        }
Example #2
0
        static int nCurrentNodeNumber; // A helper variable

        /// <summary>
        /// Returns what is the depth, of the tree that a node contains.
        /// </summary>
        /// <param name="ndRoot">The root node</param>
        /// <returns>Returns what is the depth, of the tree that a node contains.</returns>
        public static int FindDepth(Node ndRoot)
        {
            int nDepth = 0;

            if (ndRoot is FunctionNode)
            {
                FunctionNode fncRoot = (FunctionNode)ndRoot;
                for (int nSonNum = 0;
                     nSonNum != fncRoot.m_arrSons.Length;
                     nSonNum++)
                {
                    nDepth = Math.Max(nDepth, FindDepth(fncRoot.m_arrSons[nSonNum]));
                }
            }

            return(nDepth + 1);
        }
Example #3
0
        /// <summary>
        /// Exchanges two nodes, such that any other nodes that hold the same memory
        /// Will not be affected.
        /// </summary>
        /// <param name="ndNodeOne">Node one</param>
        /// <param name="ndNodeOneParent">Node one parent</param>
        /// <param name="ndProgramOneRootNode">The main root of node one</param>
        /// <param name="ndNodeTwo">Node two</param>
        /// <param name="ndNodeTwoParent">Node two parent</param>
        /// <param name="ndProgramTwoRootNode">The main root of node two</param>
        public static void ExchangeNodes(Node ndNodeOne, Node ndNodeOneParent, ref Node ndProgramOneRootNode,
                                         Node ndNodeTwo, Node ndNodeTwoParent, ref Node ndProgramTwoRootNode)
        {
            //node ndnodeoneclone = (node)ndnodeone.clone();
            //node ndnodetwoclone = (node)ndnodetwo.clone();
            //ndnodeone = ndnodetwoclone;
            //ndnodetwo = ndnodeoneclone;
            if (ndNodeOneParent == null)
            {
                ndProgramOneRootNode = ndNodeTwo;
            }
            else
            {
                FunctionNode fncNodeOneParent = (FunctionNode)ndNodeOneParent;
                // Find node one in node one parent sons and exchange it with node two
                for (int nSonIndexForParentOne = 0;
                     nSonIndexForParentOne < fncNodeOneParent.m_arrSons.Length;
                     nSonIndexForParentOne++)
                {
                    if (fncNodeOneParent.m_arrSons[nSonIndexForParentOne] == ndNodeOne)
                    {
                        fncNodeOneParent.m_arrSons[nSonIndexForParentOne] = ndNodeTwo;
                    }
                }
            }

            if (ndNodeTwoParent == null)
            {
                ndProgramTwoRootNode = ndNodeOne;
            }
            else
            {
                FunctionNode fncNodeTwoParent = (FunctionNode)ndNodeTwoParent;
                // Find node two in node two parent sons and exchange it with node one
                for (int nSonIndexForParentTwo = 0;
                     nSonIndexForParentTwo < fncNodeTwoParent.m_arrSons.Length;
                     nSonIndexForParentTwo++)
                {
                    if (fncNodeTwoParent.m_arrSons[nSonIndexForParentTwo] == ndNodeTwo)
                    {
                        fncNodeTwoParent.m_arrSons[nSonIndexForParentTwo] = ndNodeOne;
                    }
                }
            }
        }
Example #4
0
        /// <summary>
        /// Clones the function node recursively, The cloned version sits on a
        /// Different memory
        /// </summary>
        /// <returns>The clone of the function node</returns>
        public override object Clone()
        {
            FunctionNode fncNewNode = new FunctionNode();

            // Copies the regular data members
            fncNewNode.m_funcFunction = this.m_funcFunction;
            fncNewNode.m_arrSons      = new Node[this.m_arrSons.Length];

            // Passes on all the sons and clones them too (This works recursively)
            for (int nSonNodeIndex = 0;
                 nSonNodeIndex < this.m_arrSons.Length;
                 nSonNodeIndex++)
            {
                fncNewNode.m_arrSons[nSonNodeIndex] =
                    (Node)this.m_arrSons[nSonNodeIndex].Clone();
            }

            return(fncNewNode);
        }
Example #5
0
        /// <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);
        }
Example #6
0
        /// <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();
        }