//constructor for creating all nodes but the first
        public Node(Node prev, bool isInclude, int exit, int enter)
        {
            //copy info needed from parent node
            this.lowerBound = prev.lowerBound;
            this.matrixLength = prev.matrixLength;
            this.rCmatrix = copy2Darray(prev.rCmatrix);
            this.entered = copyArray(prev.entered);
            this.exited = copyArray(prev.exited);

            if (isInclude)//code only for an include node
            {
                this.totalEdges = prev.totalEdges + 1;
                entered[enter] = exit;
                exited[exit] = enter;
                rCmatrix[enter, exit] = Double.PositiveInfinity;
                eliminateEdges(rCmatrix, exit, enter);
                if(this.totalEdges < matrixLength)
                {
                    eliminatePCycles(rCmatrix, exit, enter);
                }

            }
            else//code only for an exclude node
            {
                this.totalEdges = prev.totalEdges;
                rCmatrix[exit, enter] = Double.PositiveInfinity;
            }

            reduceMatrix(rCmatrix);
        }
Пример #2
0
        public ArrayList BranchAndBound(City[] Cities, ArrayList Route, double BSSF)
        {
            Node startNode = new Node(Cities);
            startNode.initStaticMembers();
            PriorityQueue pQ = new PriorityQueue(startNode);
            ArrayList bbRoute = null;
            Stopwatch timer = new Stopwatch();
            timer.Start();

            //while ((pQ.Size() > 0) && (pQ.Peek() < BSSF) && (timer.Elapsed.TotalMinutes < 10))
            while ((pQ.Size() > 0) && (pQ.Peek() < BSSF) && (timer.Elapsed.TotalSeconds < 30))
            {
                // Keep track of the largest size of the queue
                if (pQ.Size() > Node.maxNodesCreated)
                {
                    Node.maxNodesCreated = pQ.Size();
                }

                startNode = pQ.DeleteMinimum();
                //startNode.matrix2Table();

                // Check for a solution
                if (startNode.includedEdges == Cities.Length)
                {
                    ArrayList tempRoute = new ArrayList();

                    if (!startNode.exited.Contains(-1))
                    {
                        int index = 0;

                        while (tempRoute.Count < Cities.Length)
                        {
                            tempRoute.Add(Cities[startNode.exited[index]]);
                            index = startNode.exited[index];
                        }

                        BSSF = startNode.lowerBound;
                        bbRoute = tempRoute;
                        Node.numSolutions++;
                    }
                }

                Node incNode = new Node(startNode);
                Node excNode = new Node(startNode);
                Node maxInclude = null;
                Node maxExclude = null;

                double maxDiff = -1;
                double diff = 0;
                int maxRow = 0;
                int maxCol = 0;

                for (int row = 0; row < startNode.matrixSize; row++)
                {
                    for (int col = 0; col < startNode.matrixSize; col++)
                    {
                        if (startNode.rcMatrix[row, col] == 0)
                        {
                            Node includeNode = new Node(incNode, true, row, col);
                            Node excludeNode = new Node(excNode, false, row, col);
                            diff = excludeNode.lowerBound - includeNode.lowerBound;
                            Node.numStatesCreated += 2;

                            if (diff > maxDiff)
                            {
                                maxDiff = diff;
                                maxRow = row;
                                maxCol = col;
                                maxInclude = new Node(includeNode);
                                maxExclude = new Node(excludeNode);
                            }
                        }
                    }
                }

                if (maxInclude != null && maxInclude.lowerBound < BSSF)
                {
                    pQ.Insert(maxInclude);
                }
                else
                {
                    Node.pruneCount++;
                }

                if (maxExclude != null && maxExclude.lowerBound < BSSF)
                {
                    pQ.Insert(maxExclude);
                }
                else
                {
                    Node.pruneCount++;
                }
            }

            timer.Stop();
            Node.timeElapsed = timer.ElapsedMilliseconds;

            if (bbRoute == null)
            {
                return Route;
            }
            else
            {
                // Add the rest of the queue to the pruned count
                Node.pruneCount += pQ.Size();
                return bbRoute;
            }
        }
        public void insert(Node node)
        {
            heap.Add(node);

            bubbleUp(heap.Count - 1);
        }
        /// <summary>
        ///  solve the problem.  This is the entry point for the solver when the run button is clicked
        /// right now it just picks a simple solution. 
        /// </summary>
        public void solveProblemBandB()
        {
            //initialize BSSF with a greedy algorithm
            Algorithms algorithms = new Algorithms();
            bssf = new TSPSolution(algorithms.greedy(Cities));
            Node.bssf = bssf.costOfRoute();

            int maxQsize = 0;
            int totalStates = 0;

            int timeSeconds = Convert.ToInt32(Program.MainForm.textBoxTime.Text);

            //set up priority queue and stopwatch
            PriorityQueue PQ = new PriorityQueue();
            PQ.insert(new Node(Cities));
            Stopwatch stopwatch = new Stopwatch();
            stopwatch.Start();
            while(PQ.getSize() > 0 && stopwatch.Elapsed.TotalSeconds < timeSeconds)
            {
                //pop node off of queue and check lower bound against bssf
                Node node = PQ.deleteMin();
                if(node.lowerBound > Node.bssf)
                {
                    Node.prunes++;
                    break;
                }

                Node include = null;
                Node exclude = null;
                double maxDif = Double.NegativeInfinity;

                //search for include/exclude edge that gives max difference in lower bound
                double[,] matrix = node.rCmatrix;
                for (int i = 0; i < node.matrixLength; i++)
                {
                    if (node.exited[i] == -1)
                    {
                        for (int j = 0; j < node.matrixLength; j++)
                        {
                            if (matrix[i, j] == 0)
                            {
                                Node tempInclude = new Node(node, true, i, j);
                                Node tempExclude = new Node(node, false, i, j);
                                double potentialMaxDif = tempExclude.lowerBound - tempInclude.lowerBound;
                                if (potentialMaxDif > maxDif)
                                {
                                    maxDif = potentialMaxDif;
                                    include = tempInclude;
                                    exclude = tempExclude;
                                }
                            }
                        }
                    }

                }

                //check if found a bssf
                if(include.totalEdges == include.matrixLength && include.lowerBound < Node.bssf)
                {
                    Node.bssfUpdates++;
                    Node.bssf = include.lowerBound;
                    Node.bssfNode = include;
                }
                else if(include.lowerBound < Node.bssf)//add include node to queue
                {
                    PQ.insert(include);
                    int currentQSize = PQ.getSize();
                    if(currentQSize > maxQsize)
                    {
                        maxQsize = currentQSize;
                    }
                }
                else//prune include node
                {
                    Node.prunes++;
                }

                if(exclude.lowerBound < Node.bssf)//add exclude node to queue
                {
                    PQ.insert(exclude);
                    int currentQSize = PQ.getSize();
                    if (currentQSize > maxQsize)
                    {
                        maxQsize = currentQSize;
                    }
                }
                else//prune exclude node
                {
                    Node.prunes++;
                }

                totalStates += 2;//2 states are created per while-loop iteration

            }

            stopwatch.Stop();

            //if stopwatch is < 30, then we have found an optimal solution
            bool isOptimal = false;
            if(stopwatch.Elapsed.TotalSeconds < timeSeconds)
            {
                isOptimal = true;
            }

            //prune number of items left in the queue
            Node.prunes += PQ.getSize();

            //if a bssf has been found better than the greedy solution
            if(Node.bssfNode != null)
            {
                Node solution = Node.bssfNode;

                ArrayList route = solution.getRoute(Cities);

                // call this the best solution so far.  bssf is the route that will be drawn by the Draw method.
                bssf = new TSPSolution(route);
            }

            //display stats
            if (isOptimal)
            {
                Program.MainForm.tbCostOfTour.Text = " " + bssf.costOfRoute() + "*";
            }
            else
            {
                Program.MainForm.tbCostOfTour.Text = " " + bssf.costOfRoute();
            }

            Program.MainForm.tbElapsedTime.Text = " " + stopwatch.Elapsed.TotalSeconds;

            // do a refresh.
            Program.MainForm.Invalidate();

            //print more stats
            Console.WriteLine();
            Console.WriteLine("Max # of stored states: " + maxQsize);
            Console.WriteLine("# of BSSF updates: " + Node.bssfUpdates);
            Console.WriteLine("Total # of states created: " + totalStates);
            Console.WriteLine("Total # of states pruned: " + Node.prunes);

            Node.resetStaticVariables();
        }
 public static void resetStaticVariables()
 {
     Node.bssf = Double.PositiveInfinity;
     Node.bssfNode = null;
     Node.prunes = 0;
     Node.bssfUpdates = 0;
 }