public static PathGenetic BestSolution(List <PathGenetic> population) { PathGenetic currentBestPath = population[0]; for (int i = 1; i < population.Count; i++) { if (population[i].cost < currentBestPath.cost) { currentBestPath = population[i]; } } return(currentBestPath); }
public static PathGenetic GenerateChildPolish(Cplex cplex, Instance instance, INumVar[] x, PathGenetic mother, PathGenetic father) { //Percorso di codifica del figlio int[] path = new int[mother.path.Length]; //Fisso le variabili in soluzione in entrambi i genitori for (int i = 0; i < mother.path.Length; i++) { if (mother.path[i] == 1 && father.path[i] == 1) { x[i].LB = 1; } else if (mother.path[i] == 0 && father.path[i] == 0) { x[i].UB = 0; } } //Risolvo il modello cplex.Solve(); //Ottengo la soluzione ottima calcolata da Cplex double[] pathChild = cplex.GetValues(x); //Traduco il vettore restituitomi in un vettore di interi for (int i = 0; i < mother.path.Length; i++) { if (pathChild[i] >= 0.5) { path[i] = 1; } else { path[i] = 0; } } //Creiamo il figlio PathGenetic child = new PathGenetic(path, cplex.GetObjValue()); //Fisso il LB di tutte le variabili a for (int i = 0; i < mother.path.Length; i++) { x[i].LB = 0; x[i].UB = 1; } return(child); }
static void GeneticAlgorithm(Instance instance, Process process, Random rnd, Stopwatch clock, int sizePopulation, string choice) { PathGenetic incumbentSol = new PathGenetic(); PathGenetic currentBestPath = null; List <PathGenetic> OriginallyPopulated = new List <PathGenetic>(); List <PathGenetic> ChildPoulation = new List <PathGenetic>(); List <int>[] listArray = Utility.BuildSLComplete(instance); //Generate the first population for (int i = 0; i < sizePopulation; i++) { OriginallyPopulated.Add(Utility.NearestNeightborGenetic(instance, rnd, true, listArray)); } do { //Generate the child for (int i = 0; i < sizePopulation; i++) { if (i % 2 != 0) { ChildPoulation.Add(Utility.GenerateChild(instance, rnd, OriginallyPopulated[i], OriginallyPopulated[i - 1], listArray)); } } OriginallyPopulated = Utility.NextPopulation(instance, sizePopulation, OriginallyPopulated, ChildPoulation); //currentBestPath contains the best path of the current population currentBestPath = Utility.BestSolution(OriginallyPopulated); if (currentBestPath.cost < incumbentSol.cost) { incumbentSol = (PathGenetic)currentBestPath.Clone(); Utility.PrintGeneticSolution(instance, process, incumbentSol); } // We empty the list that contain the child ChildPoulation.RemoveRange(0, ChildPoulation.Count); } while (clock.ElapsedMilliseconds / 1000.0 < instance.TimeLimit); Console.WriteLine("Best distance found within the timelit is: " + incumbentSol.cost); }
public static PathGenetic GenerateChild(Instance instance, Random rnd, PathGenetic mother, PathGenetic father, List <int>[] listArray) { PathGenetic child; int[] pathChild = new int[instance.NNodes]; //This variable defines the point of breaking the path of the father and that of the mother int crossover = (rnd.Next(0, instance.NNodes)); for (int i = 0; i < instance.NNodes; i++) { if (i > crossover) { pathChild[i] = mother.path[i]; } else { pathChild[i] = father.path[i]; } } //With a probability of 0.01 we make a mutation if (rnd.Next(0, 101) == 100) { Mutation(instance, rnd, pathChild); } //The repair method ensures that the child is a permissible path child = Repair(instance, pathChild, listArray); if (ProbabilityTwoOpt(instance, rnd) == 1) { child.path = InterfaceForTwoOpt(child.path); TSP.TwoOpt(instance, child); child.path = Reverse(child.path); } return(child); }
public static void PrintGeneticSolution(Instance instance, Process process, PathGenetic Heuristic) { StreamWriter file = new StreamWriter(instance.InputFile + ".dat", false); for (int i = 0; i + 1 < instance.NNodes; i++) { int vertice1 = Heuristic.path[i]; int vertice2 = Heuristic.path[i + 1]; file.WriteLine(instance.Coord[vertice1].X + " " + instance.Coord[vertice1].Y + " " + (vertice1 + 1)); file.WriteLine(instance.Coord[vertice2].X + " " + instance.Coord[vertice2].Y + " " + (vertice2 + 1) + "\nEdges"); } file.WriteLine(instance.Coord[Heuristic.path[0]].X + " " + instance.Coord[Heuristic.path[0]].Y + " " + (Heuristic.path[0] + 1)); file.WriteLine(instance.Coord[Heuristic.path[instance.NNodes - 1]].X + " " + instance.Coord[Heuristic.path[instance.NNodes - 1]].Y + " " + (Heuristic.path[instance.NNodes - 1] + 1) + "\nEdges"); //GNUPlot input file needs to be closed file.Close(); //Accessing GNUPlot to read the file if (Program.VERBOSE >= -1) { PrintGNUPlot(process, instance.InputFile, 1, Heuristic.cost, -1); } }
static void Polishing(Cplex cplex, Instance instance, Process process, Random rnd, int sizePopulation, Stopwatch clock) { //Definisco l' oggetto che codifica la soluzione che rappresenta l' incumbent(miglio soluzione in assoluto fra tutte le generazioni) PathGenetic incumbentSol = new PathGenetic(); //Miglior soluzione all' interno di una generazione PathGenetic currentBestPath = null; //Popolazione padre corrente List <PathGenetic> OriginallyPopulated = new List <PathGenetic>(); //Popolazione figlia List <PathGenetic> ChildPoulation = new List <PathGenetic>(); List <int>[] listArray = Utility.BuildSLComplete(instance); //Costruisco il modello INumVar[] x = Utility.BuildModel(cplex, instance, -1); //Installo la lazy cplex.Use(new TSPLazyConsCallback(cplex, x, instance, process, false)); //Ripristino il numero di thread al numero di core logici cplex.SetParam(Cplex.Param.Threads, cplex.GetNumCores()); //Setto un EpGap di 0.2(molto alto) in modo da produrre nel più breve tempo possibile una soluzione cplex.SetParam(Cplex.DoubleParam.EpGap, 0.1); for (int i = 0; i < sizePopulation; i++) { OriginallyPopulated.Add(Utility.NearestNeightborGeneticPolish(instance, rnd, listArray)); } do { for (int i = 0; i < sizePopulation; i++) { if ((i != 0) && (i % 2 != 0)) { ChildPoulation.Add(Utility.GenerateChildPolish(cplex, instance, x, OriginallyPopulated[i], OriginallyPopulated[i - 1])); } } OriginallyPopulated = Utility.NextPopulation(instance, sizePopulation, OriginallyPopulated, ChildPoulation); //Miglio soluzione della popolazione attualE currentBestPath = Utility.BestSolution(OriginallyPopulated); if (currentBestPath.cost < incumbentSol.cost) { //Aggiorno la soluzione incumbent incumbentSol = (PathGenetic)currentBestPath.Clone(); //Print the new incombent solution StreamWriter file = new StreamWriter(instance.InputFile + ".dat", false); for (int i = 0; i < instance.NNodes; i++) { for (int j = i + 1; j < instance.NNodes; j++) { int pos = Utility.xPos(i, j, instance.NNodes); if (incumbentSol.path[pos] >= 0.5) { file.WriteLine(instance.Coord[i].X + " " + instance.Coord[i].Y + " " + (i + 1)); file.WriteLine(instance.Coord[j].X + " " + instance.Coord[j].Y + " " + (j + 1) + "\n"); } } } file.Close(); Utility.PrintGNUPlot(process, instance.InputFile, 1, incumbentSol.cost, -1); } ChildPoulation.RemoveRange(0, ChildPoulation.Count); } while (clock.ElapsedMilliseconds / 1000.0 < instance.TimeLimit); Console.WriteLine("Best distance found within the timelit is: " + incumbentSol.cost); }