예제 #1
0
        /// <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;
        }
예제 #2
0
        /// <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)
        {
            StartTime = DateTime.Now;

            // Calculate time outs automatically if not provided
            if (timeOutEvaluations == 0)
            {
                var numDims =
                    builder.CreateModel().GetNewDecisionVector().Count;
                timeOutEvaluations = Math.Min(numDims * 20000, 2000000);
            }

            var timeOutDurationNotNull = TimeSpan.MaxValue;

            if (timeOutDuration != null)
            {
                timeOutDurationNotNull = timeOutDuration.Value;
            }

            var timeOutManager = new TimeOutManager(timeOutEvaluations, timeOutDurationNotNull);

            if (newIndividualsPerGeneration <= 0)
            {
                throw new ArgumentOutOfRangeException(nameof(newIndividualsPerGeneration),
                                                      "At least one new individual must be created each generation.");
            }

            setUpAgents(timeOutManager, reportingFrequency, newIndividualsPerGeneration);

            if (reinsertionAgent == null || evaluationAgent == null)
            {
                throw new ApplicationException("Failed to initialise TPL buffers.");
            }

            reinsertionAgent.SaveAll = storeAll;

            // Get started
            var pumpPrimingInds = reinsertionAgent.CreateNewIndividuals(
                Math.Max(NumberOfIndividualsToStart, newIndividualsPerGeneration));

            foreach (var ind in pumpPrimingInds)
            {
                reinsertionAgent.NewIndividuals.Post(ind);
            }

            // Wait for completion
            try
            {
                Task.WaitAll(
                    reinsertionAgent.IndividualsForReinsertion.Completion,
                    reinsertionAgent.NewIndividuals.Completion,
                    evaluationAgent.EvaluatedIndividuals.Completion,
                    evaluationAgent.IndividualsForEvaluation.Completion);
            }
            catch (AggregateException e) when(e.InnerExceptions.All(ie => ie is TaskCanceledException))
            {
                // There is no way to wait for cancellation,
                // so we have to wait for completion and then
                // ignore the cancellation errors
            }

            FinalPopulation = reinsertionAgent.GetCurrentPopulation();
            AllEvaluated    = reinsertionAgent.AllEvaluated;

            if (FinalPopulation.Count <= 0)
            {
                return;
            }

            // Not really the best found unless the optimiser is elitist
            BestFound = FinalPopulation.Best();
        }