public double EvaluateGA(OptimizableStructure individual) { List <double> speedSequence = DecodeSpeedProfile(individual); int numberOfLineSegments = individual.ParameterList.Count - 1; averageSpeed = ComnputeAverageSpeed(speedSequence, numberOfLineSegments); Initialize(); singleRunSimulation.Start(); loggedData = singleRunSimulation.Log; fuelConsumption = loggedData.LogItemList.Find(i => i.Name == "FuelConsumption").ValueList.Last(); List <double> vehicleSpeedList = new List <double>(); vehicleSpeedList = loggedData.LogItemList.Find(i => i.Name == "Speed").ValueList; topSpeed = vehicleSpeedList.Max(); vehicleSpeedList.RemoveAt(0); minSpeed = vehicleSpeedList.Min(); vehicleSpeedList.Insert(0, 0); if (Math.Abs(averageSpeed - desiredAverageSpeed) < 1 / 3.6) { return(1 / fuelConsumption); } else { return(0); } }
private void OnNewBestIndividualFound(List <int> individualSpeedIndexList, long speedProfileIndex, double averageSpeed, double fitness, OptimizableStructure individual, int individualIndexInGeneration, int generationIndex, bool isIndividualFeasible) { if (NewBestIndividualFound != null) { EvaluatedIndividualEventArgs e = new EvaluatedIndividualEventArgs(individualSpeedIndexList, speedProfileIndex, averageSpeed, fitness, individual, individualIndexInGeneration, generationIndex, isIndividualFeasible); EventHandler <EvaluatedIndividualEventArgs> handler = NewBestIndividualFound; handler(this, e); } }
public EvaluatedIndividualEventArgs(List <int> averageIndividualSpeedIndex, long speedProfileIndex, double averageSpeed, double fitness, OptimizableStructure individual, int individualIndexInGeneration, int generationIndex, bool isIndividualFeasible) { this.averageIndividualSpeedIndex = averageIndividualSpeedIndex; this.fitness = fitness; this.averageSpeed = averageSpeed; this.speedProfileIndex = speedProfileIndex; this.individual = individual; this.individualIndexInGeneration = individualIndexInGeneration; this.generationIndex = generationIndex; this.isIndividualFeasible = isIndividualFeasible; }
public List <double> DecodeSpeedProfile(OptimizableStructure individual) { //this.speedProfileIndividual = individual; int numberOfLineSegments = individual.ParameterList.Count - 1; List <double> speedSequence = new List <double>(); for (int i = 0; i < numberOfLineSegments + 1; i++) { int speedIndex = ((IntParameter)individual.ParameterList[i]).ParameterValue; speedSequence.Add(possibleSpeedList[speedIndex]); } speedProfile = new PiecewiseLinearSpeedProfile(metricPath, numberOfLineSegments); speedProfile.Generate(metricPath, speedSequence); return(speedSequence); }
private void ShowBatchResult(int numberOfEvaluatedIndividuals, double bestScore, double averageScore, int iRun, OptimizableStructure optimizedProfile) { batchRunProgressListBox.Items.Insert(0, "Run ID: " + iRun.ToString("0") + " Number of evaluated individuals: " + numberOfEvaluatedIndividuals.ToString().PadLeft(7) + " Best fitness: " + bestScore.ToString("0.000000")); List <double> speedSequence = new List <double>(); for (int i = 0; i < optimizationSettings.NumberOfSpeedPoints + 1; i++) { int speedIndex = ((IntParameter)optimizedProfile.ParameterList[i]).ParameterValue; speedSequence.Add(speedProfileOptimizer.PossibleSpeedList[speedIndex]); } PiecewiseLinearSpeedProfile tempProfile = new PiecewiseLinearSpeedProfile(metricPath, optimizationSettings.NumberOfSpeedPoints); tempProfile.Generate(metricPath, speedSequence); PlotSpeedProfile(speedProfilePlot2DPanel, tempProfile, "Batch run"); }
private void ThreadSafeShowResult(int numberOfEvaluatedIndividuals, double bestScore, double averageScore, int iRun, OptimizableStructure optimizedProfile) { if (InvokeRequired) { Invoke(new MethodInvoker(() => ShowBatchResult(numberOfEvaluatedIndividuals, bestScore, averageScore, iRun, optimizedProfile))); } else { ShowBatchResult(numberOfEvaluatedIndividuals, bestScore, averageScore, iRun, optimizedProfile); } }
private void BatchRunLoop(int numberOfBatchRuns, PiecewiseLinearSpeedProfileOptimizationSettings optimizationSettings, OptimizationMethod optimizationMethod) { for (int iRun = 0; iRun < numberOfBatchRuns; iRun++) { speedProfileOptimizer = new PiecewiseLinearSpeedProfileOptimization(); speedProfileOptimizer.OptimizationMethod = optimizationMethod; speedProfileOptimizer.IndividualEvaluated += new EventHandler <EvaluatedIndividualEventArgs>(ThreadSafeHandleBatchRunIndividualEvaluated); speedProfileOptimizer.RunSynchronous(optimizationSettings, new Random(), optimizationSettings.OptimizationTime, metricMap, metricPath); double bestScore = speedProfileOptimizer.BestScore; int numberOfEvaluatedIndividuals = speedProfileOptimizer.NumberOfEvaluatedIndividuals; OptimizableStructure optimizedProfile = speedProfileOptimizer.OptimizedSpeedProfile.Copy(); bestIndividualsList.Add(optimizedProfile); double averageScore = speedProfileOptimizer.AverageFitness; List <double> speedSequence = new List <double>(); List <int> speedSequenceIndexList = new List <int>(); for (int i = 0; i < optimizationSettings.NumberOfSpeedPoints + 1; i++) { int speedIndex = ((IntParameter)optimizedProfile.ParameterList[i]).ParameterValue; speedSequenceIndexList.Add(speedIndex); speedSequence.Add(speedProfileOptimizer.PossibleSpeedList[speedIndex]); } long speedProfileIndex = GetIndexFromValues(speedSequenceIndexList, speedProfileOptimizer.PossibleSpeedList.Count); batchRunInfo += iRun.ToString("0").PadLeft(3) + " " + bestScore.ToString("0.000000").PadLeft(11) + " " + averageScore.ToString("0.000000").PadLeft(11) + " ["; for (int ii = 0; ii < speedSequenceIndexList.Count - 1; ii++) { batchRunInfo += speedSequenceIndexList[ii].ToString("0") + " "; } batchRunInfo += speedSequenceIndexList[speedSequenceIndexList.Count - 1].ToString("0") + "] " + speedProfileIndex.ToString("0").PadLeft(13) + " " + numberOfEvaluatedIndividuals.ToString("0").PadLeft(6) + "\r\n"; ThreadSafeShowResult(numberOfEvaluatedIndividuals, bestScore, averageScore, iRun, optimizedProfile); } if (InvokeRequired) { this.BeginInvoke(new MethodInvoker(() => startBatchRunButton.Enabled = true)); } else { startBatchRunButton.Enabled = true; } if (InvokeRequired) { this.BeginInvoke(new MethodInvoker(() => batchRunProgressListBox.Enabled = true)); } else { batchRunProgressListBox.Enabled = true; } string path = batchPath + "\\BatchRunResult" + "_" + roadFileName + ".txt"; System.IO.File.WriteAllText(path, batchRunInfo); }
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(); }
private void SetUpGeneticAlgorithm() { populationSize = optimizationSettings.PopulationSize; tournamentSelectionParameter = optimizationSettings.TournamentSelectionParameter; tournamentSize = optimizationSettings.TournamentSize; // Note: The mutation rate is set below, after the individuals have been generated crossoverProbability = optimizationSettings.CrossoverProbability; creepMutationRate = optimizationSettings.CreepMutationRate; int numberOfLineSegments = optimizationSettings.NumberOfSpeedPoints; double minimumParameterValue = optimizationSettings.MinimumSpeedValue; double maximumParameterValue = optimizationSettings.MaximumSpeedValue; double discretizationStep = optimizationSettings.SpeedIncrement; double desiredAverageSpeed = optimizationSettings.DesiredAverageSpeed; possibleSpeedList = new List <double>(); double initialSpeed = minimumParameterValue; possibleSpeedList.Add(initialSpeed); while (initialSpeed < maximumParameterValue) { initialSpeed += discretizationStep; initialSpeed = Math.Min(initialSpeed, maximumParameterValue); possibleSpeedList.Add(initialSpeed); } //returns the index of desired average speed from the possible speed list (generated above). Required for optimizaiton. int desiredAverageSpeedIndex = possibleSpeedList.FindIndex(s => s == desiredAverageSpeed); OptimizableStructure cruiseControlSpeedProfile = new OptimizableStructure(); IntParameter p0ParameterFirstIndividual = new IntParameter(); p0ParameterFirstIndividual.MaximumValue = possibleSpeedList.Count - 1; p0ParameterFirstIndividual.MinimumValue = 0; p0ParameterFirstIndividual.ParameterValue = desiredAverageSpeedIndex; cruiseControlSpeedProfile.ParameterList.Add(p0ParameterFirstIndividual); for (int jj = 0; jj < numberOfLineSegments; jj++) { IntParameter p0Parameter = new IntParameter(); p0Parameter.MaximumValue = possibleSpeedList.Count - 1; p0Parameter.MinimumValue = 0; p0Parameter.ParameterValue = desiredAverageSpeedIndex; cruiseControlSpeedProfile.ParameterList.Add(p0Parameter); } population.Add(cruiseControlSpeedProfile.Copy()); scoreList.Add(double.MinValue); for (int ii = 1; ii < populationSize; ii++) { OptimizableStructure individual = new OptimizableStructure(); IntParameter p0ParameterFirst = new IntParameter(); p0ParameterFirst.MaximumValue = possibleSpeedList.Count - 1; p0ParameterFirst.MinimumValue = 0; p0ParameterFirst.ParameterValue = desiredAverageSpeedIndex; individual.ParameterList.Add(p0ParameterFirst); for (int jj = 0; jj < numberOfLineSegments; jj++) { IntParameter p0Parameter = new IntParameter(); p0Parameter.MaximumValue = possibleSpeedList.Count - 1; p0Parameter.MinimumValue = 0; p0Parameter.ParameterValue = desiredAverageSpeedIndex; individual.ParameterList.Add(p0Parameter); } // Randomize all individuals except the first one: OptimizableStructure mutatedIndividual = (OptimizableStructure)Modification.Execute(individual, 1.0, 1.0, randomNumberGenerator); population.Add(mutatedIndividual.Copy()); scoreList.Add(double.MinValue); } mutationRate = optimizationSettings.RelativeMutationProbability / (double)population[0].ParameterList.Count; }