private void solveVRP(World world) { // Spawns objects that visualize the points of interest spawnPointOfInterestObjects(); // Initialize visibility graph List <Vector2> addPoints = new List <Vector2> (world.pointsOfInterest); foreach (var point in world.startPositions) { addPoints.Add(point); } foreach (var point in world.goalPositions) { addPoints.Add(point); } VisibilityGraph.initVisibilityGraph(world, addPoints); // Execute FloydWarshall algorithm on visibility graph to get shortest paths FloydWarshall fw = new FloydWarshall(world.visibilityGraph); float[,] floydWarshallDistMatrix = fw.findShortestPaths(); // Get number of obstacle vertices obstacleVertCount = world.graphVertices.Count - world.pointsOfInterest.Length - agents.Length * 2; // Remove obstacle vertex rows and columns from the distance matrix as GA does not work with them to find a solution float[,] distanceMatrix = getSubArray(floydWarshallDistMatrix, obstacleVertCount); // Use the genetic algorithm for the Vehicle Routing Problem GeneticAlgorithm ga = new GeneticAlgorithm(populationSize, populationSize, world.pointsOfInterest.Length, agents.Length, distanceMatrix, 0.02f, geneticAlgorithmIterations, false, 0.04f, 0.01f, true); ga.generationalGeneticAlgorithm(); List <int> solution = ga.getFittestIndividual(); solution = GeneticAlgorithmHelper.includeSolutionGoals(solution, world.pointsOfInterest.Length, agents.Length); // Reconstruct path including intermediate obstacle vertex nodes for (int i = 0; i < solution.Count; i++) { solution [i] += obstacleVertCount; } List <int> reconstructedSolution = reconstructShortestPath(solution, fw, agents.Length); // Visualize the reconstructed path (solution including intermediate nodes) Visualizer.visualizeVRPsolution(world.graphVertices, reconstructedSolution, agents.Length, obstacleVertCount); solutionList = GeneticAlgorithmHelper.splitSolution(solution, world.graphVertices.Count, agents.Length); for (int i = 0; i < solutionList.Count; i++) { solutionList[i] = reconstructShortestPath(solutionList [i], fw, agents.Length); } solutionCoordinates = getSolutionCoordinates(solutionList); }
public void generationalGeneticAlgorithm() { // Initialize population initializePopulation(); // Get parent selection probabilities - They do not depend on fitness values but only on population size and hence can be precomputed double[] selectionProbabilities = calculateRankingProbabilities(population.Length, "Linear"); System.Array.Reverse(selectionProbabilities); // If overselection is true, split selection probabilities in two double[] fitSelectionProbabilities = null; //user if overselection is true double[] unfitSelectionProbabilities = null; //user if overselection is true int seperatingIdx = -1; //user if overselection is true if (overselection) { seperatingIdx = M - (int)(this.M * this.fitGroupPerc); fitSelectionProbabilities = calculateRankingProbabilities((int)(this.M * this.fitGroupPerc), "Linear"); unfitSelectionProbabilities = calculateRankingProbabilities(seperatingIdx, "Linear"); } float bestFitness = float.MaxValue; float prevBestFitness = float.MaxValue; int count = 0; for (int i = 0; i < this.maxIterations; i++) { // Calculate fitness for each individual float[] populationFitness = calculateFitness(this.population); int[] populationIndices = populationFitness.getIndexList(); // Sort fitness of each individual along with their indices System.Array.Sort(populationFitness, populationIndices); prevBestFitness = bestFitness; bestFitness = populationFitness [0]; // check for convergence if (GeneticAlgorithmHelper.abs(populationFitness [0] - prevBestFitness) < this.eps) { count++; } //if(count >= this.maxIterations * 0.05) //break; // Sample parents from population int[] matingPool; if (!overselection) { //Run stochastic universal sampling algorithm to get mating pool (selected parents) matingPool = stochasticUniversalSampling(selectionProbabilities, populationIndices, this.lambda); } else { // If overselection is activated int[] fitPopulationIndices = new int[(int)(this.M * this.fitGroupPerc)]; int[] unfitPopulationIndices = new int[this.M - (int)(this.M * this.fitGroupPerc)]; // Split population in fit and unfit where fit is <fitGroupPerc>% of the initial population System.Array.Copy(populationIndices, 0, unfitPopulationIndices, 0, seperatingIdx); System.Array.Copy(populationIndices, seperatingIdx, fitPopulationIndices, 0, (int)(this.M * this.fitGroupPerc)); // Select 80% parents from fit group and 20% from unfit group int[] fitMatingPool = stochasticUniversalSampling(fitSelectionProbabilities, fitPopulationIndices, (int)(0.8f * this.M)); int[] unfitMatingPool = stochasticUniversalSampling(unfitSelectionProbabilities, unfitPopulationIndices, (int)(0.2f * this.M)); // Merge fit and unfit parents selected in the same mating pool matingPool = GeneticAlgorithmHelper.mergeArrays(fitMatingPool, unfitMatingPool); } // Mate the parents selected to get offsprings List <int>[] offsprings = mateParents(matingPool); float[] offspringsFitness = calculateFitness(offsprings); // Pick the best from the population and the new offsprings as the new population List <int>[] sortedPopulation = getOrderedPopulation(this.population, populationIndices); List <int>[] intermediatePool = GeneticAlgorithmHelper.mergeArrays(sortedPopulation, offsprings); float[] intermediateFitness = GeneticAlgorithmHelper.mergeArrays(populationFitness, offspringsFitness); int[] intermediatePoolIndices = intermediatePool.getIndexList(); System.Array.Sort(intermediateFitness, intermediatePoolIndices); System.Array.Copy(getOrderedPopulation(intermediatePool, intermediatePoolIndices), 0, this.population, 0, this.population.Length); } }