private Node getPartialRoute(Node node, int rowNum, int colNum) { double[,] updated = new double[Cities.Length, Cities.Length]; for (int i = 0; i < Cities.Length; i++) { for (int k = 0; k < Cities.Length; k++) { updated[i, k] = node.getMatrix()[i, k]; } } ArrayList partialRoute = new ArrayList(); for (int i = 0; i < node.getRoute().Count; i++) { partialRoute.Add(node.getRoute()[i]); } double newbssf = node.getbssf() + node.getMatrix()[rowNum, colNum]; for (int i = 0; i < Cities.Length; i++) { updated[rowNum, i] = double.PositiveInfinity; updated[i, colNum] = double.PositiveInfinity; } updated[rowNum, colNum] = double.PositiveInfinity; updated[colNum, rowNum] = double.PositiveInfinity; partialRoute.Add(Cities[colNum]); Node newNode = new Node(newbssf, updated, partialRoute); newNode.setNum(colNum); return(reduceMatrix(newNode)); }
private Node reduceMatrix(Node node) { double[,] updated = new double[Cities.Length, Cities.Length]; double updatedbssf = node.getbssf(); for (int i = 0; i < Cities.Length; i++) { for (int k = 0; k < Cities.Length; k++) { updated[i, k] = node.getMatrix()[i, k]; } } for (int i = 0; i < Cities.Length; i++) //for each row { double min = double.PositiveInfinity; for (int k = 0; k < Cities.Length; k++) //get minimum for each row { if (updated[i, k] < min) { min = updated[i, k]; } } if (min != 0 && min != double.PositiveInfinity) { for (int k = 0; k < Cities.Length; k++) //subtract minimum from each value { updated[i, k] -= min; } updatedbssf += min; } } for (int i = 0; i < Cities.Length; i++) //for each column { double min = double.PositiveInfinity; for (int k = 0; k < Cities.Length; k++) //get minimum for each column { if (updated[k, i] < min) { min = updated[k, i]; } } if (min != 0 && min != double.PositiveInfinity) { for (int k = 0; k < Cities.Length; k++) //subtract minimum from each value { updated[k, i] -= min; } updatedbssf += min; } } Node newNode = new Node(updatedbssf, updated, node.getRoute()); newNode.setNum(node.getNum()); return(newNode); }
/// <summary> /// performs a Branch and Bound search of the state space of partial tours /// stops when time limit expires and uses BSSF as solution /// </summary> /// <returns>results array for GUI that contains three ints: cost of solution, time spent to find solution, number of solutions found during search (not counting initial BSSF estimate)</returns> public string[] bBSolveProblem() { string[] results = new string[3]; string[] origResults = defaultSolveProblem(); double origbssf = Convert.ToDouble(origResults[COST]); double[,] originalDistances = new double[Cities.Length, Cities.Length]; List <Node> todoNodes = new List <Node>(); int numSolutions = 0; int numChildStates = 0; int statesPruned = 0; int numBSSF = 0; int maxNumOfStates = 0; double bestSolution = origbssf; ArrayList routeSolution = new ArrayList(); for (int i = 0; i < Cities.Length; i++) //make original matrix from default route { for (int k = 0; k < Cities.Length; k++) { if (i == k) { originalDistances[i, k] = double.PositiveInfinity; } else { originalDistances[i, k] = Cities[i].costToGetTo(Cities[k]); } } } Stopwatch timer = new Stopwatch(); timer.Start(); routeSolution.Add(Cities[0]); Node startNode = new Node(0, originalDistances, routeSolution); //put nodes in queue todoNodes.Add(reduceMatrix(startNode)); while (todoNodes.Count > 0) //while the list is not empty { if (timer.Elapsed.TotalSeconds >= TIME_LIMIT) { break; } Node node = todoNodes[0]; //get first element if (node.getRoute().Count == Cities.Length) //if a leaf node { numSolutions++; TSPSolution sol = new TSPSolution(node.getRoute()); if (sol.costOfRoute() < bestSolution) //reset the best solution if it is lower { bestSolution = sol.costOfRoute(); routeSolution = node.getRoute(); numBSSF++; } } else //if not a leaf node { if (node.getbssf() <= bestSolution) //pruning not needed { for (int i = 1; i < Cities.Length; i++) { if (node.getMatrix()[node.getNum(), i] != double.PositiveInfinity) { todoNodes.Add(getPartialRoute(node, node.getNum(), i)); numChildStates++; } } } else { statesPruned++; } } if (todoNodes.Count > maxNumOfStates) { maxNumOfStates = todoNodes.Count; } todoNodes.RemoveAt(0); //remove the node when finished calculating todoNodes.Sort(); //sorting based on priority } timer.Stop(); bssf = new TSPSolution(routeSolution); Console.WriteLine("Number of child states is " + numChildStates); Console.WriteLine("Number of states pruned is " + statesPruned); Console.WriteLine("Number of bssf updates is " + numBSSF); Console.WriteLine("Number of stored states is " + maxNumOfStates); results[COST] = bssf.costOfRoute().ToString(); // load results into array here, replacing these dummy values results[TIME] = timer.Elapsed.ToString(); results[COUNT] = numSolutions.ToString(); return(results); }