public Task <Pollinator> ApplyRuleAsync(Pollinator pollinator, ResetPollinationRuleArgument ruleArgument)
        {
            var current = ruleArgument.NewPollinator;
            var group   = ruleArgument.Group;

            return(Task.Run(() =>
            {
                if (!current.CheckWhetherValuesCorrect())
                {
                    _logger.Error($"Pollinator got NaN or +/- Infinity. Pollinator - {PollinatorExtensions.ToString(current)}");
                    return pollinator;
                }

                Pollinator best;

                var currentSolution = pollinator.CountFunction(_functionStrategy);
                var newSolution = current.CountFunction(_functionStrategy);

                _logger.Trace($"Current solution {currentSolution}");
                _logger.Trace($"New solution {newSolution}");

                if (currentSolution > newSolution && _isMin ||
                    newSolution > currentSolution && !_isMin)
                {
                    group.Replace(pollinator, current);
                    best = current;
                }
                else
                {
                    best = pollinator;
                }

                if (RandomGenerator.Random.NextDouble() < _pReset)
                {
                    _logger.Trace($"Before pollinator reset is {PollinatorExtensions.ToString(best)}");

                    var generated = _pollinatorUpdater.Update(best);
                    group.Replace(best, generated);
                    best = generated;

                    _logger.Trace($"After pollinator reset is {PollinatorExtensions.ToString(best)}");
                }

                return best;
            }));
        }
        public Task <Pollinator> ApplyRuleAsync(Pollinator pollinator, LocalPollinationRuleArgument ruleArgument)
        {
            var randomPollinator = ruleArgument.RandomPollinator;

            _logger.Trace($"Random pollinator is {PollinatorExtensions.ToString(randomPollinator)}");
            _logger.Trace($"Current pollinator is {PollinatorExtensions.ToString(pollinator)}");

            return(Task.Run(() =>
            {
                var rand = RandomGenerator.Random.NextDouble();

                var result = pollinator + rand * randomPollinator - pollinator;

                _logger.Trace($"Global result pollinator is {PollinatorExtensions.ToString(result)}");

                return result;
            }));
        }
        public async Task <Pollinator> PolinateAsync()
        {
            var t            = 0;
            var bestSolution = _groups.GetBestSolution(_functionStrategy, _algorithmSettings.IsMin);

            while (++t <= _algorithmSettings.MaxGeneration)
            {
                _logger.Debug($"Start step {t}");
                await PolinateOnceAsync();

                bestSolution = _groups.GetBestSolution(_functionStrategy, _algorithmSettings.IsMin);

                OnStepFinished(new StepFinishedArgs(bestSolution, t));

                _logger.Debug($"Best pollinator after step {t} is {PollinatorExtensions.ToString(bestSolution)}");
                _logger.Debug($"Best solution after step {t} is {bestSolution.CountFunction(_functionStrategy)}");
            }

            return(bestSolution);
        }
        public Task <Pollinator> ApplyRuleAsync(Pollinator pollinator, GlobalPollinationRuleArgument ruleArgument)
        {
            var bestPollinator = ruleArgument.BestPollinator;

            _logger.Trace($"Best pollinator is {PollinatorExtensions.ToString(bestPollinator)}");
            _logger.Trace($"Current pollinator is {PollinatorExtensions.ToString(pollinator)}");

            return(Task.Run(() =>
            {
                var distanceDifference = (pollinator - bestPollinator)
                                         .CountFunction(FunctionStrategies.FunctionStrategies.DistanceFunction);

                var lambda = FunctionStrategies.FunctionStrategies.LambdaFunction(distanceDifference);

                var rand = FunctionStrategies.FunctionStrategies.MantegnaFunction(lambda);

                var result = pollinator + rand * (pollinator - bestPollinator);

                _logger.Trace($"Global result pollinator is {PollinatorExtensions.ToString(result)}");

                return result;
            }));
        }