public void RunSimulation(Map map) { // Get number of clients on the map (without depo) int numberOfClients = map.Locations.Count - 1; // Get max possible value based on due date of depo // Double maxValue = Convert.ToDouble(map.Locations.First().DueDate); // Set an absurdly high maxValue Double maxValue = 8000; // Set min possible value as 1.0 - impossible to achieve, but not illegal. Double minValue = 1.0; // Generate random initial chromosomes for (int i = 0; i < PopulationSize; i++) { /*Solutions[i] = new Chromosome(numberOfClients); do { Solutions[i].MakeRandomChromosome(); Solutions[i].FitnessFunction(map); } while (Solutions[i].Fitness < 0);*/ Chromosome c = new Chromosome(numberOfClients); do { c.MakeRandomChromosome(); c.Fitness = c.FitnessFunction(map); } while (c.Fitness < 0); Solutions.Add(c); } for (int i = 0; i < Generations; i++) { Solutions = geneticRoulette.createNewGeneration(Solutions, maxValue, minValue, map); if (checkStopConditions() == true) break; //Chromosome ch = GetBestSolutionFound(); //Console.WriteLine("best " + ch.FitnessFunction(map) + ", routes " + ch.Routes.Count()); } }
private void start_btn_Click(object sender, EventArgs e) { if (dataFile == null) return; Map m = new Map(); m.Locations = dataFile.NodeList; m.NumberOfVehicles = dataFile.VehicleNumber; m.VehicleCapacity = dataFile.VehicleCapacity; output_textbox.Clear(); output_textbox.Text = String.Empty; string s = ""; GAController gac = new GAController(Int32.Parse(population_tb.Text), Int32.Parse(generations_tb.Text)); //for (int i = 0; i < gac.Generations; i++) //{ gac.RunSimulation(m); Chromosome ch = gac.GetBestSolutionFound(); ch.fixRoutes(); s += "Cost: " + ch.Fitness + ", routes number: " + ch.Routes.Count() + ", routes:" + ch.ChromosomeRouteString() + "\r\n"; //} output_textbox.Text = s; //output_textbox.Text = gac.GetSolutionText(); // remove everything from chart and redraw points chart1.Series.Clear(); chart1.Series.Add("Points"); chart1.Series["Points"].ChartType = System.Windows.Forms.DataVisualization.Charting.SeriesChartType.Point; foreach (Node n in dataFile.NodeList) { //output_textbox.Text += n.CustomerNr + "\t" + n.X + "\t" + n.Y + "\t" + n.Demand + "\t" + n.ReadyTime + "\t" + n.DueDate + "\t" + n.Service + "\r\n"; chart1.Series["Points"].Points.AddXY(n.X, n.Y); } chart1.Series["Points"].Points[0].Color = Color.Red; Chromosome c = gac.GetBestSolutionFound(); // draw routes for best chromosome found // draw all routes in given chromosome List<int[]> routes = c.Routes; for (int i = 0; i < routes.Count; i++) { int[] route = routes[i]; chart1.Series.Add("Route_"+i); for (int j = 0; j < route.Length; j++) { Node n = dataFile.NodeList[route[j]]; chart1.Series["Route_" + i].Points.AddXY(n.X, n.Y); } chart1.Series["Route_" + i].ChartType = System.Windows.Forms.DataVisualization.Charting.SeriesChartType.Line; } chart1.SaveImage(inputFilename + ".png", ChartImageFormat.Png); File.WriteAllText(inputFilename + "_solution.txt", output_textbox.Text); }
public double FitnessFunction(Map map) { double currentTime = 0; double currentVehicleLoad = 0; double maxVehicleLoad = map.VehicleCapacity; int availableVehicles = map.NumberOfVehicles; int vehiclesUsed = 1; List<int> singleRoute = new List<int>(); Node depo = map.Locations.Where(l => l.CustomerNr == 0).Single(); singleRoute.Add(depo.CustomerNr); Node previousNode = depo; Routes.Clear(); for (int i = 0; i < Nodes.Length; i++) { Node currentNode = map.Locations.Where(l => l.CustomerNr == Nodes[i]).Single(); if (vehiclesUsed > availableVehicles) { return -1; } if(currentVehicleLoad + currentNode.Demand <= maxVehicleLoad) { currentVehicleLoad += currentNode.Demand; currentTime += locationController.DistanceBetweenLocations(previousNode, currentNode); if (currentTime < currentNode.ReadyTime) { currentTime += (currentNode.ReadyTime - currentTime); } if (currentTime < currentNode.DueDate) { currentTime += currentNode.Service; if (currentTime + locationController.DistanceBetweenLocations(currentNode, depo) < depo.DueDate) { singleRoute.Add(currentNode.CustomerNr); previousNode = currentNode; } else { singleRoute[singleRoute.Count - 1] = depo.CustomerNr; i--; previousNode = depo; currentTime = 0; currentVehicleLoad = 0; vehiclesUsed++; singleRoute.Clear(); singleRoute.Add(depo.CustomerNr); } } else { singleRoute.Add(depo.CustomerNr); Routes.Add(singleRoute.ToArray()); previousNode = depo; i--; currentTime = 0; currentVehicleLoad = 0; vehiclesUsed++; singleRoute.Clear(); singleRoute.Add(depo.CustomerNr); } } else { singleRoute[singleRoute.Count - 1] = depo.CustomerNr; i--; previousNode = depo; currentTime = 0; currentVehicleLoad = 0; vehiclesUsed++; singleRoute.Clear(); singleRoute.Add(depo.CustomerNr); } if (i == Nodes.Length - 1) { if (singleRoute.Count == 2) { singleRoute.Add(depo.CustomerNr); } if (Routes.Contains(singleRoute.ToArray()) == false) { Routes.Add(singleRoute.ToArray()); } } } int visitedNodes = 0; foreach (int[] singleR in Routes) { foreach (int place in singleR) { if (place != 0){ visitedNodes++; } } } if (visitedNodes == Nodes.Length) { double totalPath = 0; foreach (int[] singleR in Routes) { for (int place = 1; place < singleR.Length; place++ ) { Node place1 = map.Locations.Where(l => l.CustomerNr == singleR[place - 1]).Single(); Node place2 = map.Locations.Where(l => l.CustomerNr == singleR[place]).Single(); totalPath += locationController.DistanceBetweenLocations(place1, place2); } } return totalPath; } else { return -1; } }
public List<Chromosome> createNewGeneration(List<Chromosome> currentGeneration, Double maxValue, Double minValue, Map map) { int populationSize = currentGeneration.Count; int nodeSize = currentGeneration.First().Nodes.Length; Double[] selectionProb = new Double[populationSize]; Double[] fitnessWithMaxMinValue = new Double[populationSize]; List<Chromosome> newGeneration = new List<Chromosome>(populationSize); List<Chromosome> finalGeneration = currentGeneration; Double maxLocalValue = getMaxLocalValue(currentGeneration, maxValue); // Using the same loop for populating the new generation list and // calculating the fitness for minimum with resprect to maxValue for (int i = 0; i < populationSize; i++) { /*newGeneration[i] = new Chromosome(nodeSize);*/ newGeneration.Add(new Chromosome(nodeSize)); fitnessWithMaxMinValue[i] = maxValue + minValue - currentGeneration[i].Fitness; } // Get the overall fitness for modified fitness' Double overallFitness = getOverallFitness(fitnessWithMaxMinValue); // Calculating probabilities for each modified fitness for (int i = 0; i < populationSize; i++) { selectionProb[i] = fitnessWithMaxMinValue[i] / overallFitness; } // Computing the distribution for each chromosome Double[] distribution = new Double[populationSize]; for (int i = 0; i < populationSize; i++) { for (int j = 0; j <= i; j++) { distribution[i] += selectionProb[j]; } } for (int i = 0; i < populationSize; i++) { // 0 - Reproduction // 1 - Crossing // 2 - Mutation int geneticOperation = 0; int randomGenetic = rand.Next(0, 100); if ((randomGenetic <= crossProb) && (i + 1 < populationSize)) { geneticOperation = 1; } else if (randomGenetic <= (crossProb + mutProb)) { geneticOperation = 2; } switch (geneticOperation) { case 0: int reproductionChromosome = selectChromosome(distribution, populationSize); newGeneration[i] = currentGeneration[reproductionChromosome]; newGeneration[i].Fitness = newGeneration[i].FitnessFunction(map); break; case 1: int parent1 = selectChromosome(distribution, populationSize); int parent2 = selectChromosome(distribution, populationSize); while (parent1 == parent2) { parent2 = selectChromosome(distribution, populationSize); } int startingIndex = rand.Next(nodeSize); int endingIndex = rand.Next(startingIndex, nodeSize); newGeneration[i].CrossChromosomeWithParents(currentGeneration[parent1], currentGeneration[parent2], startingIndex, endingIndex); newGeneration[i].Fitness = newGeneration[i].FitnessFunction(map); newGeneration[i + 1].CrossChromosomeWithParents(currentGeneration[parent2], currentGeneration[parent1], startingIndex, endingIndex); newGeneration[i + 1].Fitness = newGeneration[i + 1].FitnessFunction(map); i++; break; case 2: int mutationChromosome = selectChromosome(distribution, populationSize); newGeneration[i] = currentGeneration[mutationChromosome]; newGeneration[i].MutateChromosome(); newGeneration[i].Fitness = newGeneration[i].FitnessFunction(map); break; } } // Make random chromosomes until there are no more failing solutions for (int i = 0; i < populationSize; i++) { if (newGeneration[i].Fitness <= 0) continue; int worstChromosomeIndex = getIndexOfWorstChromosome(finalGeneration); if (newGeneration[i].Fitness < finalGeneration[worstChromosomeIndex].Fitness) { finalGeneration[worstChromosomeIndex] = newGeneration[i]; } } return finalGeneration; }