Пример #1
0
        public ProblemAndSolver.TSPSolution Solve()
        {
            //Tests show that heap is better for more cities, array is better for less
            queue           = new HeapPriorityQueue();
            nodesCreated    = 0;
            prunedNodes     = 0;
            averageDistance = 0;
            numUpdates      = 0;
            var timer = new Stopwatch();

            timer.Start();
            //Build the mother node state
            //Build a starting matrix. time O(n^2) space O(n^2)
            int count = 0;

            double[,] motherMatrix = new double[cities.Length, cities.Length];
            for (int row = 0; row < cities.Length; row++)
            {
                for (int col = 0; col < cities.Length; col++)
                {
                    double cost = cities[row].costToGetTo(cities[col]);
                    motherMatrix[row, col] = row == col ? double.PositiveInfinity : cost;
                    if (!double.IsPositiveInfinity(cost))
                    {
                        averageDistance += cost;
                        count++;
                    }
                }
            }
            averageDistance = averageDistance / count;
            //Reduce the matrix & get the bound. time O(n^2)
            double    bound = ReduceMatrix(motherMatrix);
            ArrayList route = new ArrayList();

            route.Add(cities[0]);
            //Put them in a new state
            State motherState = new State(motherMatrix, route, bound, 0);

            //Expand the mother node state. time O(n^3) space O(n^3)
            ExpandState(motherState);
            //While the priority queue is not empty. Worst case Time O(n^3*b^n+log(n!)), with b > 1
            while (!queue.IsEmpty() && timer.ElapsedMilliseconds < timeLimit)
            {
                //pop off the top state and expand it. time O(n^3) space O(n^3)
                //DeleteMin could potentially be as bad as time O(logn!)
                ExpandState(queue.DeleteMin());
            }
            timer.Stop();

            //When the timer goes off, update results and return bssf
            results[ProblemAndSolver.COST]  = costOfBssf().ToString();
            results[ProblemAndSolver.TIME]  = timer.Elapsed.ToString();
            results[ProblemAndSolver.COUNT] = numUpdates.ToString();
            Console.WriteLine("Max Stored States: " + queue.LargestSize());
            Console.WriteLine("States Created: " + nodesCreated);
            Console.WriteLine("States Pruned: " + prunedNodes);
            return(bssf);
        }
Пример #2
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
        /// </summary>
        /// <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)</returns>
        public string[] bBSolveProblem()
        {
            string[]      results = new string[3];
            int           count   = 0;
            Stopwatch     timer   = new Stopwatch();
            PriorityQueue queue   = new PriorityQueue();

            timer.Start();

            greedySolveProblem();

            queue.Insert(new PartialPath(CalculateInitialMatrix(), Cities));

            /* While there are still partial paths on the queue,
             * the best one is popped off and its children are generated.
             * Those that are better than the bssf are added to the queue.
             */
            while (timer.Elapsed.TotalMilliseconds < time_limit && !queue.Empty())
            {
                PartialPath currentNode = queue.DeleteMin();
                if (currentNode.FullPath && currentNode.CompletePath)
                {
                    TSPSolution potentialSolution = new TSPSolution(currentNode.Path);
                    if (potentialSolution.costOfRoute() < costOfBssf())
                    {
                        bssf = potentialSolution;
                        count++;
                    }
                }
                else if (currentNode.LowerBound < costOfBssf())
                {
                    GenerateChildren(currentNode, queue);
                }
            }

            timer.Stop();

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

            Console.WriteLine("Branch & Bound Size: " + Cities.Length + " Random: " + Seed + " Path: " + costOfBssf().ToString() + " Time: " + timer.Elapsed.ToString());


            return(results);
        }