/// <summary> /// This function returns an object of the class <see cref="Route"/> if /// a route exists bewteen the provided locations. Otherwise, NULL is returned. /// </summary> /// <returns>A <see cref="Route"/> An object describing the shortest path from the start to end location</returns> /// <param name="startLoc">The start location in the desired route.</param> /// <param name="endLoc">The destination location of the desired route.</param> /// <para> /// This function uses and A* search to find the shortest route between the two given locations /// on the network. /// </para> protected Route CalculateRoute(Location startLoc, Location endLoc) { if (startLoc == null || endLoc == null) { return(null); } // Already at the location Route retRoute; if (startLoc.LocID == endLoc.LocID) { retRoute = new Route(); return(retRoute); } Location start; Location goal; netLocs.TryGetValue(startLoc.LocID, out start); netLocs.TryGetValue(endLoc.LocID, out goal); if (start == null || goal == null) { return(null); } // Make Lists for search List <SearchNode> openList = new List <SearchNode>(); List <SearchNode> closedList = new List <SearchNode>(); // Place starting node in open list list openList.Add(new SearchNode(start, null, 0, calculateDistance(start, goal))); SearchNode curSearchNode; SearchNode goalSearchNode = null; while (true) { //Exit upon empty openList if (openList.Count == 0) { break; } // Sort openList and choose lowest F openList.Sort(); // Take lowest F in openList and move to closedList curSearchNode = openList[0]; openList.RemoveAt(0); closedList.Add(curSearchNode); // Check for goal node if (curSearchNode.Equals(goal)) { goalSearchNode = curSearchNode; break; } // Add connected nodes to open list if not already listed in closedList, update if on openList foreach (Location location in curSearchNode.location) { bool found = false; // Ignore node if on closed list foreach (SearchNode searchNode in closedList) { if (searchNode.Equals(location)) { found = true; break; } } if (found) { continue; } // Potentially update SearchNode if it is on the openList and the costToNode is less foreach (SearchNode searchNode in openList) { if (searchNode.Equals(location)) { // Compare costToNode, update parent if node has lower cost float newCostToNode = curSearchNode.costToNode + calculateDistance(curSearchNode.location, location); if (newCostToNode < searchNode.costToNode) { searchNode.parentSearchNode = curSearchNode; searchNode.costToNode = newCostToNode; } found = true; break; } } if (found) { continue; } openList.Add(new SearchNode(location, curSearchNode, curSearchNode.costToNode + calculateDistance(curSearchNode.location, location), calculateDistance(location, goal))); } } if (goalSearchNode == null) { return(null); } // Make a route if the final NodeWrap, a route from start to goal, was found retRoute = new Route(); SearchNode parent = goalSearchNode; // Create route from goal to start while (parent != null) { retRoute.AddLocation(parent.location); parent = parent.parentSearchNode; } // Reverse route becuase it was created from goal to start then lock it retRoute.Reverse(); retRoute.Lock(); return(retRoute); }