Example #1
0
 private void printRoute(BBNode node)
 {
     List<City> cities = new List<City>(Cities);
     Console.WriteLine("Route: ");
     foreach (Object obj in node.Route)
     {
         City city = (City)obj;
         Console.Write(cities.IndexOf(city) + "->");
     }
     Console.WriteLine(cities.IndexOf((City)node.Route[0]));
 }
Example #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];
            Stopwatch timer = new Stopwatch();
            int intermediateSolutions = 0;
            int numStatesCreated = 0;
            int maxInQueue = 0;
            int numStatesPruned = 0;
            defaultSolveProblem();

            timer.Start();

            // initialize the root node
            List<int> children = new List<int>();
            int[,] matrix = initializeCostMatrix(Cities, ref children, 0);
            //printMatrix(matrix, "Absolute Cost:");
            BBNode rootNode = new BBNode(children, matrix, 0);      // 0 is it's row index in the cost matrix
            rootNode.reduceMatrix();
            //printMatrix(rootNode.costMatrix, "Root Reduced Matrix:");
            //Console.WriteLine("\nRoot.LocalBound = " + rootNode.localBound);
            rootNode.Route.Add(Cities[0]);          // the route starts at itself

            // initialize the priority queue (add the root)
            priorityQueue.Enqueue(rootNode, 0);
            double costOfBSSF = bssf.costOfRoute();
            //Console.WriteLine("BSSF cost:" + costOfBSSF);

            bool timesUp = false;

            while (!timesUp && priorityQueue.Count > 0)
            {
                BBNode node = priorityQueue.Dequeue();
                if (node.localBound < costOfBSSF)
                {
                    foreach (int child in node.children)
                    {
                        // Check if time has expired
                        if (timer.Elapsed.TotalMilliseconds > time_limit)
                        {
                            timesUp = true;
                        }
                        // Find the cost to the child node from the current node
                        int costToNode = node.costMatrix[node.rowIndex, child];

                        if ((costToNode < int.MaxValue) && (costToNode + node.localBound) < costOfBSSF)      // we want to create a new state
                        {
                            List<int> childrenToPass = new List<int>(node.children);
                            childrenToPass.Remove(child);
                            int[,] childMatrix = infinityOutMatrix(node.costMatrix, node.rowIndex, child);
                            BBNode childNode = new BBNode(childrenToPass, childMatrix, child);              // Create a state
                            childNode.localBound = node.localBound + node.costMatrix[node.rowIndex, child];
                            childNode.reduceMatrix();
                            childNode.Route.AddRange(node.Route);
                            childNode.Route.Add(Cities[child]);
                            numStatesCreated++;

                            // if it's a leaf, update the BSSF
                            if (childNode.children.Count == 0)
                            {
                                if (childNode.localBound < costOfBSSF)
                                {
                                    bssf = new TSPSolution(childNode.Route);
                                    costOfBSSF = bssf.costOfRoute();
                                    intermediateSolutions++;
                                }
                            }
                            else    // otherwise, add it to the queue.
                            {
                                priorityQueue.Enqueue(childNode, (float)(childNode.localBound / (childNode.Route.Count * 1000)));
                                if (priorityQueue.Count > maxInQueue)
                                {
                                    maxInQueue = priorityQueue.Count;
                                }
                            }
                        }
                        else
                        {
                            numStatesPruned++;
                        }
                        // otherwise ignore it. Definitely not part of the solution.
                    }
                }
                else numStatesPruned++;

            }

            timer.Stop();
            results[COST] = bssf.costOfRoute().ToString();    // load results into array here, replacing these dummy values
            results[TIME] = timer.Elapsed.ToString();
            results[COUNT] = intermediateSolutions.ToString();

            // Used to fill out the table in the report
            String storedStates = "Max Stored States: " + maxInQueue + "\n";
            String statesCreated = "Total States Created: " + numStatesCreated + "\n";
            String statesPruned = "Total State Pruned: " + numStatesPruned + "\n";
            MessageBox.Show(storedStates + statesCreated + statesPruned);
            Console.WriteLine(storedStates);
            Console.WriteLine(statesCreated);
            Console.WriteLine(statesPruned);

            return results;
        }
        // Processes a node in the branch and bound tree
        // If it is a leaf node and is better than the current best solution,
        // set the bssf to this node.  If it is not a leaf, add nodes for each
        // unvisited city which is lower than the current upper bound.
        private void ProcessBBNode(
            IPriorityQueue <BBNode, BBPriority> queue,
            Tuple <BBNode, BBPriority> el,
            ref int count,
            ref double upper,
            ref int totalStates,
            ref int pruned,
            ref int maxQueueSize
            )
        {
            BBNode top = el.Item1;

            // Check if the route has passed through every city
            if (top.Cities.Count == Cities.Length)
            {
                // Add the trip back to the starting node.
                double cost = top.Cost + top.Matrix.Costs[top.Cities[top.Cities.Count - 1], 0];
                if (cost < upper)
                {
                    upper = cost;
                    count++;

                    // CLear any nodes with higher cost than the new upper. DEPTH_NONE indicates
                    // that only cost should be considered, and not depth.  Add the pruned nodes
                    // to the pruned count.
                    pruned += queue.DeleteElementsHigherThan(new BBPriority(BBPriority.DEPTH_NONE, upper));

                    ArrayList cities = new ArrayList();
                    foreach (int city in top.Cities)
                    {
                        cities.Add(Cities[city]);
                    }


                    bssf = new TSPSolution(cities);
                }
            }
            else
            {
                // Add nodes to the queue for each potential route out of the current city
                int lastCity = top.Cities[top.Cities.Count - 1];
                for (int i = 0; i < top.Matrix.Costs.GetLength(0); i++)
                {
                    if (!Double.IsInfinity(top.Matrix.Costs[lastCity, i]))
                    {
                        Matrix newMatrix = top.Matrix.FollowRoute(lastCity, i);
                        double newCost   = el.Item2.Cost
                                           + top.Matrix.Costs[lastCity, i]
                                           + (newMatrix.LowerBound - top.Matrix.LowerBound);

                        totalStates++;

                        // If the prospective state is lower cost than the bssf, add it to the queue
                        if (newCost < upper)
                        {
                            List <int> newCities = top.Cities.Concat(new List <int> {
                                i
                            }).ToList();
                            queue.Insert(
                                new BBNode(newCities, newMatrix, newCost),
                                new BBPriority(newCities.Count, newCost)
                                );
                        }
                        else
                        {
                            pruned++;
                        }
                    }
                }

                if (queue.Size > maxQueueSize)
                {
                    maxQueueSize = queue.Size;
                }
            }
        }