// finds the best tour possible using the branch and bound method of attack // For an example of what to return, see DefaultSolver.solve() method. public Problem solve() { Stopwatch timer = new Stopwatch(); timer.Start(); State beginningState = new State(cityData.size); SolverHelper.initializeState(beginningState, cityData); this.q.Enqueue(beginningState); Problem determineBSSFProblem = SolverHelper.clone(cityData); this.cityData.bssf = GreedySolver.solve(determineBSSFProblem).bssf; while (q.Count > 0) { recur(q.Dequeue()); //Clear out any states that have a BSSF less than //that of the current } timer.Stop(); cityData.timeElasped = timer.Elapsed; return(cityData); }
public TSPSolution(City[] cities, List <int> cityOrder, double costOfRoute) { // From the list of city indexes, create the list of cities route = new List <City>(cityOrder.Count); foreach (int i in cityOrder) { City temp = SolverHelper.clone(cities[i]); route.Add(temp); } this.costOfRoute = costOfRoute; }
// Returns the index of the last city to be visited in the cycle private static void recur(State state) { //state.printState(); int currCityIndex = state.currCityIndex; // All cities have been visited; finish and return if (state.getCitiesVisited() == state.size - 1) { // The current path cannot be completed bc there is no path from the last city to the first if (state.matrix[currCityIndex, state.cityOfOriginIndex] == double.PositiveInfinity) { state.lowerBound = double.PositiveInfinity; } else { state.addCity(currCityIndex); state.lowerBound += state.matrix[currCityIndex, state.cityOfOriginIndex]; return; } } state.addCity(currCityIndex); // find the smallest distance to any other city double closestCityDistance = double.PositiveInfinity; int closestCityIndex = -1; for (int j = 1; j < state.matrix.GetLength(1); j++) { // For a different starting city, the following code // would have to be added: //for (int j = 0; j < state.matrix.GetLength(1); j++) //if (j == state.startCityIndex) // continue; if (state.matrix[currCityIndex, j] < closestCityDistance) { closestCityIndex = j; closestCityDistance = state.matrix[currCityIndex, j]; } } // add [i,j] state.lowerBound += closestCityDistance; // Blank out appropriate spaces SolverHelper.blankOut(state, closestCityIndex); // reduce SolverHelper.reduce(state); state.currCityIndex = closestCityIndex; recur(state); }
// finds the greedy tour starting from each city and keeps the best (valid) one // For an example of what to return, see DefaultSolver.solve() method. public static Problem solve(Problem cityData) { Stopwatch timer = new Stopwatch(); timer.Start(); State state = new State(cityData.size); SolverHelper.initializeState(state, cityData); state.currCityIndex = 0; recur(state); timer.Stop(); // Since cityData is static, it is pointing to the cityData object // that was passed in. Setting it's BSSF here will set the BSSF // of the cityData object in the Form1 class. cityData.bssf = new TSPSolution(cityData.cities, state.cityOrder, state.lowerBound); cityData.timeElasped = timer.Elapsed; cityData.solutions = 1; return(cityData); }
private void recur(State state) { // This is a leaf // All cities have been visited; finish and return if (state.getCitiesVisited() == cityData.size - 1) { // The path to the last city is blocked if (state.matrix[state.currCityIndex, state.cityOfOriginIndex] == SolverHelper.SPACE_PLACEHOLDER) { return; } state.addCity(state.currCityIndex); // Since we've hit a leaf node, we've found another possible solution cityData.solutions++; // Add the last hop to the lower bound to get the cost of the complete cycle state.lowerBound += state.matrix[state.currCityIndex, state.cityOfOriginIndex]; // Check to see if this route is smaller than the current BSSF // If so, replace the current BSSF if (state.lowerBound < cityData.bssf.costOfRoute) { cityData.bssf = new TSPSolution(cityData.cities, state.cityOrder, state.lowerBound); } return; } state.addCity(state.currCityIndex); for (int j = 1; j < state.matrix.GetLength(1); j++) { //Console.WriteLine(state.currCityIndex + " " + j); //state.printState(); double currDistVal = state.matrix[state.currCityIndex, j]; if (currDistVal != SolverHelper.SPACE_PLACEHOLDER && state.lowerBound + currDistVal < cityData.bssf.costOfRoute) { State childState = SolverHelper.clone(state); // add [i,j] childState.lowerBound += currDistVal; // Blank out the appropriate values with the placeholder SolverHelper.blankOut(childState, j); //childState.printState(); // reduce SolverHelper.reduce(childState); childState.currCityIndex = j; if (childState.lowerBound < cityData.bssf.costOfRoute) { q.Enqueue(childState); } } } }