Example #1
0
        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);
        }