Example #1
0
        internal Population RunGeneration(int currentGeneration, Population currentPopulation, FitnessFunction fitnessFunctionDelegate)
        {
            //create new empty populations for processing
            var tempPopulation      = currentPopulation.CreateEmptyCopy();
            var processedPopulation = tempPopulation.CreateEmptyCopy();

            tempPopulation.Solutions.AddRange(currentPopulation.Solutions);

            //clear the current population, this keeps it simple as the solutions could
            //easily get corrupted by genetic operators as from v 2.04 on, the genes are no longer cloned
            currentPopulation.Solutions.Clear();

            //invoke the operators
            //Note: Each operator will contribute to populating the New Population. It is not untill all operators are
            //invoked the the new population is complete. For example the Elite operator with 10% will return a
            //_newPopulation object containing only the top 10% of the solutions that exist in _population.
            //Deletions handled by the operator(s)
            foreach (var op in this.Operators)
            {
                var enabled = true;
                //maxFitnessPre = tempPopulation.MaximumFitness;

                var genOp = op as IGeneticOperator;                 //this is the new interface
                if (genOp != null)
                {
                    //using new interface so check enabled
                    enabled = genOp.Enabled;
                }

                //note that each internal operator will adhere to the enabled flag itself,
                //however the check is made here as this cannot be guaranteed with third party
                //operators.
                if (enabled)
                {
                    op.Invoke(tempPopulation, ref processedPopulation, fitnessFunctionDelegate);

                    Evaluations += op.GetOperatorInvokedEvaluations();

                    tempPopulation.Solutions.Clear();
                    tempPopulation.Solutions.AddRange(processedPopulation.Solutions);
                    processedPopulation.Solutions.Clear();

                    //TODO: Fix this.
                    //Some solutions will have already been evaluated during the operator invocations
                    //e.g. crossover, however, they may have also been mutated. By tracking/evaluating
                    //mutated we could get here only needing to evaluate those that wern't touched
                    //by the operators. The Chromosome.EvaluatedByOperator flag could help here...
                    //evaluate in case it affects the next operators selection

                    Evaluations += tempPopulation.Evaluate(fitnessFunctionDelegate);

                    //raise the Generation Complete event
                    if (this.OnOperatorComplete != null)
                    {
                        var eventArgs = new GaOperatorEventArgs(op, tempPopulation, currentGeneration + 1, Evaluations);
                        this.OnOperatorComplete(this, eventArgs);
                    }
                }
            }

            return(tempPopulation);
        }