Beispiel #1
0
        /// <summary>
        /// Draw just the list of cities.
        /// </summary>
        /// <param name="cityList">The list of cities to draw.</param>
        private void DrawCityList(Cities cityList)
        {
            Image    cityImage = new Bitmap(tourDiagram.Width, tourDiagram.Height);
            Graphics graphics  = Graphics.FromImage(cityImage);

            if (pic_d)
            {
                graphics.DrawImage(pic, ulCorner);
            }
            foreach (City city in cityList)
            {
                // Draw a circle for the city.
                graphics.DrawEllipse(Pens.Red, city.Location.X - 2, city.Location.Y - 2, 5, 5);
            }

            this.tourDiagram.Image = cityImage;

            updateCityCount();
        }
        /// <summary>
        /// Draw just the list of cities.
        /// </summary>
        /// <param name="cityList">The list of cities to draw.</param>
        private void DrawCityList(Cities cityList)
        {
            Image    cityImage = new Bitmap(tourDiagram.Width, tourDiagram.Height);
            Graphics graphics  = Graphics.FromImage(cityImage);

            int City_num = 1;

            foreach (City city in cityList)
            {
                // Draw a circle for the city.

                graphics.DrawString(City_num.ToString(), drawFont, drawBrush, city.Location.X + 3, city.Location.Y + 3);
                graphics.DrawEllipse(Pens.Black, city.Location.X - 2, city.Location.Y - 2, 5, 5);
                City_num += 1;
            }

            this.tourDiagram.Image = cityImage;

            updateCityCount();
        }
Beispiel #3
0
        /// <summary>
        /// Determine  fitness
        /// </summary>

        public void DetermineFitness(Cities cities)
        {
            Fitness = 0;

            int lastCity = 0;
            int nextCity = this[0].Connection1;

            foreach (Link link in this)
            {
                Fitness += cities[lastCity].Distances[nextCity];

                if (lastCity != this[nextCity].Connection1)
                {
                    lastCity = nextCity;
                    nextCity = this[nextCity].Connection1;
                }
                else
                {
                    lastCity = nextCity;
                    nextCity = this[nextCity].Connection2;
                }
            }
        }
Beispiel #4
0
        /// <summary>
        /// Perform the crossover operation on 2 parent tours to create a new child tour.
        /// This function should be called twice to make the 2 children.
        /// In the second call, the parent parameters should be swapped.
        /// </summary>
        /// <param name="parent1">The first parent tour.</param>
        /// <param name="parent2">The second parent tour.</param>
        /// <param name="cityList">The list of cities in this tour.</param>
        /// <param name="rand">Random number generator. We pass around the same random number generator, so that results between runs are consistent.</param>
        /// <returns>The child tour.</returns>
        public static Tour Crossover(Tour parent1, Tour parent2, Cities cityList, Random rand)
        {
            Tour child = new Tour(cityList.Count);      // the new tour we are making

            int[] cityUsage = new int[cityList.Count];  // how many links 0-2 that connect to this city
            int   city;                                 // for loop variable
            int   nextCity;                             // the other city in this link

            for (city = 0; city < cityList.Count; city++)
            {
                cityUsage[city] = 0;
            }

            // Take all links that both parents agree on and put them in the child
            for (city = 0; city < cityList.Count; city++)
            {
                if (cityUsage[city] < 2)
                {
                    if (parent1[city].Connection1 == parent2[city].Connection1)
                    {
                        nextCity = parent1[city].Connection1;
                        if (testConnectionValid(child, cityList, cityUsage, city, nextCity))
                        {
                            joinCities(child, cityUsage, city, nextCity);
                        }
                    }
                    if (parent1[city].Connection2 == parent2[city].Connection2)
                    {
                        nextCity = parent1[city].Connection2;
                        if (testConnectionValid(child, cityList, cityUsage, city, nextCity))
                        {
                            joinCities(child, cityUsage, city, nextCity);
                        }
                    }
                    if (parent1[city].Connection1 == parent2[city].Connection2)
                    {
                        nextCity = parent1[city].Connection1;
                        if (testConnectionValid(child, cityList, cityUsage, city, nextCity))
                        {
                            joinCities(child, cityUsage, city, nextCity);
                        }
                    }
                    if (parent1[city].Connection2 == parent2[city].Connection1)
                    {
                        nextCity = parent1[city].Connection2;
                        if (testConnectionValid(child, cityList, cityUsage, city, nextCity))
                        {
                            joinCities(child, cityUsage, city, nextCity);
                        }
                    }
                }
            }

            // The parents don't agree on whats left, so we will alternate between using
            // links from parent 1 and then parent 2.

            for (city = 0; city < cityList.Count; city++)
            {
                if (cityUsage[city] < 2)
                {
                    if (city % 2 == 1)  // we prefer to use parent 1 on odd cities
                    {
                        nextCity = findNextCity(parent1, child, cityList, cityUsage, city);
                        if (nextCity == -1) // but if thats not possible we still go with parent 2
                        {
                            nextCity = findNextCity(parent2, child, cityList, cityUsage, city);;
                        }
                    }
                    else // use parent 2 instead
                    {
                        nextCity = findNextCity(parent2, child, cityList, cityUsage, city);
                        if (nextCity == -1)
                        {
                            nextCity = findNextCity(parent1, child, cityList, cityUsage, city);
                        }
                    }

                    if (nextCity != -1)
                    {
                        joinCities(child, cityUsage, city, nextCity);

                        // not done yet. must have been 0 in above case.
                        if (cityUsage[city] == 1)
                        {
                            if (city % 2 != 1)  // use parent 1 on even cities
                            {
                                nextCity = findNextCity(parent1, child, cityList, cityUsage, city);
                                if (nextCity == -1) // use parent 2 instead
                                {
                                    nextCity = findNextCity(parent2, child, cityList, cityUsage, city);
                                }
                            }
                            else // use parent 2
                            {
                                nextCity = findNextCity(parent2, child, cityList, cityUsage, city);
                                if (nextCity == -1)
                                {
                                    nextCity = findNextCity(parent1, child, cityList, cityUsage, city);
                                }
                            }

                            if (nextCity != -1)
                            {
                                joinCities(child, cityUsage, city, nextCity);
                            }
                        }
                    }
                }
            }

            // Remaining links must be completely random.
            // Parent's links would cause multiple disconnected loops.
            for (city = 0; city < cityList.Count; city++)
            {
                while (cityUsage[city] < 2)
                {
                    do
                    {
                        nextCity = rand.Next(cityList.Count);  // pick a random city, until we find one we can link to
                    } while (!testConnectionValid(child, cityList, cityUsage, city, nextCity));

                    joinCities(child, cityUsage, city, nextCity);
                }
            }

            return(child);
        }
        /// <summary>
        /// Starts the TSP algorithm.
        /// To stop before all generations are calculated, set <see cref="Halt"/> to true.
        /// </summary>
        /// <param name="populationSize">Number of random tours to create before starting the algorithm.</param>
        /// <param name="maxGenerations">Number of times to perform the crossover operation before stopping.</param>
        /// <param name="groupSize">Number of tours to examine in each generation. Top 2 are chosen as the parent tours whose children replace the worst 2 tours in the group.</param>
        /// <param name="mutation">Odds that a child tour will be mutated..</param>
        /// <param name="iterationForConverge">Iteration for converge...</param>
        /// <param name="seed">Seed for the random number generator.</param>
        /// <param name="chanceToUseCloseCity">The odds (out of 100) that a city that is known to be close will be used in any given link.</param>
        /// <param name="cityList">List of cities in the tour.</param>
        public void Begin(int populationSize, int maxGenerations, int groupSize, int mutation, int iterationForConverge, int seed, int chanceToUseCloseCity, Cities cityList)
        {
            rand = new Random(seed);

            this.cityList = cityList;

            population = new Population();
            population.CreateRandomPopulation(populationSize, cityList, rand, chanceToUseCloseCity);

            displayTour(population.BestTour, 0, false);

            bool foundNewBestTour = false;

            TspForm tspform = new TspForm();

            int ItterForStop = 0;
            int Waiter       = 0;

            for (generation = 0; generation < maxGenerations; generation++)
            {
                Waiter += 1;

                if (Waiter >= 100)
                {
                    if (TspForm.iteration == 0 || generation >= 50 && generation <= maxGenerations / 100)
                    {
                        TspForm.iteration = generation;
                    }

                    if (TspForm.iteration != generation)
                    {
                        double stop_work = TspForm.iteration - generation / 1.4;

                        if (stop_work <= 0)
                        {
                            ItterForStop += 1;
                        }
                    }

                    if (ItterForStop == iterationForConverge)
                    {
                        Halt = true;//Break the algorithm if we found the best tour
                    }
                }


                if (Halt)
                {
                    break;  // GUI has requested we exit.
                }
                foundNewBestTour = makeChildren(groupSize, mutation);

                if (foundNewBestTour)
                {
                    displayTour(population.BestTour, generation, false);
                }
            }

            displayTour(population.BestTour, generation, true);
        }
Beispiel #6
0
        /// <summary>
        /// Starts the TSP algorithm.
        /// To stop before all generations are calculated, set <see cref="Halt"/> to true.
        /// </summary>
        /// <param name="populationSize">Number of random tours to create before starting the algorithm.</param>
        /// <param name="maxGenerations">Number of times to perform the crossover operation before stopping.</param>
        /// <param name="groupSize">Number of tours to examine in each generation. Top 2 are chosen as the parent tours whose children replace the worst 2 tours in the group.</param>
        /// <param name="mutation">Odds that a child tour will be mutated..</param>
        /// <param name="seed">Seed for the random number generator.</param>
        /// <param name="chanceToUseCloseCity">The odds (out of 100) that a city that is known to be close will be used in any given link.</param>
        /// <param name="cityList">List of cities in the tour.</param>
        public void Begin(int populationSize, int maxGenerations, int groupSize, int mutation, int seed, int chanceToUseCloseCity, Cities cityList, int Col)
        {
            rand = new Random(seed);

            this.cityList = cityList;

            population = new Population();
            population.CreateRandomPopulation(populationSize, cityList, rand, chanceToUseCloseCity);

            displayTour(population.BestTour, 0, false, Col);

            bool foundNewBestTour = false;
            int  generation;

            for (generation = 0; generation < maxGenerations; generation++)
            {
                if (Halt)
                {
                    break;  // GUI has requested we exit.
                }
                foundNewBestTour = makeChildren(groupSize, mutation);

                if (foundNewBestTour)
                {
                    displayTour(population.BestTour, generation, false, Col);
                }
            }

            displayTour(population.BestTour, generation, true, Col);
        }
Beispiel #7
0
        /// <summary>
        /// crossover
        /// </summary>
        public static Tour Crossover(Tour parent1, Tour parent2, Cities cityList, Random rand)
        {
            Tour child = new Tour(cityList.Count);

            int[] cityUsage = new int[cityList.Count];
            int   city;
            int   nextCity;

            for (city = 0; city < cityList.Count; city++)
            {
                cityUsage[city] = 0;
            }


            for (city = 0; city < cityList.Count; city++)
            {
                if (cityUsage[city] < 2)
                {
                    if (parent1[city].Connection1 == parent2[city].Connection1)
                    {
                        nextCity = parent1[city].Connection1;
                        if (testConnectionValid(child, cityList, cityUsage, city, nextCity))
                        {
                            joinCities(child, cityUsage, city, nextCity);
                        }
                    }
                    if (parent1[city].Connection2 == parent2[city].Connection2)
                    {
                        nextCity = parent1[city].Connection2;
                        if (testConnectionValid(child, cityList, cityUsage, city, nextCity))
                        {
                            joinCities(child, cityUsage, city, nextCity);
                        }
                    }
                    if (parent1[city].Connection1 == parent2[city].Connection2)
                    {
                        nextCity = parent1[city].Connection1;
                        if (testConnectionValid(child, cityList, cityUsage, city, nextCity))
                        {
                            joinCities(child, cityUsage, city, nextCity);
                        }
                    }
                    if (parent1[city].Connection2 == parent2[city].Connection1)
                    {
                        nextCity = parent1[city].Connection2;
                        if (testConnectionValid(child, cityList, cityUsage, city, nextCity))
                        {
                            joinCities(child, cityUsage, city, nextCity);
                        }
                    }
                }
            }



            for (city = 0; city < cityList.Count; city++)
            {
                if (cityUsage[city] < 2)
                {
                    if (city % 2 == 1)
                    {
                        nextCity = findNextCity(parent1, child, cityList, cityUsage, city);
                        if (nextCity == -1)
                        {
                            nextCity = findNextCity(parent2, child, cityList, cityUsage, city);;
                        }
                    }
                    else
                    {
                        nextCity = findNextCity(parent2, child, cityList, cityUsage, city);
                        if (nextCity == -1)
                        {
                            nextCity = findNextCity(parent1, child, cityList, cityUsage, city);
                        }
                    }

                    if (nextCity != -1)
                    {
                        joinCities(child, cityUsage, city, nextCity);


                        if (cityUsage[city] == 1)
                        {
                            if (city % 2 != 1)
                            {
                                nextCity = findNextCity(parent1, child, cityList, cityUsage, city);
                                if (nextCity == -1)
                                {
                                    nextCity = findNextCity(parent2, child, cityList, cityUsage, city);
                                }
                            }
                            else
                            {
                                nextCity = findNextCity(parent2, child, cityList, cityUsage, city);
                                if (nextCity == -1)
                                {
                                    nextCity = findNextCity(parent1, child, cityList, cityUsage, city);
                                }
                            }

                            if (nextCity != -1)
                            {
                                joinCities(child, cityUsage, city, nextCity);
                            }
                        }
                    }
                }
            }


            for (city = 0; city < cityList.Count; city++)
            {
                while (cityUsage[city] < 2)
                {
                    do
                    {
                        nextCity = rand.Next(cityList.Count);
                    } while (!testConnectionValid(child, cityList, cityUsage, city, nextCity));

                    joinCities(child, cityUsage, city, nextCity);
                }
            }

            return(child);
        }