public List <ProblemPerformanceSingleObjective> RunAssessment( int numberOfRestarts, int reportingFrequency, Action <Population> reporters, Action <int> iterationReporter, int timeOutEvaluations = 0, TimeSpan?timeOutDuration = null, int numberOfNewIndividualsPerGeneration = 1) { var results = new List <ProblemPerformanceSingleObjective>(); for (var i = 1; i <= numberOfRestarts; i++) { var optimiserRunner = new OptimiserRunnerBasic(builder, evaluator, convergenceCheckers, reporters); optimiserRunner.Run( reportingFrequency: reportingFrequency, timeOutEvaluations: timeOutEvaluations, timeOutDuration: timeOutDuration, newIndividualsPerGeneration: numberOfNewIndividualsPerGeneration); results.Add( new ProblemPerformanceSingleObjective( builder.CreateOptimiser().ToString(), evaluator, optimiserRunner)); iterationReporter(i); } return(results); }
/// <summary> /// Constructor. /// </summary> /// <param name="builder">The builder for the optimisation elements.</param> /// <param name="evaluator">The evaluator.</param> /// <param name="convergenceCheckers">Checks for early completion.</param> /// <param name="reporters">The action that reports progress.</param> public OptimiserRunnerParallel( OptimiserBuilder builder, IEvaluator evaluator, Func <Population, bool> convergenceCheckers, Action <Population> reporters) { this.builder = builder; this.evaluator = evaluator; this.convergenceCheckers = convergenceCheckers; reportingAgent = new ActionBlock <Population>(reporters); NumberOfIndividualsToStart = builder.CreateOptimiser().Population.TargetSize / 4; if (NumberOfIndividualsToStart < 4) { NumberOfIndividualsToStart = 4; } }
/// <summary> /// Initialises all the buffers to be ready. /// </summary> /// <param name="timeOutManager">The <see cref="TimeOutManager"/>.</param> /// <param name="reportingFrequency">The number of reinsertions between reports on the current population</param> /// <param name="numberOfNewIndividualsPerGeneration">The number of new individuals to generate whenever an individual is reinserted.</param> private void setUpAgents( TimeOutManager timeOutManager, int reportingFrequency, int numberOfNewIndividualsPerGeneration) { reinsertionAgent = new ReinsertionAgent( builder.CreateOptimiser(), builder.CreateModel(), timeOutManager, convergenceCheckers, reportingFrequency, numberOfNewIndividualsPerGeneration); evaluationAgent = new EvaluationAgent( evaluator, reinsertionAgent.CancellationSource.Token); //Create link so that newly created individuals from the ReinsertionAgent // are pushed to the EvaluationAgent reinsertionAgent.NewIndividuals.LinkTo( evaluationAgent.IndividualsForEvaluation, new DataflowLinkOptions() { PropagateCompletion = true }); //Create link so that evaluated individuals from the EvaluationAgent // are pushed to the ReinsertionAgent evaluationAgent.EvaluatedIndividuals.LinkTo( reinsertionAgent.IndividualsForReinsertion, new DataflowLinkOptions() { PropagateCompletion = true }); //Create link so that reports from the ReinsertionAgent // are pushed to the reporting delegates reinsertionAgent.Reports.LinkTo(reportingAgent, new DataflowLinkOptions() { PropagateCompletion = true }); }
/// <summary> /// Runs the optimisation. /// </summary> /// <param name="storeAll"><see langword="true"/> to store all individuals evaluated (memory required).</param> /// <param name="reportingFrequency">The number of evaluations between reporting progress.</param> /// <param name="timeOutEvaluations">The maximum number of evaluations before terminating the optimisation.</param> /// <param name="timeOutDuration">The maximum time allowed before terminating the optimisation.</param> /// <param name="newIndividualsPerGeneration">The number of new <see cref="Individual"/>s to generate each time new individuals are generated from the <see cref="Population"/>.</param> public override void Run( bool storeAll = true, int reportingFrequency = 100, int timeOutEvaluations = 0, TimeSpan?timeOutDuration = null, int newIndividualsPerGeneration = 1) { // Initialise StartTime = DateTime.Now; var optimiser = builder.CreateOptimiser(); var model = builder.CreateModel(); cancelDemanded = false; //Setup if (newIndividualsPerGeneration <= 0) { throw new ArgumentOutOfRangeException(nameof(newIndividualsPerGeneration), "At least one new individual must be created each generation."); } var nextInds = optimiser.GetNextToEvaluate(newIndividualsPerGeneration); if (timeOutEvaluations == 0) { var numDims = nextInds[0].DecisionVector.Count; timeOutEvaluations = Math.Min(numDims * 20000, 2000000); } var timeOutDurationNotNull = TimeSpan.MaxValue; if (timeOutDuration != null) { timeOutDurationNotNull = timeOutDuration.Value; } timeOutManager = new TimeOutManager(timeOutEvaluations, timeOutDurationNotNull); AllEvaluated = new List <Individual>(); FinalPopulation = null; BestFound = null; //Go! while (nextInds.Count > 0 && nextInds[0].DecisionVector.Count > 0) { foreach (var nextInd in nextInds) { nextInd.SetProperty( OptimiserPropertyNames.CreationIndex, timeOutManager.EvaluationsRun); // Evaluate model.PrepareForEvaluation(nextInd); evaluator.Evaluate(nextInd); } // Reinsert optimiser.ReInsert(nextInds); foreach (var nextInd in nextInds) { nextInd.SetProperty( OptimiserPropertyNames.ReinsertionIndex, timeOutManager.EvaluationsRun); timeOutManager.IncrementEvaluationsRun(); } // Store if (storeAll) { AllEvaluated.AddRange(nextInds); } // Update best var bestInd = optimiser.Population.Best(); if (BestFound == null || (bestInd != null && bestInd.Fitness < BestFound.Fitness)) { BestFound = bestInd; } // Create individuals for next loop nextInds = optimiser.GetNextToEvaluate(newIndividualsPerGeneration); // Check for completion if (timeOutManager.HasPerformedTooManyEvaluations() || timeOutManager.HasRunOutOfTime() || cancelDemanded) { //Bored... break; } if (optimiser.Population.IsTargetSizeReached) { if (convergenceCheckers(optimiser.Population)) { break; } } if (timeOutManager.EvaluationsRun % reportingFrequency == 0) { reporters(optimiser.Population); } } reporters(optimiser.Population); //Finish off FinalPopulation = optimiser.Population; }