static void Main(string[] args) { Params.rand = new Random(); Params.GetParams(); PathModifier.getTownsHS(); Params.bestOne = new Individual(); Params.bestOne.generateFixedIndividual(1); Individual I = new Individual(); Population oldPopulation, newPopulation; Reproduction breed = new Reproduction(); oldPopulation = new Population(100); double chance; for (int i = 0; i < 100; i++) { int startingTown = Params.rand.Next(Params.numberOfTowns) + 1; I = new Individual(); I.generateFixedIndividual(startingTown); oldPopulation.Add(I); } for (int generation = 0; generation < 37; generation++) { newPopulation = new Population(100); for (int i = 0; i < 100; i++) { chance = Params.rand.NextDouble(); for (int j = i + 1; j < 100; j++) { if (chance < (1 - (i / 2 + j / 2) / 100)) { I = breed.crossOver(oldPopulation[i], oldPopulation[j]); if (!newPopulation.population.Contains(I)) { newPopulation.Add(I); } } } } oldPopulation = newPopulation; } Params.bestOne.printIndividual(); StreamWriter sw = new StreamWriter("bestPath.txt"); Params.bestOne.writeIndividualToFile(sw); sw.Close(); Console.ReadKey(); }
public void GenerateRoutes() { Parameters.rand = new Random(); PathModifier.getTownsHS(); Parameters.bestOne = new Individual(); HashSet <int> usedTowns; Individual I = new Individual(); Population oldPopulation, newPopulation; Reproduction breed = new Reproduction(); int populationSize = 40; int numberOfGenerations = 80; double chance; double totalSumProfit = 0; double totalProfit = 0; bool timeOut = false; Parameters.solutions.Clear(); usedTowns = new HashSet <int>(); for (int z = 0; z < Parameters.daysOfTrip; z++) { var watch = System.Diagnostics.Stopwatch.StartNew(); timeOut = false; Parameters.bestOne = new Individual(); oldPopulation = new Population(populationSize); for (int i = 0; i < populationSize; i++) { int startingTown = Parameters.rand.Next(Parameters.numberOfTowns) + 1; if (usedTowns.Contains(startingTown)) { i--; continue; } I = new Individual(); I.generateFixedIndividual(startingTown, usedTowns); oldPopulation.Add(I); } for (int generation = 0; generation < numberOfGenerations; generation++) { if (timeOut) { break; } newPopulation = new Population(populationSize); for (int i = 0; i < populationSize; i++) { if (timeOut) { break; } chance = Parameters.rand.NextDouble(); for (int j = i + 1; j < populationSize; j++) { if (watch.ElapsedMilliseconds > (Parameters.ExecutionTime - 10) / Parameters.daysOfTrip) { timeOut = true; break; } if (chance < (1 - (i / 2 + j / 2) / populationSize)) { if (i < oldPopulation.Count && j < oldPopulation.Count) { I = breed.crossOver(oldPopulation[i], oldPopulation[j], usedTowns); if (!newPopulation.population.Contains(I)) { newPopulation.Add(I); } } } } } oldPopulation = newPopulation; if (oldPopulation.Count > 0) { Parameters.Notify(oldPopulation[0]); } } Parameters.totalProfit += Parameters.bestOne.profit; Parameters.totalLength += Parameters.bestOne.length; if (Parameters.bestOne.path.Count == 0) { Parameters.bestOne.path.Add(0); Parameters.bestOne.path.Add(0); } Parameters.bestOne.ModifyPathToBeginWithCapital(); Parameters.solutions.Add(Parameters.bestOne); for (int k = 0; k < Parameters.bestOne.path.Count; k++) { usedTowns.Add(Parameters.bestOne.path[k]); } } Parameters.Notify(null); List <int> usedTownsCheck = new List <int>(); foreach (Individual i in Parameters.solutions) { for (int x = 0; x < i.path.Count - 1; x++) { if (i.path[x] != 0 && usedTownsCheck.Contains(i.path[x])) { Console.WriteLine(i.path[x]); } usedTownsCheck.Add(i.path[x]); } } totalSumProfit += totalProfit; Parameters.SaveToFile(); }
public Individual crossOver(Individual parent1, Individual parent2, HashSet <int> usedTowns) { Individual child = new Individual(); int point = parent1.Count > parent2.Count ? Parameters.rand.Next(parent2.Count - 2) + 2 : Parameters.rand.Next(parent1.Count - 2) + 2; child.path.Add(parent1.path[0]); child.length = 0; child.profit = 0; bool[] wasUsed = new bool[Parameters.numberOfTowns + 1]; wasUsed[parent1[0]] = true; for (int i = 1; i < point; i++) { child.path.Add(parent1.path[i]); child.profit += Parameters.profits[parent1.path[i]]; child.length += Parameters.distances[child.path[i - 1], child.path[i]]; wasUsed[parent1.path[i]] = true; } // child.path.Contains(parent2.path[i]) for (int i = point; i < parent2.path.Count - 1; i++) { if (!wasUsed[parent2[i]] && child.length + Parameters.distances[child.path[child.Count - 1], parent2.path[i]] + Parameters.distances[child.path[0], parent2.path[i]] <= 1.03 * Parameters.maxLength) { child.path.Add(parent2.path[i]); child.profit += Parameters.profits[parent2.path[i]]; child.length += Parameters.distances[child.path[child.Count - 1], child.path[child.Count - 2]]; } } child.path.Add(child.path[0]); child.length += Parameters.distances[child.path[child.Count - 2], child.path[child.Count - 1]]; child.insertCapital(); double chance = Parameters.rand.NextDouble(); if (chance > Parameters.Ptrc) { PathModifier.tryRemoveChange(child, usedTowns); } else if (chance < Parameters.Pmt) { PathModifier.tryMutate(child, usedTowns); } else if (chance > Parameters.Pmv) { child.path = PathModifier.tryMoving(child.path, usedTowns); } /* * else if (chance < 0.015) * { * PathModifier.tryExchanging(child, usedTowns); * }*/ else if (chance > 0.7 && chance < 0.72) { child.partialTwoOpt(Parameters.rand.Next(1, 5)); } else if (chance > 0.6 && chance < 0.64) { child.path = PathModifier.trySwapping(child.path, usedTowns); } else { PathModifier.tryInverting(child); } child.evaluatePath(); int similarityToParent1 = 0, similarityToParent2 = 0; double pSimilarityToParent1 = 0, pSimilarityToParent2 = 0; for (int i = 0; i < child.Count; i++) { if (i < parent1.Count) { if (child.path[i] == parent1.path[i]) { similarityToParent1++; } } if (i < parent2.Count) { if (child.path[i] == parent2.path[i]) { similarityToParent2++; } } if (i >= parent2.Count && i >= parent1.Count) { break; } } pSimilarityToParent1 = similarityToParent1 / (child.Count); pSimilarityToParent2 = similarityToParent2 / (child.Count); if (pSimilarityToParent1 >= pSimilarityToParent2) { if (parent1.fitness > child.fitness) { return(parent1); } } if (pSimilarityToParent2 >= pSimilarityToParent1) { if (parent2.fitness > child.fitness) { return(parent2); } } return(child); }