private void Swap(int xi, int yi)
        {
            SubProblem temp = this.queue[xi];

            this.queue[xi] = this.queue[yi];
            this.queue[yi] = temp;
        }
        public SubProblem Pop()
        {
            SubProblem minimum = this.queue[0];

            this.Swap(0, this.queue.Count - 1);
            this.queue.RemoveAt(queue.Count - 1);

            int i = 0;

            while (this.GetLeftChildIndex(i) < this.queue.Count)
            {
                int leftChildIndex  = this.GetLeftChildIndex(i);
                int rightChildIndex = this.GetRightChildIndex(i);
                int minChildIndex;
                if (rightChildIndex >= this.queue.Count)
                {
                    minChildIndex = leftChildIndex;
                }
                else if (this.GetHeuristic(this.queue[leftChildIndex]) < this.GetHeuristic(this.queue[rightChildIndex]))
                {
                    minChildIndex = leftChildIndex;
                }
                else
                {
                    minChildIndex = rightChildIndex;
                }

                if (this.GetHeuristic(this.queue[minChildIndex]) < this.GetHeuristic(this.queue[i]))
                {
                    this.Swap(i, minChildIndex);
                    i = minChildIndex;
                }
                else
                {
                    break;
                }
            }

            return(minimum);
        }
 public double GetHeuristic(SubProblem subProblem)
 {
     return(4 * subProblem.lowerBound / subProblem.path.Count);
 }
 public void Add(SubProblem subProblem)
 {
     this.queue.Add(subProblem);
     this.BubbleUp(this.queue.Count - 1);
 }
        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);
        }