Exemple #1
0
        /// <summary>
        /// Sorts genomes using the <see cref="_generationEvaluationActor"/>.
        /// </summary>
        /// <param name="genomesToSort">The <see cref="ImmutableGenome"/>s to sort.</param>
        /// <returns>The sorting result.</returns>
        protected SortResult SortGenomes(ImmutableList <ImmutableGenome> genomesToSort)
        {
            var generationEvaluationMessage = new GenerationEvaluation <TInstance, TResult>(
                genomesToSort,
                this._instances,
                (runEvaluator, participantsOfGeneration, instancesOfGeneration) =>
                new SortingGenerationEvaluationStrategy <TInstance, TResult>(
                    runEvaluator,
                    participantsOfGeneration,
                    instancesOfGeneration,
                    this._currentGeneration,
                    this._useGrayBoxInGeneration));

            var generationEvaluationTask = this._generationEvaluationActor.Ask <SortResult>(generationEvaluationMessage).ContinueWith(
                task =>
            {
                if (task.IsFaulted)
                {
                    throw new InvalidOperationException(
                        $"The generation evaluation in generation {this._currentGeneration} resulted in an exception!{Environment.NewLine}Message: {task.Exception?.Message}");
                }

                return(task.Result);
            });

            generationEvaluationTask.Wait();
            return(generationEvaluationTask.Result);
        }
Exemple #2
0
        /// <summary>
        /// The <see cref="Ready"/> state is responsible for handling generation evaluation messages.
        /// </summary>
        private void Ready()
        {
            this.Receive <GenerationEvaluation <TInstance, TResult> >(
                generationEvaluation =>
            {
                this.SetGenerationEvaluationIssuer(this.Sender);
                this._currentGenerationEvaluation = generationEvaluation;
                this._evaluationStrategy          = generationEvaluation.EvaluationStrategyFactory(
                    this._runEvaluator,
                    generationEvaluation.Participants,
                    generationEvaluation.Instances);
                this._genomesWaitingForResultsFromStorage = new HashSet <ImmutableGenome>(
                    generationEvaluation.Participants,
                    ImmutableGenome.GenomeComparer);

                this.Become(this.FetchingResultsFromStorage);
                foreach (var genome in this._genomesWaitingForResultsFromStorage.ToList())
                {
                    this._resultStorageActor.Tell(new GenomeResultsRequest(genome));
                }
            });

            // Unreachable member events should always be handled to keep the Akka.NET cluster clean.
            this.Receive <ClusterEvent.UnreachableMember>(
                this.HandleUnreachableMessage);
        }
Exemple #3
0
        /// <summary>
        /// Evaluates all incumbent genomes on the provided instances.
        /// </summary>
        /// <param name="allIncumbentGenomes">All incumbent genomes.</param>
        /// <param name="instances">The instances.</param>
        /// <returns>The <see cref="GgaResult{TResult}"/>.</returns>
        public GgaResult <TResult> EvaluateAllIncumbentGenomes(
            IEnumerable <ImmutableGenome> allIncumbentGenomes,
            IEnumerable <TInstance> instances)
        {
            if (allIncumbentGenomes == null)
            {
                throw new ArgumentNullException(nameof(allIncumbentGenomes));
            }

            if (!allIncumbentGenomes.Any())
            {
                throw new ArgumentOutOfRangeException(nameof(allIncumbentGenomes));
            }

            if (instances == null)
            {
                throw new ArgumentNullException(nameof(instances));
            }

            if (!instances.Any())
            {
                throw new ArgumentOutOfRangeException(nameof(instances));
            }

            // Set generation to -1 and disable gray box, since this is a "post tuning generation".
            var generationEvaluationMessage = new GenerationEvaluation <TInstance, TResult>(
                allIncumbentGenomes,
                instances,
                (runEvaluator, participantsOfGeneration, instancesOfGeneration) =>
                new MiniTournamentGenerationEvaluationStrategy <TInstance, TResult>(
                    runEvaluator,
                    participantsOfGeneration,
                    instancesOfGeneration,
                    -1,
                    this._configuration,
                    false,
                    true));

            var generationEvaluationTask = this._generationEvaluationActor.Ask <GgaResult <TResult> >(generationEvaluationMessage).ContinueWith(
                task =>
            {
                if (task.IsFaulted)
                {
                    throw new InvalidOperationException(
                        $"The evaluation of all incumbent genomes resulted in an exception!{Environment.NewLine}Message: {task.Exception?.Message}");
                }

                return(task.Result);
            });

            generationEvaluationTask.Wait();
            return(generationEvaluationTask.Result);
        }
Exemple #4
0
        /// <summary>
        /// Selects those genomes from the competitive part of the population that are allowed to reproduce.
        /// </summary>
        /// <param name="instancesForEvaluation">
        /// The <typeparamref name="TInstance"/>s to use for evaluation.
        /// </param>
        /// <returns>
        /// Competitive genomes allowed to reproduce.
        /// </returns>
        private TournamentWinnersWithRank <TResult> PerformSelection(
            IEnumerable <TInstance> instancesForEvaluation)
        {
            var generationEvaluationMessage = new GenerationEvaluation <TInstance, TResult>(
                this._population.GetCompetitiveIndividuals().Select(genome => new ImmutableGenome(genome)),
                instancesForEvaluation,
                (runEvaluator, participantsOfGeneration, instancesOfGeneration) => new MiniTournamentGenerationEvaluationStrategy <TInstance, TResult>(
                    runEvaluator,
                    participantsOfGeneration,
                    instancesOfGeneration,
                    this._currentGeneration,
                    this._configuration,
                    this._useGrayBoxInGeneration,
                    false));

            var generationEvaluationTask = this._tournamentSelector.Ask <GgaResult <TResult> >(generationEvaluationMessage).ContinueWith(
                task =>
            {
                if (task.IsFaulted)
                {
                    // It was impossible to determine the best genomes, i.e. something really bad happened.
                    // In this case, we throw an exception for the caller to handle.
                    throw new InvalidOperationException(
                        $"The generation evaluation with GGA in generation {this._currentGeneration} resulted in an exception!{Environment.NewLine}Message: {task.Exception?.Message}");
                }

                var result = new TournamentWinnersWithRank <TResult>(
                    task.Result.CompetitiveParents,
                    task.Result.GenerationBest,
                    task.Result.GenerationBestResult,
                    task.Result.GenomeToTournamentRank);
                return(result);
            });

            generationEvaluationTask.Wait();
            return(generationEvaluationTask.Result);
        }
Exemple #5
0
        public static void Crossover(this CrossoverFunction crossoverFunction, NeuralNetwork child,
                                     GenerationEvaluation evaluation, SelectionFunction selectionFunction, float fitnessPower)
        {
            var(b, w)          = evaluation.pool.Select(selectionFunction, fitnessPower);
            var(better, worse) = (b.Genes, w.Genes);

            var genes     = child.genes;
            var count     = genes.Length;
            var halfCount = genes.Length / 2;

            switch (crossoverFunction)
            {
            case CrossoverFunction.HalfWorstBest:
                for (var i = 0; i < halfCount; i++)
                {
                    child.genes[i] = better[i];
                }
                for (var i = halfCount; i < count; i++)
                {
                    child.genes[i] = worse[i];
                }
                break;

            case CrossoverFunction.HalfBestWorse:
                for (var i = 0; i < halfCount; i++)
                {
                    child.genes[i] = worse[i];
                }
                for (var i = halfCount; i < count; i++)
                {
                    child.genes[i] = better[i];
                }
                break;

            case CrossoverFunction.HalfRandomShift:
                var shift    = Random.Range(0, count - 1);
                var overlaps = shift + halfCount > count - 1;

                for (var i = 0; i < count; i++)
                {
                    child.genes[i] = (!overlaps && i > shift && i < shift + halfCount || overlaps && !(i > shift && i < shift + halfCount) ? better : worse)[i];
                }
                break;

            case CrossoverFunction.Step:
                for (var i = 0; i < count; i++)
                {
                    genes[i] = (i % 2 == 0 ? better : worse)[i];
                }
                break;

            case CrossoverFunction.StepRandom:
                for (var i = 0; i < count; i++)
                {
                    genes[i] = (Random.value > .5f ? better : worse)[i];
                }
                break;

            case CrossoverFunction.FractionRandom: {
                for (var i = 0; i < count; i++)
                {
                    var fraction = Random.value;
                    genes[i] = better[i] * fraction + worse[i] * (1f - fraction);
                }

                break;
            }

            case CrossoverFunction.FractionByFitness: {
                var fraction = b.Fitness / (b.Fitness + w.Fitness);
                for (var i = 0; i < count; i++)
                {
                    genes[i] = better[i] * fraction + worse[i] * (1f - fraction);
                }

                break;
            }

            case CrossoverFunction.Average:
            default:
                for (var i = 0; i < count; i++)
                {
                    genes[i] = (better[i] + worse[i]) * .5f;
                }
                break;
            }
        }