private ComplexityRegulationMode DetermineMode_WhileSimplifying(
            EvolutionAlgorithmStatistics eaStats,
            PopulationStatistics popStats)
        {
            // Currently simplifying.
            // Test if simplification (ongoing reduction in complexity) has stalled.

            // We allow simplification to progress for a few generations before testing of it has stalled, this allows
            // a lead in time for the effects of simplification to occur.
            // In addition we do not switch to complexifying if complexity is above the currently defined ceiling.
            if (
                ((eaStats.Generation - _lastTransitionGeneration) > _minSimplifcationGenerations) &&
                (popStats.MeanComplexity < _complexityCeiling) &&
                ((popStats.MeanComplexityHistory.Mean - _prevMeanMovingAverage) >= 0.0))
            {
                // Simplification has stalled; switch back to complexification.
                _currentMode = ComplexityRegulationMode.Complexifying;
                _lastTransitionGeneration = eaStats.Generation;
                _prevMeanMovingAverage    = 0.0;
            }
            // else: otherwise remain in simplifying mode.

            // Update previous mean moving average complexity value.
            _prevMeanMovingAverage = popStats.MeanComplexityHistory.Mean;

            // Set a new complexity ceiling, relative to the current population complexity mean.
            _complexityCeiling = popStats.MeanComplexity + _relativeComplexityCeiling;

            return(_currentMode);
        }
Exemple #2
0
 /// <summary>
 /// Notify the strategy of a change in complexity regulation mode in the evolution algorithm.
 /// </summary>
 /// <param name="mode">The current mode.</param>
 public void NotifyComplexityRegulationMode(ComplexityRegulationMode mode)
 {
     _mutationTypeDistributionsCurrent = mode switch
     {
         ComplexityRegulationMode.Complexifying => _mutationTypeDistributionsComplexifying,
         ComplexityRegulationMode.Simplifying => _mutationTypeDistributionsSimplifying,
         _ => throw new ArgumentException("Unexpected complexity regulation mode."),
     };
 }
        /// <summary>
        /// Constructs with the default NeatEvolutionAlgorithmParameters and speciation strategy
        /// (KMeansClusteringStrategy with ManhattanDistanceMetric).
        /// </summary>
        public NeatEvolutionAlgorithm()
        {
            _eaParams = new NeatEvolutionAlgorithmParameters();
            _eaParamsComplexifying = _eaParams;
            _eaParamsSimplifying   = _eaParams.CreateSimplifyingParameters();
            _stats = new NeatAlgorithmStats(_eaParams);
            _speciationStrategy = new KMeansClusteringStrategy <TGenome>(new ManhattanDistanceMetric());

            _complexityRegulationMode     = ComplexityRegulationMode.Complexifying;
            _complexityRegulationStrategy = new NullComplexityRegulationStrategy();
        }
        /// <summary>
        /// Constructs with the provided NeatEvolutionAlgorithmParameters and ISpeciationStrategy.
        /// </summary>
        public NeatEvolutionAlgorithm(NeatEvolutionAlgorithmParameters eaParams,
                                      ISpeciationStrategy <TGenome> speciationStrategy,
                                      IComplexityRegulationStrategy complexityRegulationStrategy)
        {
            _eaParams = eaParams;
            _eaParamsComplexifying = _eaParams;
            _eaParamsSimplifying   = _eaParams.CreateSimplifyingParameters();
            _stats = new NeatAlgorithmStats(_eaParams);
            _speciationStrategy = speciationStrategy;

            _complexityRegulationMode     = ComplexityRegulationMode.Complexifying;
            _complexityRegulationStrategy = complexityRegulationStrategy;
        }
Exemple #5
0
        public void TestInitialisation()
        {
            var strategy = new AbsoluteComplexityRegulationStrategy(10, 10.0);

            var eaStats  = new EvolutionAlgorithmStatistics();
            var popStats = new PopulationStatistics();

            // The strategy should initialise to, and remain in, Complexifying mode.
            for (int i = 0; i < 100; i++)
            {
                eaStats.Generation = i;
                ComplexityRegulationMode mode = strategy.UpdateMode(eaStats, popStats);
                Assert.AreEqual(ComplexityRegulationMode.Complexifying, mode);
            }
        }
        /// <summary>
        /// Construct the complexity regulation strategy with the provided regulation parameters.
        /// </summary>
        public DefaultComplexityRegulationStrategy(ComplexityCeilingType ceilingType, double ceilingValue)
        {
            _ceilingType = ceilingType;
            _complexityCeiling = ceilingValue;

            // For relative complexity ceiling we await the first call to DetermineMode() before setting the threshold
            // relative to the population mean complexity. Indicate this with -1.0.
            if(ComplexityCeilingType.Relative ==  ceilingType) {
                _complexityCeilingCurrent = -1.0;
            } else {
                _complexityCeilingCurrent = ceilingValue;
            }

            _currentMode = ComplexityRegulationMode.Complexifying;
        }
Exemple #7
0
        /// <summary>
        /// Constructs with the default NeatEvolutionAlgorithmParameters and speciation strategy
        /// (KMeansClusteringStrategy with ManhattanDistanceMetric).
        /// </summary>

        /*
         * public NeatEvolutionAlgorithm()
         * {
         *  _eaParams = new NeatEvolutionAlgorithmParameters();
         *  _eaParamsComplexifying = _eaParams;
         *  _eaParamsSimplifying = _eaParams.CreateSimplifyingParameters();
         *  _stats = new NeatAlgorithmStats(_eaParams);
         *  _speciationStrategy = new KMeansClusteringStrategy<TGenome>(new ManhattanDistanceMetric());
         *
         *  _complexityRegulationMode = ComplexityRegulationMode.Complexifying;
         *  _complexityRegulationStrategy = new NullComplexityRegulationStrategy();
         * }
         */

        /// <summary>
        /// Constructs with the provided NeatEvolutionAlgorithmParameters and ISpeciationStrategy.
        /// </summary>

/*
 *      public NeatEvolutionAlgorithm(NeatEvolutionAlgorithmParameters eaParams,
 *                                    ISpeciationStrategy<TGenome> speciationStrategy,
 *                                    IComplexityRegulationStrategy complexityRegulationStrategy)
 *      {
 *          _eaParams = eaParams;
 *          _eaParamsComplexifying = _eaParams;
 *          _eaParamsSimplifying = _eaParams.CreateSimplifyingParameters();
 *          _stats = new NeatAlgorithmStats(_eaParams);
 *          _speciationStrategy = speciationStrategy;
 *
 *          _complexityRegulationMode = ComplexityRegulationMode.Complexifying;
 *          _complexityRegulationStrategy = complexityRegulationStrategy;
 *      }
 */
        public void Construct(NeatEvolutionAlgorithmParameters eaParams,
                              ISpeciationStrategy <TGenome> speciationStrategy,
                              IComplexityRegulationStrategy complexityRegulationStrategy,
                              IGenomeListEvaluator <TGenome> initialGenomeListEvaluator)
        {
            _eaParams = eaParams;
            _eaParamsComplexifying = _eaParams;
            _eaParamsSimplifying   = _eaParams.CreateSimplifyingParameters();
            _stats = new NeatAlgorithmStats(_eaParams);
            _speciationStrategy = speciationStrategy;

            _complexityRegulationMode     = ComplexityRegulationMode.Complexifying;
            _complexityRegulationStrategy = complexityRegulationStrategy;

            _initialGenomeListEvaluator = initialGenomeListEvaluator;
        }
        private ComplexityRegulationMode DetermineMode_WhileComplexifying(
            EvolutionAlgorithmStatistics eaStats,
            PopulationStatistics popStats)
        {
            // Currently complexifying.
            // Test if the complexity ceiling has been reached.
            if (popStats.MeanComplexity > _complexityCeiling)
            {
                // Switch to simplifying mode.
                _currentMode = ComplexityRegulationMode.Simplifying;
                _lastTransitionGeneration = eaStats.Generation;
                _prevMeanMovingAverage    = popStats.MeanComplexityHistory.Mean;
            }

            return(_currentMode);
        }
        private void UpdateUIState_EaStats()
        {
            NeatEvolutionAlgorithmStatistics eaStats  = (NeatEvolutionAlgorithmStatistics)_eaRunner.EA.Stats;
            NeatPopulationStatistics         popStats = _neatPop.NeatPopulationStats;

            // Search mode.
            ComplexityRegulationMode mode = ((NeatEvolutionAlgorithm <double>)_eaRunner.EA).ComplexityRegulationMode;

            txtSearchStatsMode.Text      = mode.ToString();
            txtSearchStatsMode.BackColor = mode switch
            {
                ComplexityRegulationMode.Complexifying => Color.LightSkyBlue,
                _ => Color.LightSkyBlue
            };

            txtStatsGeneration.Text = eaStats.Generation.ToString("N0");
            txtStatsBest.Text       = popStats.BestFitness.PrimaryFitness.ToString();

            // Auxiliary fitness info.
            double[] auxFitnessArr = popStats.BestFitness.AuxFitnessScores;
            if (auxFitnessArr != null && auxFitnessArr.Length > 0)
            {
                txtStatsAlternativeFitness.Text = auxFitnessArr[0].ToString("#.######");
            }
            else
            {
                txtStatsAlternativeFitness.Text = "";
            }

            txtStatsMean.Text             = popStats.MeanFitness.ToString("#.######");
            txtSpeciesChampsMean.Text     = popStats.AverageSpeciesBestFitness.ToString("#.######");
            txtStatsTotalEvals.Text       = eaStats.TotalEvaluationCount.ToString("N0");
            txtStatsEvalsPerSec.Text      = eaStats.EvaluationsPerSec.ToString("##,#.##");
            txtStatsBestGenomeComplx.Text = popStats.BestComplexity.ToString("N0");
            txtStatsMeanGenomeComplx.Text = popStats.MeanComplexity.ToString("#.##");
            txtStatsMaxGenomeComplx.Text  = popStats.MaxComplexity.ToString("N0");

            ulong totalOffspringCount = eaStats.TotalOffspringCount;

            if (totalOffspringCount > 0)
            {
                txtStatsTotalOffspringCount.Text        = totalOffspringCount.ToString("N0");
                txtStatsAsexualOffspringCount.Text      = string.Format("{0:N0} ({1:P})", eaStats.TotalOffspringAsexualCount, (eaStats.TotalOffspringAsexualCount / (double)totalOffspringCount));
                txtStatsCrossoverOffspringCount.Text    = string.Format("{0:N0} ({1:P})", eaStats.TotalOffspringSexualCount, (eaStats.TotalOffspringSexualCount / (double)totalOffspringCount));
                txtStatsInterspeciesOffspringCount.Text = string.Format("{0:N0} ({1:P})", eaStats.TotalOffspringInterspeciesCount, (eaStats.TotalOffspringInterspeciesCount / (double)totalOffspringCount));
            }
        }
Exemple #10
0
    /// <summary>
    /// Construct a new instance.
    /// </summary>
    /// <param name="complexityCeiling">The absolute complexity ceiling.</param>
    /// <param name="minSimplifcationGenerations">The minimum number of generations we stay within simplification mode.</param>
    public AbsoluteComplexityRegulationStrategy(
        int minSimplifcationGenerations,
        double complexityCeiling)
    {
        _minSimplifcationGenerations = minSimplifcationGenerations;
        _complexityCeiling           = complexityCeiling;
        _currentMode = ComplexityRegulationMode.Complexifying;
        _lastTransitionGeneration = 0;

        if (minSimplifcationGenerations < 1)
        {
            throw new ArgumentException("Must be 1 or above.", nameof(minSimplifcationGenerations));
        }
        if (complexityCeiling < 1)
        {
            throw new ArgumentException("Must be at 1 or above.", nameof(complexityCeiling));
        }
    }
        /// <summary>
        /// Notify the strategy of a change in complexity regulation mode in the evolution algorithm.
        /// </summary>
        /// <param name="mode">The current mode.</param>
        public void NotifyComplexityRegulationMode(ComplexityRegulationMode mode)
        {
            switch (mode)
            {
            case ComplexityRegulationMode.Complexifying:
                _settingsCurrent = _settingsComplexifying;
                _mutationTypeDistributionsCurrent = _mutationTypeDistributionsComplexifying;
                break;

            case ComplexityRegulationMode.Simplifying:
                _settingsCurrent = _settingsSimplifying;
                _mutationTypeDistributionsCurrent = _mutationTypeDistributionsSimplifying;
                break;

            default:
                throw new ArgumentException("Unexpected complexity regulation mode.");
            }
        }
        /// <summary>
        /// Construct the complexity regulation strategy with the provided regulation parameters.
        /// </summary>
        public DefaultComplexityRegulationStrategy(ComplexityCeilingType ceilingType, double ceilingValue)
        {
            _ceilingType       = ceilingType;
            _complexityCeiling = ceilingValue;

            // For relative complexity ceiling we await the first call to DetermineMode() before setting the threshold
            // relative to the population mean complexity. Indicate this with -1.0.
            if (ComplexityCeilingType.Relative == ceilingType)
            {
                _complexityCeilingCurrent = -1.0;
            }
            else
            {
                _complexityCeilingCurrent = ceilingValue;
            }

            _currentMode = ComplexityRegulationMode.Complexifying;
        }
Exemple #13
0
        /// <summary>
        /// Construct a new instance.
        /// </summary>
        /// <param name="relativeComplexityCeiling">The relative complexity ceiling.</param>
        /// <param name="minSimplifcationGenerations">The minimum number of generations we stay within simplification mode.</param>
        public RelativeComplexityRegulationStrategy(
            int minSimplifcationGenerations,
            double relativeComplexityCeiling)
        {
            _minSimplifcationGenerations = minSimplifcationGenerations;
            _relativeComplexityCeiling   = relativeComplexityCeiling;
            _complexityCeiling           = relativeComplexityCeiling;
            _currentMode = ComplexityRegulationMode.Complexifying;
            _lastTransitionGeneration = 0;

            if (minSimplifcationGenerations < 1)
            {
                throw new ArgumentException(nameof(minSimplifcationGenerations));
            }
            if (relativeComplexityCeiling < 1)
            {
                throw new ArgumentException(nameof(relativeComplexityCeiling));
            }
        }
        /// <summary>
        /// Determine which complexity regulation mode the search should be in given the provided
        /// NEAT algorithm stats.
        /// </summary>
        public ComplexityRegulationMode DetermineMode(NeatAlgorithmStats stats)
        {
            if (ComplexityRegulationMode.Complexifying == _currentMode)
            {
                if (-1.0 == _complexityCeilingCurrent)
                {   // First call to DetermineMode(). Continue complexifying and set threshold relative current complexity.
                    _complexityCeilingCurrent = stats._meanComplexity + _complexityCeiling;
                }
                // Currently complexifying. Test if the complexity ceiling has been reached.
                else if (stats._meanComplexity > _complexityCeilingCurrent)
                {   // Switch to simplifying mode.
                    _currentMode = ComplexityRegulationMode.Simplifying;
                    _lastTransitionGeneration = stats._generation;
                }
            }
            else
            {   // Currently simplifying. Test if simplication (ongoing reduction in complexity) has stalled.
                // We allow simplification to progress for a few generations before testing of it has stalled, this allows
                // a lead in time for the effects of simplification to occur.
                // In addition we do not switch to complexifying if complexity is above the currently defined ceiling.
                if (((stats._generation - _lastTransitionGeneration) > MinSimplifcationGenerations) &&
                    (stats._meanComplexity < _complexityCeilingCurrent) &&
                    ((stats._complexityMA.Mean - stats._prevComplexityMA) >= 0.0))
                {   // Simplification has stalled. Switch back to complexification.
                    _currentMode = ComplexityRegulationMode.Complexifying;
                    _lastTransitionGeneration = stats._generation;

                    // Redefine the complexity ceiling (for relative ceiling only).
                    if (ComplexityCeilingType.Relative == _ceilingType)
                    {
                        _complexityCeilingCurrent = stats._meanComplexity + _complexityCeiling;
                    }
                }
            }
            return(_currentMode);
        }
        /// <summary>
        /// Progress forward by one generation. Perform one generation/iteration of the evolution algorithm.
        /// </summary>
        protected override void PerformOneGeneration()
        {
            // Calculate statistics for each specie (mean fitness, target size, number of offspring to produce etc.)
            int offspringCount;

            SpecieStats[] specieStatsArr = CalcSpecieStats(out offspringCount);

            // Create offspring.
            List <TGenome> offspringList = CreateOffspring(specieStatsArr, offspringCount);

            // Trim species back to their elite genomes.
            bool emptySpeciesFlag = TrimSpeciesBackToElite(specieStatsArr);

            // Rebuild _genomeList. It will now contain just the elite genomes.
            RebuildGenomeList();

            // Append offspring genomes to the elite genomes in _genomeList. We do this before calling the
            // _genomeListEvaluator.Evaluate because some evaluation schemes re-evaluate the elite genomes
            // (otherwise we could just evaluate offspringList).
            _genomeList.AddRange(offspringList);

            // Evaluate genomes.
            _genomeListEvaluator.Evaluate(_genomeList);

            // Integrate offspring into species.
            if (emptySpeciesFlag)
            {
                // We have one or more terminated species. Therefore we need to fully re-speciate all genomes to divide them
                // evenly between the required number of species.

                // Clear all genomes from species (we still have the elite genomes in _genomeList).
                ClearAllSpecies();

                // Speciate genomeList.
                _speciationStrategy.SpeciateGenomes(_genomeList, _specieList);
            }
            else
            {
                // Integrate offspring into the existing species.
                _speciationStrategy.SpeciateOffspring(offspringList, _specieList);
            }
            Debug.Assert(!TestForEmptySpecies(_specieList), "Speciation resulted in one or more empty species.");

            // Sort the genomes in each specie. Fittest first (secondary sort - youngest first).
            SortSpecieGenomes();

            // Update stats and store reference to best genome.
            UpdateBestGenome();
            UpdateStats();

            // Determine the complexity regulation mode and switch over to the appropriate set of evolution
            // algorithm parameters. Also notify the genome factory to allow it to modify how it creates genomes
            // (e.g. reduce or disable additive mutations).
            _complexityRegulationMode = _complexityRegulationStrategy.DetermineMode(_stats);
            _genomeFactory.SearchMode = (int)_complexityRegulationMode;
            switch (_complexityRegulationMode)
            {
            case ComplexityRegulationMode.Complexifying:
                _eaParams = _eaParamsComplexifying;
                break;

            case ComplexityRegulationMode.Simplifying:
                _eaParams = _eaParamsSimplifying;
                break;
            }

            // TODO: More checks.
            Debug.Assert(_genomeList.Count == _populationSize);
        }
        /// <summary>
        /// Determine which complexity regulation mode the search should be in given the provided
        /// NEAT algorithm stats.
        /// </summary>
        public ComplexityRegulationMode DetermineMode(NeatAlgorithmStats stats)
        {
            if(ComplexityRegulationMode.Complexifying == _currentMode)
            {
                if(-1.0 == _complexityCeilingCurrent)
                {   // First call to DetermineMode(). Continue complexifying and set threshold relative current complexity.
                    _complexityCeilingCurrent = stats._meanComplexity + _complexityCeiling;
                } 
                // Currently complexifying. Test if the complexity ceiling has been reached.
                else if(stats._meanComplexity > _complexityCeilingCurrent)
                {   // Switch to simplifying mode.
                    _currentMode = ComplexityRegulationMode.Simplifying;
                    _lastTransitionGeneration = stats._generation;
                }
            }
            else
            {   // Currently simplifying. Test if simplication (ongoing reduction in complexity) has stalled.
                // We allow simplification to progress for a few generations before testing of it has stalled, this allows
                // a lead in time for the effects of simplification to occur.
                // In addition we do not switch to complexifying if complexity is above the currently defined ceiling.
                if(((stats._generation - _lastTransitionGeneration) > MinSimplifcationGenerations) 
                 && (stats._meanComplexity < _complexityCeilingCurrent)
                 && ((stats._complexityMA.Mean - stats._prevComplexityMA) >= 0.0))
                {   // Simplification has stalled. Switch back to complexification.
                    _currentMode = ComplexityRegulationMode.Complexifying;
                    _lastTransitionGeneration = stats._generation;

                    // Redefine the complexity ceiling (for relative ceiling only).
                    if(ComplexityCeilingType.Relative == _ceilingType) {
                        _complexityCeilingCurrent = stats._meanComplexity + _complexityCeiling;
                    }
                }
            }
            return _currentMode;
        }