/// <summary> /// Makes states for all the nodes in the graph that aren't in state's route and stores them in a priority queue /// Time O(n^3) Space O(n^3) /// </summary> /// <param name="state">parentState. The state to expand</param> public void ExpandState(State parentState) { //if the state's bound >= bssf: increment prunedNodes & return if (parentState.bound > costOfBssf()) { prunedNodes++; return; } //If all the nodes in the graph are in the route (compare sizes): wrap up the route by traveling to the first node and checking the result against bssf. Update bssf if needed. if (parentState.route.Count >= cities.Count()) { //Time O(n) double costToReturn = TravelInMatrix(parentState.matrix, parentState.lastCity, 0); if (!double.IsPositiveInfinity(costToReturn)) { parentState.bound += costToReturn; parentState.route.Add(cities[0]); if (parentState.bound < costOfBssf()) { bssf = new ProblemAndSolver.TSPSolution(parentState.route); numUpdates++; } } return; } //Else: //For each node in the graph that isn't in the route: time O(n^3) space O(n^3) for (int i = 0; i < cities.Count(); i++) { City city = cities[i]; if (double.IsPositiveInfinity(cities[parentState.lastCity].costToGetTo(city)) || parentState.route.Contains(i)) { continue; } //Copy the parent node state //Time O(n^2) size O(n^2) State childState = parentState.Copy(); nodesCreated++; childState.route.Add(cities[i]); childState.lastCity = i; //Travel in the matrix to the new node and set the appropriate cells to infinity (TravelInMatrix). time O(n) double travelCost = TravelInMatrix(childState.matrix, parentState.lastCity, i); if (double.IsPositiveInfinity(travelCost)) { continue; } childState.bound += travelCost; //Reduce the matrix and update the bound. time O(n^2) childState.bound += ReduceMatrix(childState.matrix); //If the bound is lower than bssf's: if (childState.bound < costOfBssf()) { //add the state to the priority queue. time O(logn) queue.Insert(childState); } else { prunedNodes++; } } }