Beispiel #1
0
        /// <summary>
        /// performs a Branch and Bound search of the state space of partial tours
        /// stops when time limit expires and uses BSSF as solution
        /// @returns results array for GUI that contains three ints: cost of solution, time spent to find solution, number of solutions found during search (not counting initial BSSF estimate)
        public string[] bBSolveProblem()
        {
            // counts the number of bssf updates / solutions found
            int count = 0;

            // counts the number of pruned states
            int pruned = 0;

            // counts the number of total states
            int total_states = 0;

            //container for results
            string[] results = new string[3];

            //priority queue implementation
            HeapQueue myqueue = new HeapQueue();

            Route = new ArrayList();
            Stopwatch timer = new Stopwatch();

            timer.Start();
            Route.Clear();

            //generate greedy bssf as initial guess
            greedySolveProblem();

            //initialize a matrix with all the cities
            bBNode init = new bBNode(GetCities());

            /**
             * Starts at the first city (0).
             * It doesn't matter where we start because we are looking for a "loop" of cities.
             * And we don't want to repeatedly find the same solution by starting at a different city.
             */
            bBNode root = new bBNode(init, 0);
            bBNode next;

            //initialize queue
            myqueue.MakeQueue((int)Math.Pow(Cities.Length, 2), root);
            total_states++;

            //while the queue is not empty and we haven't hit the time limit . . .
            while (!myqueue.IsEmpty() && timer.ElapsedMilliseconds < this.time_limit)
            {
                // take the top node in the queue
                next = (bBNode)myqueue.DeleteBestRoute();
                //if it has a better solution than the bssf, go deeper, otherwise, we prune it.
                if (next.getBound() < bssf.costOfRoute())
                {
                    // check if the route is finished
                    if (next.getRouteLength() == Cities.Length)
                    {
                        //We found a better solution!
                        bssf = new TSPSolution(next.getRoute());
                        count++;
                    }
                    else
                    {
                        // expand the node, and only insert the children that do better than the bssf
                        List <bBNode> children = next.Expand();
                        foreach (bBNode c in children)
                        {
                            total_states++;
                            if (c.getBound() < bssf.costOfRoute())
                            {
                                myqueue.Insert(c);
                            }
                            else
                            {
                                pruned++;
                            }
                        }
                    }
                }
                else
                {
                    pruned++;
                }
            }
            timer.Stop();

            Console.WriteLine("**************************************");
            Console.WriteLine("# cities: " + Cities.Length);
            Console.WriteLine("# seed: " + _seed);
            Console.WriteLine("RunningTime: " + timer.Elapsed);
            Console.WriteLine("Best tour: " + costOfBssf());
            Console.WriteLine("Max stored states: " + myqueue.getMaxStoredStates());
            Console.WriteLine("Number of Solutions: " + count);
            Console.WriteLine("Number total states: " + total_states);
            Console.WriteLine("Total pruned states: " + pruned);

            results[COST]  = costOfBssf().ToString();                         // load results array
            results[TIME]  = timer.Elapsed.ToString();
            results[COUNT] = count.ToString();

            return(results);
        }