private void OptimizationLoop() { population = new List <OptimizableStructure>(); scoreList = new List <double>(); if (optimizationMethod == OptimizationMethod.GA) { stopWatch.Start(); running = true; double elapsedOptimizationTime; SetUpGeneticAlgorithm(); creepMutationRate = 0; bestScore = double.MinValue; iterationIndex = 0; numberOfEvaluatedIndividuals = 0; double minimumParameterValue = optimizationSettings.MinimumSpeedValue; double maximumParameterValue = optimizationSettings.MaximumSpeedValue; double desiredAverageSpeed = optimizationSettings.DesiredAverageSpeed; while (running) { for (int ii = 0; ii < populationSize; ii++) { OptimizableStructure individual = population[ii].Copy(); speedProfileEvaluator = new PiecewiseLinearSpeedProfileEvaluator(); speedProfileEvaluator.AssignMetricMap(metricMap); speedProfileEvaluator.AssignMetricPath(metricPath); speedProfileEvaluator.MaximumAllowedSpeed = maximumParameterValue; speedProfileEvaluator.MinimumAllowedSpeed = minimumParameterValue; speedProfileEvaluator.DesiredAverageSpeed = desiredAverageSpeed; speedProfileEvaluator.AssignPossibleSpeedList(possibleSpeedList); double score = speedProfileEvaluator.EvaluateGA(individual); scoreList[ii] = score; cumulativeScore += score; List <int> individualSpeedIndexList = new List <int>(); for (int kk = 0; kk < individual.ParameterList.Count; kk++) { individualSpeedIndexList.Add(((IntParameter)individual.ParameterList[kk]).ParameterValue); } long speedProfileIndex = ConvertToBase10(individualSpeedIndexList); OnIndividualEvaluated(individualSpeedIndexList, speedProfileIndex, 0, score, individual.Copy(), ii, iterationIndex, true); if (score >= bestScore) { // MW 20180206 if (score > bestScore) { OnNewBestIndividualFound(individualSpeedIndexList, speedProfileIndex, 0, score, individual.Copy(), ii, iterationIndex, true); } bestScore = score; bestIndividualIndex = ii; // Copy the best individual here, in case the algorithm exits due to maximum time reached. optimizedSpeedProfile = individual.Copy(); } numberOfEvaluatedIndividuals++; elapsedOptimizationTime = stopWatch.ElapsedTicks / (double)Stopwatch.Frequency; if (elapsedOptimizationTime >= optimizationTime | numberOfEvaluatedIndividuals >= optimizationSettings.NumberOfGenerations * optimizationSettings.PopulationSize) { running = false; OnStopped(); break; } if (!running) { break; } } // Make new generation: OptimizableStructure bestIndividual = population[bestIndividualIndex].Copy(); List <OptimizableStructure> oldPopulation = new List <OptimizableStructure>(); foreach (OptimizableStructure individual in population) { OptimizableStructure copiedIndividual = individual.Copy(); oldPopulation.Add(copiedIndividual); } population = new List <OptimizableStructure>(); int counter = 0; while (counter < oldPopulation.Count) { int firstIndex = TournamentSelection.Select(randomNumberGenerator, scoreList, OptimizationObjective.Maximization, tournamentSize, tournamentSelectionParameter); int secondIndex = TournamentSelection.Select(randomNumberGenerator, scoreList, OptimizationObjective.Maximization, tournamentSize, tournamentSelectionParameter); double r = randomNumberGenerator.NextDouble(); OptimizableStructure parent1 = oldPopulation[firstIndex]; OptimizableStructure parent2 = oldPopulation[secondIndex]; if (r < crossoverProbability) { List <OptimizableStructure> newIndividualsList = null; newIndividualsList = Crossover.ExecuteSinglePoint(parent1, parent2, unitLength, randomNumberGenerator); population.Add(newIndividualsList[0]); population.Add(newIndividualsList[1]); } else { population.Add(parent1); population.Add(parent2); } counter += 2; } if (population.Count > oldPopulation.Count) { population.RemoveAt(population.Count - 1); } // If the population size is odd.. for (int jj = 0; jj < population.Count; jj++) { OptimizableStructure individual = population[jj]; OptimizableStructure mutatedIndividual = (OptimizableStructure)Modification.Execute(individual, mutationRate, creepMutationRate, randomNumberGenerator); population[jj] = mutatedIndividual; } if (useElitism) { population[0] = bestIndividual; } double bestFitness = bestScore; double averageFitness = scoreList.Average(); List <int> bestIndividualSpeedIndexList = new List <int>(); for (int kk = 0; kk < bestIndividual.ParameterList.Count; kk++) { bestIndividualSpeedIndexList.Add(((IntParameter)bestIndividual.ParameterList[kk]).ParameterValue); } long bestSpeedProfileIndex = ConvertToBase10(bestIndividualSpeedIndexList); List <int> populationAverageIndividual = new List <int>(); OnGenerationEvaluated(bestFitness, averageFitness, iterationIndex, bestIndividualIndex, numberOfEvaluatedIndividuals, bestIndividualSpeedIndexList, bestSpeedProfileIndex); iterationIndex++; if (numberOfEvaluatedIndividuals >= optimizationSettings.NumberOfGenerations * optimizationSettings.PopulationSize) { running = false; OnStopped(); break; } } OnStopped(); } OnStopped(); }