示例#1
0
    public void CreateNewPopulation()
    {
        var tmp = populationGens;

        populationGens  = populationGens2;
        populationGens2 = tmp;

        // var b = new FlattArray<byte>((byte[])populationGens, genLength).To2d();
        Profiler.Start("Calculate fitness");
        fitnessCalc.CalculateFitness(populationGens, deviceFitnes);
        Profiler.Stop("Calculate fitness");

        Profiler.Start("sqauance");
        Thrust.seaquance(fitnessIndeces);
        Profiler.Stop("sqauance");

        Profiler.Start("sorting fitness");
        Thrust.sort_by_key(deviceFitnes, fitnessIndeces);
        Profiler.Stop("sorting fitness");

        Profiler.Start("performing genetics");
        // var c = new FlattArray<byte>((byte[])populationGens, genLength).To2d();

        performGeneticAlgorythm.Run(
            populationGens.DevicePointer,
            populationGens2.DevicePointer,
            deviceFitnes.DevicePointer,
            fitnessIndeces.DevicePointer
            );
        //var a = new FlattArray<byte>((byte[])populationGens, genLength).To2d() ;

        Profiler.Stop("performing genetics");
    }
        /// <summary>
        ///     Run a single generation of the process.
        /// </summary>
        /// <exception cref="InvalidOperationException"></exception>
        // ReSharper disable always PossibleNullReferenceException
        public void RunGeneration()
        {
            #region Validation

            if (_population == null)
            {
                throw new InvalidOperationException($"{nameof(_population)} was null");
            }
            if (_survivorSelector == null)
            {
                throw new InvalidOperationException($"{nameof(_survivorSelector)} was null");
            }
            if (_populationModifiers == null)
            {
                throw new InvalidOperationException($"{nameof(_populationModifiers)} was null");
            }
            if (_parentSelector == null)
            {
                throw new InvalidOperationException($"{nameof(_parentSelector)} was null");
            }
            if (_processInformationComposer == null)
            {
                throw new InvalidOperationException($"{nameof(_processInformationComposer)} was null");
            }

            #endregion

            _isRunning = true;

            UInt64 generationCount = _previousProcessInformation?.GetGeneration() ?? 0;
            LogDebug($"Starting generation {generationCount}");

            // Select parents to produce new generation of offspring.
            LogDebug("Selecting parents");

            IList <IEnumerable <TIndividual> > parentGroups = _parentSelector.GetParents(_population).ToList();

            // Log parents and their fitness.
            Int32 parentGroupCount = 0;
            foreach (IEnumerable <TIndividual> parentGroup in parentGroups)
            {
                Double         totalFitness  = 0;
                IList <String> parentStrings = new List <String>();
                foreach (TIndividual parent in parentGroup)
                {
                    IndividualWithFitness <TIndividual, TGene> individualParent =
                        _population.GetIndividualWithFitness(parent.GetGuid());

                    Double parentFitness = individualParent.GetFitness();
                    parentStrings.Add($"P {parent.GetGuidStringShort()} F {parentFitness}");
                    totalFitness += parentFitness;
                }

                LogInfo($"PG {parentGroupCount}, TF {totalFitness}, " + $"{string.Join(", ", parentStrings)}");

                parentGroupCount++;
            }

            if (parentGroups == null || !parentGroups.Any())
            {
                throw new InvalidOperationException("Failed to get parents");
            }

            // Mate selected parents, produce offspring.
            LogDebug("Mating parents; creating offspring");
            IList <TIndividual> offspring =
                parentGroups.Select(parentGroup => _matingFunction.Mate(parentGroup.ToList())).ToList();

            // Log unmodified offspring fitness.
            foreach (TIndividual individualOffspring in offspring)
            {
                Double offspringFitness = _fitnessFunction.CalculateFitness(individualOffspring);
                LogInfo($"O {individualOffspring.GetGuidStringShort()} F {offspringFitness}");
            }

            // Add new offspring to population.
            LogDebug("Selecting survivors; adding offspring to population");
            _survivorSelector.AddOffspring(_population, offspring);

            // Apply population modifiers to population.
            LogDebug("Applying population modifier");
            foreach (IPopulationModifier <TPopulation, TIndividual, TGene> populationModifier in _populationModifiers)
            {
                _population = populationModifier.ModifyPopulation(_population);
            }

            // Order by fitness.
            LogDebug("Ordering population by fitness");
            _population.OrderByFitness(_fitnessFunction);

            // Create information object.
            TProcessInformation currentGenerationProcessInformation =
                _processInformationComposer.ComposeProcessInformation(_previousProcessInformation, _population);

            AddToHistory(currentGenerationProcessInformation);

            LogInfo($"G{generationCount} TF {currentGenerationProcessInformation.GetTotalFitness()}");

            // Check if population has converged according to provided checks.
            if (!_hasConverged)
            {
                if (_terminationConditions.Any(terminationCondition =>
                                               terminationCondition.ShouldTerminate(_population, currentGenerationProcessInformation)))
                {
                    _hasConverged = true;
                    LogInfo("Population has converged! Termination condition met!");
                }
            }

            // Compose new process information object.
            _previousProcessInformation = currentGenerationProcessInformation;

            if (!_isRunningLocked)
            {
                _isRunning = false;
            }
        }