//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); }
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; }