/// <summary>
        /// This is the method that invokes the operator. This should not normally be called explicitly.
        /// </summary>
        /// <param name="currentPopulation"></param>
        /// <param name="newPopulation"></param>
        /// <param name="fitnessFunctionDelegate"></param>
        public new virtual void Invoke(Population currentPopulation, ref Population newPopulation, FitnessFunction fitnessFunctionDelegate)
        {
            if (currentPopulation.Solutions == null || currentPopulation.Solutions.Count == 0)
            {
                throw new ArgumentException("There are no Solutions in the current Population.");
            }

            if (newPopulation == null)
            {
                newPopulation = currentPopulation.CreateEmptyCopy();
            }

            CurrentPopulation = currentPopulation;
            NewPopulation     = newPopulation;
            FitnessFunction   = fitnessFunctionDelegate;

            if (!Enabled)
            {
                return;
            }

            //TODO: Investigate this bizare code!!!
            //need to store this as we cannot handle a change until once this generation has started
            //_replacementMethodS = ReplacementMethod;



            int maxLoop    = 100;
            int eliteCount = 0;

            //reset the number of evaluations
            _evaluations = 0;

            //now that we know how many children we are to be creating, in the case of 'Delete Last'
            //we copy the current generation across and add new children where they are greater than
            //the worst solution.
            if (_replacementMethodS == ReplacementMethod.DeleteLast)
            {
                //copy everything accross including the elites
                NewPopulation.Solutions.Clear();
                NewPopulation.Solutions.AddRange(CurrentPopulation.Solutions);
            }
            else
            {
                //just copy the elites, this will take all elites

                //TODO: Sort out what we do if we overfill the population with elites
                var elites = CurrentPopulation.GetElites();
                eliteCount = elites.Count();
                if (elites != null && eliteCount > 0)
                {
                    NewPopulation.Solutions.AddRange(elites);
                }
            }
            _currentPopulationSize = CurrentPopulation.Solutions.Count;

            _numberOfChildrenToGenerate =
                _currentPopulationSize - eliteCount;

            while (_numberOfChildrenToGenerate > 0)
            {
                //emergency exit
                if (maxLoop <= 0)
                {
                    throw new ChromosomeException("Unable to create a suitable child. If duplicates have been disallowed then consider increasing the chromosome length or increasing the number of elites.");
                }

                //these will hold the children
                Chromosome c1 = null;
                Chromosome c2 = null;

                //select some parents
                var parents = CurrentPopulation.SelectParents();
                var p1      = parents [0];
                var p2      = parents [1];

                //crossover
                var crossoverData = CreateCrossoverData(p1.Genes.Count, CrossoverType);
                PerformCrossover(p1, p2, crossoverData, out c1, out c2);

                //pass the children out to derived classes
                //(e.g. CrossoverMutate class uses this to perform mutation)
                if (OnCrossoverComplete != null)
                {
                    var eventArgs = new CrossoverEventArgs(crossoverData, p1, p2, c1, c2);
                    OnCrossoverComplete(this, eventArgs);
                }

                if (AddChild(c1))
                {
                    _numberOfChildrenToGenerate--;
                }
                else
                {
                    //unable to create child
                    maxLoop--;
                }

                //see if we can add the secomd
                if (_numberOfChildrenToGenerate > 0)
                {
                    if (AddChild(c2))
                    {
                        _numberOfChildrenToGenerate--;
                    }
                    else
                    {
                        //unable to create child
                        maxLoop--;
                    }
                }
            }

            //TODO: Test this, we shouldn't need it.
            newPopulation = NewPopulation;
        }
Exemplo n.º 2
0
        /// <summary>
        /// Main process loop for performing a crossover on a population.
        /// </summary>
        protected void Process()
        {
            int maxLoop    = 100;
            int eliteCount = 0;

            //reset the number of evaluations
            _evaluations = 0;

            //now that we know how many children we are to be creating, in the case of 'Delete Last'
            //we copy the current generation across and add new children where they are greater than
            //the worst solution.
            if (_replacementMethodS == ReplacementMethod.DeleteLast)
            {
                //copy everything accross including the elites
                _newPopulation.Solutions.Clear();
                _newPopulation.Solutions.AddRange(_currentPopulation.Solutions);
            }
            else
            {
                //just copy the elites, this will take all elites

                //TODO: Sort out what we do if we overfill the population with elites
                var elites = _currentPopulation.GetElites();
                eliteCount = elites.Count();
                if (elites != null && eliteCount > 0)
                {
                    _newPopulation.Solutions.AddRange(elites);
                }
            }
            _currentPopulationSize = _currentPopulation.Solutions.Count;

            _numberOfChildrenToGenerate =
                _currentPopulationSize - eliteCount;

            while (_numberOfChildrenToGenerate > 0)
            {
                //emergency exit
                if (maxLoop <= 0)
                {
                    throw new ChromosomeException("Unable to create a suitable child. If duplicates have been disallowed then consider increasing the chromosome length or increasing the number of elites.");
                }

                //these will hold the children
                Chromosome c1 = null;
                Chromosome c2 = null;

                //select some parents
                var parents = _currentPopulation.SelectParents();
                var p1      = parents [0];
                var p2      = parents [1];

                //crossover
                var crossoverData   = CreateCrossoverData(p1.Genes.Count, CrossoverType);
                var crossoverResult = PerformCrossover(p1, p2, CrossoverProbability, CrossoverType, crossoverData, out c1, out c2);

                //pass the children out to derived classes
                //(e.g. CrossoverMutate class uses this to perform mutation)
                if (OnCrossoverComplete != null)
                {
                    var eventArgs = new CrossoverEventArgs(crossoverResult, p1, p2, c1, c2);
                    OnCrossoverComplete(this, eventArgs);
                }

                if (AddChild(c1))
                {
                    _numberOfChildrenToGenerate--;
                }
                else
                {
                    //unable to create child
                    maxLoop--;
                }

                //see if we can add the secomd
                if (_numberOfChildrenToGenerate > 0)
                {
                    if (AddChild(c2))
                    {
                        _numberOfChildrenToGenerate--;
                    }
                    else
                    {
                        //unable to create child
                        maxLoop--;
                    }
                }
            }
        }