예제 #1
0
        /// <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);
        }