/// <summary> /// Breeds two parent path individuals to create an offspring path individual. /// </summary> /// <param name="firstParent">The first path individual to breed with second path individual .</param> /// <param name="secondParent">The second path individual to breed with first path individual.</param> /// <returns>Offspring path individual of specified parents.</returns> public static PathGraph Crossover(PathGraph firstParent, PathGraph secondParent) { int CircuitLength = Input.Size + 1; // Create new child path PathGraph ChildPath = new PathGraph(CircuitLength, Input); ChildPath[0] = Input[0]; ChildPath[CircuitLength - 1] = Input[0]; // Get random start and end indices positions for firstParent int StartPos = ThreadSafeRandom.CurrentThreadsRandom.Next(1, CircuitLength - 1); int EndPos = ThreadSafeRandom.CurrentThreadsRandom.Next(1, CircuitLength - 1) + ThreadSafeRandom.CurrentThreadsRandom.Next(1, CircuitLength - 1); // Loop and add the sub tour from firstParent to our child for (int i = 1; i < CircuitLength - 1; ++i) { // If our start position is less than the end position if (StartPos < EndPos && i > StartPos && i < EndPos) { ChildPath[i] = firstParent[i]; } // If our start position is larger else if (StartPos > EndPos) { //if (!(i < StartPos && i > EndPos)) if (i >= StartPos || i <= EndPos) { ChildPath[i] = firstParent[i]; } } } // Loop through parent2's path for (int i = 1; i < CircuitLength - 1; ++i) { // If child doesn't have the city add it if (!ChildPath.Contains(secondParent[i])) { // Loop to find a spare position in the child's tour for (int j = 1; j < CircuitLength - 1; ++j) { // Spare position found, add city if (ChildPath[j] == null) { ChildPath[j] = secondParent[i]; break; } } } } return(ChildPath); }
private static PathGraph DefaultCrossover(PathGraph firstParent, PathGraph secondParent) { int CircuitLength = Input.Size + 1; // Create new child path PathGraph ChildPath = new PathGraph(CircuitLength, Input); ChildPath[0] = Input[0]; ChildPath[CircuitLength - 1] = Input[0]; // Get random start and end indices positions for firstParent int StartPos = ThreadSafeRandom.CurrentThreadsRandom.Next(1, CircuitLength - 1); int EndPos = ThreadSafeRandom.CurrentThreadsRandom.Next(1, CircuitLength - 1) + ThreadSafeRandom.CurrentThreadsRandom.Next(1, CircuitLength - 1); // Iterate firstParent to add subset to the child for (int i = 1; i < CircuitLength - 1; ++i) { if (StartPos < EndPos && i > StartPos && i < EndPos) { ChildPath[i] = firstParent[i]; } else if (StartPos > EndPos) { if (i >= StartPos || i <= EndPos) { ChildPath[i] = firstParent[i]; } } } // Iterate secondParent's vertices to fill the remaining vertices for (int i = 1; i < CircuitLength - 1; ++i) { // Add vertex if child does not contain it already if (!ChildPath.Contains(secondParent[i])) { // Find an empty position in child for (int j = 1; j < CircuitLength - 1; ++j) { // Add vertex to empty spot if (ChildPath[j] == null) { ChildPath[j] = secondParent[i]; break; } } } } return(ChildPath); }