public int BBSolution(Stopwatch timer)
        {
            // Stats
            int maxStates    = 0;
            int totalStates  = 0;
            int prunedStates = 0;

            int           count             = 0;
            PriorityQueue q                 = new PriorityQueue();
            SubProblem    initialSubProblem = new SubProblem(
                this.CalculateCostMatrix(),
                this.Cities.Length,
                0,
                new List <int>()
                );

            initialSubProblem.path.Add(0);
            q.Add(initialSubProblem);

            while (!q.Empty() && timer.ElapsedMilliseconds < this.time_limit)
            {
                // Update statistics
                if (q.Size() > maxStates)
                {
                    maxStates = q.Size();
                }
                ++totalStates;

                SubProblem subProblem = q.Pop();


                if (subProblem.path.Count == this.Cities.Length &&
                    subProblem.path[subProblem.GetCurrentCityIndex()] != 0)
                {
                    // The subproblem is a valid solution!
                    this.bssf = new TSPSolution(PathToRoute(subProblem.path));
                    count++;
                }
                else
                {
                    if (subProblem.HasMorePaths())
                    {
                        for (int col = 0; col < this.Cities.Length; ++col)
                        {
                            if (subProblem.reducedMatrix[subProblem.GetCurrentCityIndex(), col] != double.PositiveInfinity)
                            {
                                if (subProblem.reducedMatrix[subProblem.GetCurrentCityIndex(), col] + subProblem.lowerBound < this.costOfBssf())
                                {
                                    List <int> pathClone  = new List <int>(subProblem.path);
                                    SubProblem newProblem = new SubProblem(
                                        (double[, ])subProblem.reducedMatrix.Clone(),
                                        this.Cities.Length,
                                        subProblem.lowerBound,
                                        pathClone
                                        );
                                    newProblem.path.Add(col);
                                    newProblem.BlockPaths(
                                        subProblem.GetCurrentCityIndex(),
                                        newProblem.GetCurrentCityIndex()
                                        );
                                    newProblem.ReduceCostMatrix();
                                    q.Add(newProblem);
                                }
                                else
                                {
                                    ++prunedStates;
                                }
                            }
                        }
                    }
                }
            }

            // Print stats
            Console.WriteLine("Max # of states: {0}", maxStates);
            Console.WriteLine("Total # number of states: {0}", totalStates);
            Console.WriteLine("# of states pruned: {0}", prunedStates);

            return(count);
        }