/// <inheritdoc /> public void RequeueEvaluation(GenomeInstancePair <TInstance> evaluation) { foreach (var manager in this._tournamentManagers) { manager.RequeueEvaluationIfRelevant(evaluation); } }
/// <summary> /// Requeues the given evaluation, if relevant for this mini tournament. /// </summary> /// <param name="evaluation">The evaluation.</param> public void RequeueEvaluationIfRelevant(GenomeInstancePair <TInstance> evaluation) { lock (this._lock) { if (!this._genomeToGenomeStats.TryGetValue(evaluation.Genome, out var genomeStats)) { return; } var genomeKey = new GenomeTournamentKey(evaluation.Genome, this.MiniTournamentId); var genomePriority = this._runEvaluator.ComputeEvaluationPriorityOfGenome(genomeStats.ToImmutable()); if (genomeStats.RequeueInstance(evaluation.Instance)) { if (this._globalPriorityQueue != null) { if (!this._globalPriorityQueue.Contains(genomeKey)) { this._globalPriorityQueue.Enqueue( genomeKey, genomePriority); } else { this._globalPriorityQueue.UpdatePriority(genomeKey, genomePriority); } } } } }
/// <inheritdoc /> public void GenomeInstanceEvaluationFinished(GenomeInstancePair <TInstance> evaluation, TResult result) { foreach (var manager in this._tournamentManagers) { manager.UpdateResult(evaluation, result); } }
/// <summary> /// Initializes a new instance of the <see cref="GenomeInstancePairEvaluation{TInstance}"/> class. /// </summary> /// <param name="genomeInstancePair">The genome instance pair.</param> /// <param name="generationId">The generation id.</param> /// <param name="tournamentId">The tournament id.</param> /// <param name="useGrayBoxInEvaluation">Boolean indicating whether to use gray box tuning in current evaluation.</param> public GenomeInstancePairEvaluation( GenomeInstancePair <TInstance> genomeInstancePair, int generationId, int tournamentId, bool useGrayBoxInEvaluation) { this.GenomeInstancePair = genomeInstancePair ?? throw new ArgumentNullException(nameof(genomeInstancePair)); this.GenerationId = generationId; this.TournamentId = tournamentId; this.UseGrayBoxInEvaluation = useGrayBoxInEvaluation; }
/// <summary> /// Handles the information that a evaluation has started by another mini tournament manager, if relevant. /// </summary> /// <param name="evaluation">The evaluation.</param> public void NotifyEvaluationStarted(GenomeInstancePair <TInstance> evaluation) { lock (this._lock) { if (!this._genomeToGenomeStats.TryGetValue(evaluation.Genome, out var genomeStats)) { return; } genomeStats.NotifyInstanceStarted(evaluation.Instance); this.RemoveOrUpdateInPriorityQueue(new GenomeTournamentKey(evaluation.Genome, this.MiniTournamentId)); } }
public void RacingRemovesKilledGenomesFromQueue() { var participants = this.CreateGenomesDescendingByAge(2, 0).ToList(); var instances = this._instances.Take(2).ToList(); var queue = new SimplePriorityQueue <GenomeTournamentKey, double>(); // always return second genome as target to kill by racing. var evaluatorMock = new Mock <IRunEvaluator <TestInstance, ContinuousResult> >(); evaluatorMock.Setup( e => e.GetGenomesThatCanBeCancelledByRacing( It.IsAny <IReadOnlyList <ImmutableGenomeStats <TestInstance, ContinuousResult> > >(), It.IsAny <int>())) .Returns(new[] { participants[1] }); var manager = new MiniTournamentManager <TestInstance, ContinuousResult>( participants, instances, 0, 0, evaluatorMock.Object, true, 1); this.RequeueAllEvaluations(manager); manager.StartSynchronizingQueue(queue); queue.Count.ShouldBe(2); // start an instance var winnerGenome = new GenomeTournamentKey(participants[0], 0); manager.TryGetNextInstanceAndUpdateGenomePriority(winnerGenome, out var instance).ShouldBeTrue(); // send a result var result = new ContinuousResult(42, TimeSpan.Zero); var genomeInstancePair = new GenomeInstancePair <TestInstance>(winnerGenome.Genome, instance); manager.UpdateResult(genomeInstancePair, result); // second genome should have been killed by racing + removed from queue queue.Count.ShouldBe(1); queue.First.ShouldBe(winnerGenome); }
/// <inheritdoc /> public bool TryPopEvaluation(out GenomeInstancePairEvaluation <TInstance> nextEvaluation) { if (this._priorityQueue.Count <= 0) { nextEvaluation = null; return(false); } var nextGenomeKey = this._priorityQueue.First; var associatedTournamentManager = this._tournamentManagers.FirstOrDefault(tm => tm.MiniTournamentId == nextGenomeKey.TournamentId); if (associatedTournamentManager == null) { var exception = new InvalidOperationException($"Cannot find a MiniTournamentManager with ID {nextGenomeKey.TournamentId}!"); LoggingHelper.WriteLine( VerbosityLevel.Warn, $"Error: {exception.Message}"); throw exception; } if (!associatedTournamentManager.TryGetNextInstanceAndUpdateGenomePriority(nextGenomeKey, out var nextInstance)) { nextEvaluation = null; return(false); } var nextGenomeInstancePair = new GenomeInstancePair <TInstance>(nextGenomeKey.Genome, nextInstance); foreach (var manager in this._tournamentManagers.Where(tm => tm.MiniTournamentId != associatedTournamentManager.MiniTournamentId)) { manager.NotifyEvaluationStarted(nextGenomeInstancePair); } nextEvaluation = new GenomeInstancePairEvaluation <TInstance>( nextGenomeInstancePair, this._generation, associatedTournamentManager.MiniTournamentId, this._useGrayBoxInGeneration); return(true); }
/// <summary> /// Initializes a new instance of the <see cref="Faulted{TInstance}"/> class. /// </summary> /// <param name="genomeInstancePair">The genome instance pair.</param> /// <param name="reason">The reason.</param> public Faulted(GenomeInstancePair <TInstance> genomeInstancePair, Exception reason) { this.GenomeInstancePair = genomeInstancePair; this.Reason = reason; }
/// <summary> /// Handles a result update by updating the corresponding genome stats and evaluation queue and checking for racing. /// </summary> /// <param name="evaluation">The evaluation.</param> /// <param name="result">The result.</param> public void UpdateResult(GenomeInstancePair <TInstance> evaluation, TResult result) { lock (this._lock) { if (!this._genomeToGenomeStats.TryGetValue(evaluation.Genome, out var genomeStats)) { return; } if (!genomeStats.FinishInstance(evaluation.Instance, result)) { LoggingHelper.WriteLine( VerbosityLevel.Warn, $"Trying to finish instance {evaluation.Instance} with result {result}, but it was not in GenomeStats.RunningInstances."); } if (this._enableRacing) { var currentExpandedImmutableGenomeStats = this.GetExpandedImmutableGenomeStats().ToList(); var canBeCancelledByRacing = this._runEvaluator .GetGenomesThatCanBeCancelledByRacing(currentExpandedImmutableGenomeStats, this._desiredNumberOfWinners) .ToHashSet(ImmutableGenome.GenomeComparer); if (canBeCancelledByRacing.Any()) { var numberOfCancelledByRacing = currentExpandedImmutableGenomeStats.Count(gs => gs.IsCancelledByRacing || canBeCancelledByRacing.Contains(gs.Genome)); if (numberOfCancelledByRacing > this.Participants.Count() - this._desiredNumberOfWinners) { var exception = new InvalidOperationException( $"You cannot cancel more genomes by racing than number of participants - desired number of winners!{Environment.NewLine}Number of genomes cancelled by racing: {numberOfCancelledByRacing}{Environment.NewLine}Number of participants: {this.Participants.Count()}{Environment.NewLine}Desired number of winners: {this._desiredNumberOfWinners}"); LoggingHelper.WriteLine( VerbosityLevel.Warn, $"Error: {exception.Message}"); throw exception; } foreach (var genome in canBeCancelledByRacing) { if (this._genomeToGenomeStats[genome].UpdateCancelledByRacing()) { try { if (this._globalPriorityQueue == null) { // We are in result storage update phase! continue; } this._globalPriorityQueue.Remove(this._genomeToGenomeTournamentKey[genome]); } catch (InvalidOperationException) { } } } } } var genomeKey = this._genomeToGenomeTournamentKey[evaluation.Genome]; this.RemoveOrUpdateInPriorityQueue(genomeKey); } }
/// <inheritdoc /> public void RequeueEvaluation(GenomeInstancePair <TInstance> evaluation) { this._genomeToGenomeStats[evaluation.Genome].RequeueInstance(evaluation.Instance); }
/// <inheritdoc /> public void GenomeInstanceEvaluationFinished(GenomeInstancePair <TInstance> evaluation, TResult result) { this._genomeToGenomeStats[evaluation.Genome].FinishInstance(evaluation.Instance, result); }
/// <summary> /// Initializes a new instance of the <see cref="EvaluationResult{TInstance,TResult}" /> class. /// </summary> /// <param name="genomeInstancePair">The <see cref="GenomeInstancePair{TInstance}"/>.</param> /// <param name="runResult">The run result.</param> public EvaluationResult(GenomeInstancePair <TInstance> genomeInstancePair, TResult runResult) { this.GenomeInstancePair = genomeInstancePair ?? throw new ArgumentNullException(nameof(genomeInstancePair)); this.RunResult = runResult ?? throw new ArgumentNullException(nameof(runResult)); }