public void findGreatestDiff(State state) //O(n^3) { int chosenX = 0; //city x to city y int chosenY = 0; double greatestDiff = double.NegativeInfinity; //initialize to -oo to find what the greatest //difference is List <PointF> points = new List <PointF>(); for (int i = 0; i < state.getMap().GetLength(0); i++) //rows, O(n) { for (int j = 0; j < state.getMap().GetLength(1); j++) //columns { if (state.getPoint(i, j) == 0) //if point is 0 { points.Add(new PointF(i, j)); //store all 0's in a point array } } } for (int i = 0; i < points.Count; i++) //loop through 0's to find the greatest difference { //O(n^3) there will be atmost n points, because the entire //matrix will be 0 int possibleMax = findExcludeMinusInclude(Convert.ToInt32(points[i].X), Convert.ToInt32(points[i].Y), state); //O(n^2) if (possibleMax >= greatestDiff) //set the point to point values, if it is 0 is covered by = { chosenX = Convert.ToInt32(points[i].X); chosenY = Convert.ToInt32(points[i].Y); greatestDiff = possibleMax; } } State include = makeInclude(chosenX, chosenY, state); //O(n^2) if (BSSF > include.getLB()) //if include's lowerbound is better than the BSSF { include.setEdge(chosenX, chosenY); //set the edge in the dictionary checkCycles(include, chosenX, chosenY); //O(n), make sure there are no potential cycles queue.Add(include); //add to the queue to be popped off later } if (isDictionaryFilled(include)) //O(n), have all of the edges been filled? then the include.LB is better { //than the current BSSF, set the BSSF BSSF = include.getLB(); bestState = include; //save the "bestState" } State exclude = makeExclude(chosenX, chosenY, state); //O(n^2) if (BSSF > exclude.getLB()) //if exclude's lowerbound is than the BSSF, add it to the queue { queue.Add(exclude); } if (isDictionaryFilled(exclude)) //O(n), have all of the edges been filled? { // then exclude's lowerbound is better, set the BSSF to exclude.LB BSSF = exclude.getLB(); bestState = exclude; } }
public State makeExclude(int x, int y, State state) //O(n^2) { State excludeState = new State(copyMatrix(state.getMap()), state.getLB(), state.getEdges()); //O(n^2) excludeState.setPoint(x, y, double.PositiveInfinity); //make chosen point infinity reduceMatrix(excludeState); //O(n^2) excludeState.setEdges(state.getEdges()); //initialize excludeStates edges return(excludeState); }
public void reduceMatrix(State currentState) //O(n^2) { double lowerBound = currentState.getLB(); for (int i = 0; i < currentState.getMap().GetLength(0); i++) // reduce rows { //O(n^2) double minimum = double.PositiveInfinity; //find the lowest value in that row to reduce for (int j = 0; j < currentState.getMap().GetLength(1); j++) { if (currentState.getPoint(i, j) < minimum) { minimum = currentState.getPoint(i, j); } } if (minimum == 0) //if there is already a 0 in that row, don't waste time looping through it { continue; } if (minimum != double.PositiveInfinity) { for (int j = 0; j < currentState.getMap().GetLength(1); j++) { //reduce the other entire row by that value double reducedPoint = currentState.getPoint(i, j) - minimum; currentState.setPoint(i, j, reducedPoint); } lowerBound += minimum; //add that lowest value to the lowerBound } } for (int j = 0; j < currentState.getMap().GetLength(1); j++) //reduce columns { //O(n^2) double minimum = double.PositiveInfinity; for (int i = 0; i < currentState.getMap().GetLength(0); i++) { if (currentState.getPoint(i, j) < minimum) { minimum = currentState.getPoint(i, j); //find the lowest value in the column } } if (minimum == 0) //if there is already a 0 in that column, don't waste time looping through it { continue; } if (minimum != double.PositiveInfinity) { for (int i = 0; i < currentState.getMap().GetLength(0); i++) {//reduce the entire column by that value double lowerPoint = currentState.getPoint(i, j) - minimum; currentState.setPoint(i, j, lowerPoint); } lowerBound += minimum; //add that minimum value to the lowerBound } } currentState.setLB(lowerBound); //set the lowerbound }
public int findExcludeMinusInclude(int x, int y, State state) //O(n^2) { //finds the exlude minus the include of a point in a matrix State excludeState = makeExclude(x, y, state); //O(n^2) reduceMatrix(excludeState); //O(n^2) State includeState = makeInclude(x, y, state); //O(n^2) reduceMatrix(includeState); //O(n^2) int cost = Convert.ToInt32(excludeState.getLB() - includeState.getLB()); return(cost); }
public State makeInclude(int x, int y, State state) //O(n^2) { State includeState = new State(copyMatrix(state.getMap()), state.getLB(), state.getEdges()); //O(n^2) includeState.setPoint(y, x, double.PositiveInfinity); //set the "opposite point to infinity" for (int j = 0; j < includeState.getMap().GetLength(1); j++) //set the row to infinity, O(n) { includeState.setPoint(x, j, double.PositiveInfinity); } for (int i = 0; i < includeState.getMap().GetLength(0); i++) //set the column to infinity, O(n) { includeState.setPoint(i, y, double.PositiveInfinity); } reduceMatrix(includeState); //O(n^2) includeState.setEdges(state.getEdges()); //initialize includeState's dictionary of edges return(includeState); }
//O(n^2) public void reduceMatrix(State currentState) { double lowerBound = currentState.getLB(); for (int i = 0; i < currentState.getMap().GetLength(0); i++) // reduce rows {//O(n^2) double minimum = double.PositiveInfinity; //find the lowest value in that row to reduce for (int j = 0; j < currentState.getMap().GetLength(1); j++) { if (currentState.getPoint(i, j) < minimum) minimum = currentState.getPoint(i, j); } if (minimum == 0) //if there is already a 0 in that row, don't waste time looping through it continue; if (minimum != double.PositiveInfinity) { for (int j = 0; j < currentState.getMap().GetLength(1); j++) { //reduce the other entire row by that value double reducedPoint = currentState.getPoint(i, j) - minimum; currentState.setPoint(i, j, reducedPoint); } lowerBound += minimum; //add that lowest value to the lowerBound } } for (int j = 0; j < currentState.getMap().GetLength(1); j++) //reduce columns {//O(n^2) double minimum = double.PositiveInfinity; for (int i = 0; i < currentState.getMap().GetLength(0); i++) { if (currentState.getPoint(i, j) < minimum) minimum = currentState.getPoint(i, j); //find the lowest value in the column } if (minimum == 0) //if there is already a 0 in that column, don't waste time looping through it continue; if (minimum != double.PositiveInfinity) { for (int i = 0; i < currentState.getMap().GetLength(0); i++) {//reduce the entire column by that value double lowerPoint = currentState.getPoint(i, j) - minimum; currentState.setPoint(i, j, lowerPoint); } lowerBound += minimum; //add that minimum value to the lowerBound } } currentState.setLB(lowerBound); //set the lowerbound }
//O(n^2) public State makeInclude(int x, int y, State state) { State includeState = new State(copyMatrix(state.getMap()), state.getLB(), state.getEdges()); //O(n^2) includeState.setPoint(y, x, double.PositiveInfinity); //set the "opposite point to infinity" for (int j = 0; j < includeState.getMap().GetLength(1); j++) //set the row to infinity, O(n) { includeState.setPoint(x, j, double.PositiveInfinity); } for (int i = 0; i < includeState.getMap().GetLength(0); i++) //set the column to infinity, O(n) { includeState.setPoint(i, y, double.PositiveInfinity); } reduceMatrix(includeState); //O(n^2) includeState.setEdges(state.getEdges()); //initialize includeState's dictionary of edges return includeState; }
//O(n^2) public State makeExclude(int x, int y, State state) { State excludeState = new State(copyMatrix(state.getMap()), state.getLB(), state.getEdges()); //O(n^2) excludeState.setPoint(x, y, double.PositiveInfinity); //make chosen point infinity reduceMatrix(excludeState); //O(n^2) excludeState.setEdges(state.getEdges()); //initialize excludeStates edges return excludeState; }
Stopwatch timer; //global timer public void branchAndBoundSolve() { initialState = new State(new Double[Cities.Length, Cities.Length]); timer = new Stopwatch(); timer.Start(); for (int i = 0; i < Cities.Length; i++) //O(n^2), initialize initialStates map { for (int x = 0; x < Cities.Length; x++) { initialState.setPoint(i, x, Cities[i].costToGetTo(Cities[x])); if (initialState.getPoint(i, x) == 0) { initialState.setPoint(i, x, double.PositiveInfinity); } } } initialState.initializeEdges(); //initializeEdges initializes the state's dictionary //with key 0 to n (# of cities), value -> -1 reduceMatrix(initialState); //reduce the matrix to find lower bound queue = new IntervalHeap <State>(); //this is a global queue BSSF = greedy(); //find initial best solution so far, O(n^4) Console.WriteLine("BSSF: " + BSSF); findGreatestDiff(initialState); //exclude minus include, O(n^3) TimeSpan ts = timer.Elapsed; bool terminatedEarly = false; //boolean to keep track if we stopped after 30 seconds int maxStates = 0; //keeps track of the maximum amount of states in the queue at one point int totalSeconds = 0; while (queue.Count != 0) //O(2^n * n^3), because each time you expand a node, it expands it 2 times, exponentially { //where n is the number of cities if (queue.Count > maxStates) //if maxStates needs to be updated, update it { maxStates = queue.Count; } ts = timer.Elapsed; State min = queue.DeleteMin(); if (totalSeconds < ts.Seconds) { totalSeconds = ts.Seconds; Console.WriteLine("seconds: " + totalSeconds); } if (min.getLB() < BSSF) //if the min popped off the queue has a lowerbound less than { findGreatestDiff(min); //the BSSF, expand it, otherwise, prune it. -> O(n^3) } else {//all of the lowerbounds are worse than the BSSF, break! break; } } if (!terminatedEarly)//if it solved the problem in less than 30 seconds { int city = 0; for (int i = 0; i < bestState.getEdges().Count; i++) //O(n) { if (i == 0) //outputting a map into the Route list { Route.Add(Cities[i]); city = bestState.getEdge(i); } else { Route.Add(Cities[city]); city = bestState.getEdge(city); } } bssf = new TSPSolution(Route); // update the cost of the tour. Program.MainForm.tbCostOfTour.Text = " " + bssf.costOfRoute(); Program.MainForm.tbElapsedTime.Text = ts.TotalSeconds.ToString(); // do a refresh. Program.MainForm.Invalidate(); } }