private static bool TestConnectionValid(TSPTour tour, List <TSPNode> nodes, int[] usage, int node1, int node2) { if ((node1 == node2) || (usage[node1] == 2) || (usage[node2] == 2)) { return(false); } if ((usage[node1] == 0) || (usage[node2] == 0)) { return(true); } for (int direction = 0; direction < 2; direction++) { int lastNode = node1; int currentNode; if (direction == 0) { currentNode = tour[node1].Conn1; } else { currentNode = tour[node1].Conn2; } int tourLength = 0; while ((currentNode != -1) && (currentNode != node2) && (tourLength < nodes.Count - 2)) { tourLength++; if (lastNode != tour[currentNode].Conn1) { currentNode = tour[lastNode = currentNode].Conn1; } else { currentNode = tour[lastNode = currentNode].Conn2; } } if (tourLength >= nodes.Count - 2) { return(true); } if (currentNode == node2) { return(false); } } return(true); }
private static int FindNextCity(TSPTour parent, TSPTour child, List <TSPNode> nodes, int[] usage, int node) { if (TestConnectionValid(child, nodes, usage, node, parent[node].Conn1)) { return(parent[node].Conn1); } else if (TestConnectionValid(child, nodes, usage, node, parent[node].Conn2)) { return(parent[node].Conn2); } else { return(-1); } }
private static void JoinCities(TSPTour tour, int[] cityUsage, int node1, int node2) { if (tour[node1].Conn1 == -1) { tour[node1].Conn1 = node2; } else { tour[node1].Conn2 = node2; } if (tour[node2].Conn1 == -1) { tour[node2].Conn1 = node1; } else { tour[node2].Conn2 = node1; } cityUsage[node1]++; cityUsage[node2]++; }
public static TSPTour Crossover(TSPTour parent1, TSPTour parent2, List <TSPNode> nodes, Random rand) { TSPTour child = new TSPTour(nodes.Count); int[] cityUsage = new int[nodes.Count]; int city; int nextCity; for (city = 0; city < nodes.Count; city++) { cityUsage[city] = 0; } for (city = 0; city < nodes.Count; city++) { if (cityUsage[city] < 2) { if (parent1[city].Conn1 == parent2[city].Conn1) { nextCity = parent1[city].Conn1; if (TestConnectionValid(child, nodes, cityUsage, city, nextCity)) { JoinCities(child, cityUsage, city, nextCity); } } if (parent1[city].Conn2 == parent2[city].Conn2) { nextCity = parent1[city].Conn2; if (TestConnectionValid(child, nodes, cityUsage, city, nextCity)) { JoinCities(child, cityUsage, city, nextCity); } } if (parent1[city].Conn1 == parent2[city].Conn2) { nextCity = parent1[city].Conn1; if (TestConnectionValid(child, nodes, cityUsage, city, nextCity)) { JoinCities(child, cityUsage, city, nextCity); } } if (parent1[city].Conn2 == parent2[city].Conn1) { nextCity = parent1[city].Conn2; if (TestConnectionValid(child, nodes, cityUsage, city, nextCity)) { JoinCities(child, cityUsage, city, nextCity); } } } } for (city = 0; city < nodes.Count; city++) { if (cityUsage[city] < 2) { if (city % 2 == 1) { nextCity = FindNextCity(parent1, child, nodes, cityUsage, city); if (nextCity == -1) { nextCity = FindNextCity(parent2, child, nodes, cityUsage, city); } } else { nextCity = FindNextCity(parent2, child, nodes, cityUsage, city); if (nextCity == -1) { nextCity = FindNextCity(parent1, child, nodes, cityUsage, city); } } if (nextCity != -1) { JoinCities(child, cityUsage, city, nextCity); if (cityUsage[city] == 1) { if (city % 2 != 1) { nextCity = FindNextCity(parent1, child, nodes, cityUsage, city); if (nextCity == -1) { nextCity = FindNextCity(parent2, child, nodes, cityUsage, city); } } else { nextCity = FindNextCity(parent2, child, nodes, cityUsage, city); if (nextCity == -1) { nextCity = FindNextCity(parent1, child, nodes, cityUsage, city); } } if (nextCity != -1) { JoinCities(child, cityUsage, city, nextCity); } } } } } for (city = 0; city < nodes.Count; city++) { while (cityUsage[city] < 2) { do { nextCity = rand.Next(nodes.Count); } while (!TestConnectionValid(child, nodes, cityUsage, city, nextCity)); JoinCities(child, cityUsage, city, nextCity); } } return(child); }
private bool MakeChildren(int groupSize, int mutation) { int[] tourGroup = new int[groupSize]; int tourCount, i, topTour, childPosition, tempTour; for (tourCount = 0; tourCount < groupSize; tourGroup[tourCount++] = rand.Next(population.Count)) { } for (tourCount = 0; tourCount < groupSize - 1; tourCount++) { topTour = tourCount; for (i = topTour + 1; i < groupSize; i++) { if (population[tourGroup[i]].Fitness < population[tourGroup[topTour]].Fitness) { topTour = i; } } if (topTour != tourCount) { tempTour = tourGroup[tourCount]; tourGroup[tourCount] = tourGroup[topTour]; tourGroup[topTour] = tempTour; } } bool foundNewBestTour = false; childPosition = tourGroup[groupSize - 1]; population[childPosition] = TSPTour.Crossover(population[tourGroup[0]], population[tourGroup[1]], nodes, rand); if (rand.Next(100) < mutation) { population[childPosition].Mutate(rand); } population[childPosition].DetermineFitness(nodes); if (population[childPosition].Fitness < population.BestTour.Fitness) { population.BestTour = population[childPosition]; foundNewBestTour = true; } childPosition = tourGroup[groupSize - 2]; population[childPosition] = TSPTour.Crossover(population[tourGroup[1]], population[tourGroup[0]], nodes, rand); if (rand.Next(100) < mutation) { population[childPosition].Mutate(rand); } population[childPosition].DetermineFitness(nodes); if (population[childPosition].Fitness < population.BestTour.Fitness) { population.BestTour = population[childPosition]; foundNewBestTour = true; } return(foundNewBestTour); }