public TSPOrganism crossover(TSPOrganism parent) { int start = 0; int end = 0; int diff = 0; // Define a range while (true) { // Obtain two indices to swap start = rnd.Next(0, NUM_CITIES); end = rnd.Next(0, NUM_CITIES); if (start == end) { continue; } // How much did we chop off? diff = Math.Abs(start - end); double percentage = (double)diff / route.Count; if (percentage <= MAX_CROSSOVER_PERCENTAGE) { break; } } // Force the start to be the lower number, and end to be the higher // this is mainly just for sanity's sake if (start > end) { int temp = start; start = end; end = temp; } // Now for the fun bit! ArrayList childRoute = new ArrayList(); childRoute.AddRange(route.GetRange(start, diff)); // Add the subsequence to the child's list // Now, loop through the second parent, starting after 'end' // If the element is not contained in the child route, we add it (to the end) for (int i = end + 1; i < NUM_CITIES; i++) { City currentCity = parent.getRoute()[i] as City; if (childRoute.Contains(currentCity)) { continue; } childRoute.Add(currentCity); } // Then we have to add the cities before 'end' that we may have missed ArrayList prefix = new ArrayList(); for (int i = 0; i < end + 1; i++) { City currentCity = parent.getRoute()[i] as City; if (childRoute.Contains(currentCity)) { continue; } //childRoute.Insert(0, currentCity); prefix.Add(currentCity); } // Add the pre-pended portion childRoute.InsertRange(0, prefix); return(new TSPOrganism(childRoute)); }
public string[] fancySolveProblem() { string[] results = new string[3]; /* Algorithm Parameters */ int populationSize = 100; long maxGenerations = 5000; long stagnationCutoff = 300; bool shouldTimeout = true; // These are some dealios that you can customize // Apparently these are pretty statndard values // But really I know nothing about the theory behind this double percentMated = 0.6; double percentMutated = 0.3; double percentRandom = 0.1; // Percent of the initial population that should be a clone of the greedy solution double greedyProportion = 0.25; // Set up our Organism class TSPOrganism.Cities = Cities; TSPOrganism.NUM_CITIES = Cities.Length; TSPOrganism.isOnlyValidRoutes = true; // Toggle if infinity cost routes are allowed //TSPOrganism.setSeed(_seed); // Used for debugging, mainly // Create the initial list MotherNature motherNature = new MotherNature(populationSize, percentMated, percentMutated, percentRandom); Stopwatch timer = new Stopwatch(); timer.Start(); // Start by Obtaining the Greedy Solution greedySolveProblem(); // Convert the results to a TSPOrganism TSPOrganism greedySeed = new TSPOrganism(bssf.Route); List <TSPOrganism> population = motherNature.generatePopulationFromOrganism(greedySeed, greedyProportion); // Define some counters or whatever long numGenerations = 0; long gensSinceLastBest = 0; int numNewBest = 0; //TSPOrganism bestSoFar = TSPOrganism.newOrganism(); // Start with a random best TSPOrganism bestSoFar = greedySeed; // Here's acutal interesting code while (true) { if (timer.ElapsedMilliseconds / 1000 > TIME_LIMIT) { break; } numGenerations++; population = population.OrderBy(a => a.getFitness()).ToList(); List <TSPOrganism> fittestParents = population.GetRange(0, populationSize / 2); // New best? if (fittestParents[0].getFitness() < bestSoFar.getFitness()) { bestSoFar = fittestParents[0]; gensSinceLastBest = 0; numNewBest++; // Update our ratios // Start to favor mutation more and more //percentMutated += ((1 - percentMutated) / ((0.02449 * Cities.Length) + 4.122)); percentMutated += ((1 - percentMutated) / (1 + Math.Log(Cities.Length))); // Then update our percent mated percentMated = 1 - (percentMutated + percentRandom); motherNature.setPercentMutated(percentMutated); motherNature.setPercentMated(percentMated); } else { gensSinceLastBest++; } List <TSPOrganism> offspring = motherNature.createOffspring(fittestParents); // Find the fittest Offspring offspring = offspring.OrderBy(a => a.getFitness()).ToList(); List <TSPOrganism> fittestOffspring = offspring.GetRange(0, populationSize / 2); // Merge best parents and offspring to create the new population population = new List <TSPOrganism>(); population.AddRange(fittestParents); population.AddRange(fittestOffspring); if (shouldTimeout) { continue; } // Otherwise, test our break conditions if (gensSinceLastBest >= stagnationCutoff) { break; } if (numGenerations >= maxGenerations) { break; } } timer.Stop(); // Convert our solution bssf = new TSPSolution(bestSoFar.getRoute()); results[COST] = Convert.ToString(bestSoFar.getFitness()); results[TIME] = timer.Elapsed.ToString(); results[COUNT] = Convert.ToString(numNewBest); return(results); }