Beispiel #1
0
        /// <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;
        }
Beispiel #2
0
        public BaseProgram GetMinFitnessProgramForIsland(int nIslandIndex)
        {
            // Sample the first program as a starting fitness
            BaseProgram progMinFitness = this.m_engEngine.Population[nIslandIndex][0];
            float       fMinFitness    = progMinFitness.m_fFitness;

            // Go through all the programs and get the program with the
            // Minimal fitness
            foreach (BaseProgram progProgram in this.m_engEngine.Population[nIslandIndex])
            {
                // If the current program has least fitness than all the rest so far
                // Then it's the most minimal fitness program.
                if (fMinFitness > progProgram.m_fFitness)
                {
                    fMinFitness    = progProgram.m_fFitness;
                    progMinFitness = progProgram;
                }
            }

            return(progMinFitness);
        }
Beispiel #3
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);
        }
Beispiel #4
0
 protected override void RunProgram(BaseProgram progProgram)
 {
     this.EvalFitnessForProgramEvent((TreeProgram)progProgram, this);
 }