// Find the route with matching last station name and extend with new station name. public List <Route> SpawnMatchedRoute(List <Route> possibleRoutes, string prevStationName, Station stationToAdd, int duration) { List <Route> newRoutes = new List <Route>(); foreach (Route route in possibleRoutes) { if (route.LastStation.Station.StationName == prevStationName) { Route updatedRoute = (Route)route.Clone(); updatedRoute.AddStationToRoute(stationToAdd); updatedRoute.AddTotalDuration(duration); newRoutes.Add(updatedRoute); } } return(newRoutes); }
public List <Route> FindKShortestPath(string sourceStationName, string destStationName, int k) { List <Route> kRoutes = new List <Route>(); Queue <Station> stationQueue = new Queue <Station>(); HashSet <string> visitedStationName = new HashSet <string>(); Station curStation = Stations[sourceStationName]; stationQueue.Enqueue(curStation); List <Route> possibleRoutes = new List <Route>(); Route startRoute = new Route(); startRoute.AddStationToRoute(curStation); possibleRoutes.Add(startRoute); visitedStationName.Add(curStation.StationName); bool foundKRoutes = false; while (stationQueue.Count > 0 && !foundKRoutes) { curStation = stationQueue.Dequeue(); List <Route> updatedRoutes = new List <Route>(); foreach (StationEdge stationEdge in curStation.ConnectedStations) { Station connectedStation = stationEdge.Station; //valid route found. if (connectedStation.StationName == destStationName && kRoutes.Count < k) { List <Route> validRoutes = SpawnValidRoute(possibleRoutes, curStation.StationName, connectedStation, stationEdge.Duration); int availableRouteSlots = k - kRoutes.Count < validRoutes.Count ? k - kRoutes.Count : validRoutes.Count; for (int i = 0; i < availableRouteSlots; i++) { kRoutes.Add(validRoutes[i]); possibleRoutes.Remove(validRoutes[i]); } if (kRoutes.Count >= k) { foundKRoutes = true; break; } continue; } if (!visitedStationName.Contains(connectedStation.StationName)) { visitedStationName.Add(curStation.StationName); stationQueue.Enqueue(connectedStation); updatedRoutes.AddRange(SpawnMatchedRoute(possibleRoutes, curStation.StationName, connectedStation, stationEdge.Duration)); } } if (updatedRoutes.Count > 0) { updatedRoutes.AddRange(SpawnMismatchedRoute(possibleRoutes, curStation.StationName)); possibleRoutes = updatedRoutes; } } kRoutes = kRoutes.OrderBy(route => route.TotalDuration).ToList(); return(kRoutes); }