public void bubbleUp(Node n, int i) { int p = (i / 2); while ((i != 1) && (myQueue[p].getKey() > n.getKey())) { myQueue[i] = myQueue[p]; i = p; p = (i / 2); } myQueue[i] = n; }
public void siftDown(Node n, int i) { int c = minChild(i); while ((c != 0) && (myQueue[c].getKey() < n.getKey())) { myQueue[i] = myQueue[c]; i = c; c = minChild(i); } myQueue[i] = n; }
/// <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 solveProblem() { Stopwatch timer = new Stopwatch(); timer.Start(); l = Cities.Length; includeMatrix = new double[l, l]; double[,] costMatrix = new double[l, l]; //make the initial cost matrix for (int i = 0; i < l; i++) { for (int j = 0; j < l; j++) { if (i == j) { costMatrix[i, j] = double.PositiveInfinity; } else { costMatrix[i, j] = Cities[i].costToGetTo(Cities[j]); } } } //use greedy algorithm to get an initial bssf int startIndex = 0; while (bssF == double.PositiveInfinity) { bssF = greedy(costMatrix, startIndex); startIndex++; } //reduce the original cost Matrix double cost = reduceMatrix(costMatrix); //--------------------------------------------------------- //put a starter node on the heap with the reduced cost and the matrix, // an empty path, and and edgeCount of 0 //---------------------------------------------------------- BinaryHeap bh = new BinaryHeap(heapSize); int[] pathArray = new int[l]; for (int i = 0; i < l; i++) { pathArray[i] = -1; } bh.insert(new Node(cost, costMatrix, pathArray, 0)); //while queue is not empty while (bh.getQueueSize() > 0) { //since we increase the number of states whether or not they are put on the queue numStatesCreated += 2; //pop the lowest cost node off the queue Node n = bh.deleteMin(); int[] nodePath = n.getPathArray(); //this should be a valid path, we successfully included enough edges if (n.getEdgeCount() == l) { //update bssf, path, bssF = n.getKey(); bestPathSoFar = n.getPathArray(); //keep track of updates numBSSFupdates++; BinaryHeap temp = new BinaryHeap(heapSize); int preCount = bh.getQueueSize(); // go through the queue and get rid of too high LB's while (bh.getQueueSize() > 0) { Node node = bh.deleteMin(); if (node.getKey() < bssF) { temp.insert(node); } bh = temp; } //when I tried to increment numStatesPruned in the while loop it was optimized out // or something, so this is where I find out how many states I pruned int postCount = bh.getQueueSize(); numStatesPruned += preCount - postCount; } else { //was not a complete path. We now go to the method that makes an include and exclude state splitDecision(n.getMatrix(), nodePath, n.getEdgeCount()); //check to see if an include improved the bssf //if not do nothing, don't put it on the queue if (((n.getKey() + maxInclude) < bssF)) { int[] includePath = new int[l]; //must make a copy of the path array since our queue might be expanding for (int i = 0; i < includePath.Length; i++) { includePath[i] = nodePath[i]; } //includes one edge includePath[maxI] = maxJ; //we must also make a copy of the cost matrix double[,] copyIncludeMatrix = new double[l, l]; if (includeMatrix != null) { for (int i = 0; i < l; i++) { for (int j = 0; j < l; j++) { copyIncludeMatrix[i, j] = includeMatrix[i, j]; } } } Node includeNode = new Node(n.getKey() + maxInclude, copyIncludeMatrix, includePath, n.getEdgeCount() + 1); bh.insert(includeNode); } else { numStatesPruned++; } //only insert the exclude state if the lower bound is less than bssf if ((n.getKey() + maxExclude < bssF) && (bh.getQueueSize() < queueLimit)) { //save some time by just using the parents' path and almost the parent's cost matrix n.getMatrix()[maxI, maxJ] = double.PositiveInfinity; reduceMatrix(n.getMatrix()); Node excludeNode = new Node(n.getKey() + maxExclude, n.getMatrix(), nodePath, n.getEdgeCount()); bh.insert(excludeNode); } else { numStatesPruned++; } } //keep track of the highest number of stored states if (bh.getQueueSize() > maxQueueSize) { maxQueueSize = bh.getQueueSize(); } //time out after 30 seconds if (timer.ElapsedMilliseconds > 30000) { numStatesPruned = numStatesCreated - bh.getQueueSize(); break; } } //------------------------------------------------------------------ //report the route and bssf just like in the demo, and time elapsed //------------------------------------------------------------------ Route = new ArrayList(); int city = 0; int count = 0; Route.Add(Cities[0]); while (count != l) { city = bestPathSoFar[city]; Route.Add(Cities[city]); count++; } // call this the best solution so far. bssf is the route that will be drawn by the Draw method. bssf = new TSPSolution(Route); // update the cost of the tour. //some values we needed for the table Program.MainForm.tbCostOfTour.Text = " " + bssf.costOfRoute() + " " + maxQueueSize + " " + numBSSFupdates + " " + numStatesCreated + " " + numStatesPruned + " "; //report the time elapsed timer.Stop(); Program.MainForm.tbElapsedTime.Text = timer.Elapsed.ToString(); // do a refresh. Program.MainForm.Invalidate(); }