/// <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]; int count = 0; Stopwatch timer = new Stopwatch(); PriorityQueue queue = new PriorityQueue(); timer.Start(); greedySolveProblem(); queue.Insert(new PartialPath(CalculateInitialMatrix(), Cities)); /* While there are still partial paths on the queue, * the best one is popped off and its children are generated. * Those that are better than the bssf are added to the queue. */ while (timer.Elapsed.TotalMilliseconds < time_limit && !queue.Empty()) { PartialPath currentNode = queue.DeleteMin(); if (currentNode.FullPath && currentNode.CompletePath) { TSPSolution potentialSolution = new TSPSolution(currentNode.Path); if (potentialSolution.costOfRoute() < costOfBssf()) { bssf = potentialSolution; count++; } } else if (currentNode.LowerBound < costOfBssf()) { GenerateChildren(currentNode, queue); } } timer.Stop(); results[COST] = costOfBssf().ToString(); results[TIME] = timer.Elapsed.ToString(); results[COUNT] = count.ToString(); Console.WriteLine("Branch & Bound Size: " + Cities.Length + " Random: " + Seed + " Path: " + costOfBssf().ToString() + " Time: " + timer.Elapsed.ToString()); return(results); }
public int BBSolution(Stopwatch timer) { // Stats int maxStates = 0; int totalStates = 0; int prunedStates = 0; int count = 0; PriorityQueue q = new PriorityQueue(); SubProblem initialSubProblem = new SubProblem( this.CalculateCostMatrix(), this.Cities.Length, 0, new List <int>() ); initialSubProblem.path.Add(0); q.Add(initialSubProblem); while (!q.Empty() && timer.ElapsedMilliseconds < this.time_limit) { // Update statistics if (q.Size() > maxStates) { maxStates = q.Size(); } ++totalStates; SubProblem subProblem = q.Pop(); if (subProblem.path.Count == this.Cities.Length && subProblem.path[subProblem.GetCurrentCityIndex()] != 0) { // The subproblem is a valid solution! this.bssf = new TSPSolution(PathToRoute(subProblem.path)); count++; } else { if (subProblem.HasMorePaths()) { for (int col = 0; col < this.Cities.Length; ++col) { if (subProblem.reducedMatrix[subProblem.GetCurrentCityIndex(), col] != double.PositiveInfinity) { if (subProblem.reducedMatrix[subProblem.GetCurrentCityIndex(), col] + subProblem.lowerBound < this.costOfBssf()) { List <int> pathClone = new List <int>(subProblem.path); SubProblem newProblem = new SubProblem( (double[, ])subProblem.reducedMatrix.Clone(), this.Cities.Length, subProblem.lowerBound, pathClone ); newProblem.path.Add(col); newProblem.BlockPaths( subProblem.GetCurrentCityIndex(), newProblem.GetCurrentCityIndex() ); newProblem.ReduceCostMatrix(); q.Add(newProblem); } else { ++prunedStates; } } } } } } // Print stats Console.WriteLine("Max # of states: {0}", maxStates); Console.WriteLine("Total # number of states: {0}", totalStates); Console.WriteLine("# of states pruned: {0}", prunedStates); return(count); }