/// <summary> /// Gets the best stop profile. /// </summary> public static int GetBest(this ProfileSearch algorithm, IReadOnlyList <StopProfile> profiles, uint maxTransferCostInSeconds) { uint bestTime = uint.MaxValue; int bestIndex = int.MaxValue; for (var i = 0; i < profiles.Count; i++) { if (profiles[i].Seconds != Constants.NoSeconds) { uint time = ((uint)i * maxTransferCostInSeconds) + profiles[i].Seconds; if (time < bestTime) { bestIndex = i; bestTime = time; } } } if (bestIndex == int.MaxValue) { throw new ArgumentOutOfRangeException("profile", "Profile collection doesn't contain any valid entries."); } return(bestIndex); }
/// <summary> /// Gets the profile that precedes the given one on a transit route. /// </summary> public static StopProfile GetPreceding(this ProfileSearch algorithm, IReadOnlyList <StopProfile> profiles, int i, out uint stopId, out int tranfers) { var profile = profiles[i]; if (profile.IsEmpty) { // no previous connection, no preceding profile. stopId = Constants.NoStopId; tranfers = Constants.NoTransfers; return(StopProfile.Empty); } // get preceding connection. var connections = algorithm.Db.GetConnectionsEnumerator(Data.DefaultSorting.DepartureTime); connections.MoveTo(profile.PreviousConnectionId); stopId = connections.DepartureStop; var departureTime = connections.DepartureTime; var profileId = connections.TripId; // get candidates and search best match. var profileCandidates = algorithm.GetStopProfiles(connections.DepartureStop); // find exact match, same trip, no transfer. StopProfile candidate; if (i < profileCandidates.Count) { // check at same transfer count. candidate = profileCandidates[i]; connections.MoveTo(candidate.PreviousConnectionId); if (connections.TripId == profileId) { tranfers = i; return(candidate); } } // not an exact match, return the one with the least transfers. for (var c = 0; c < i; c++) { candidate = profileCandidates[c]; if (candidate.Seconds < 0) { // empty. continue; } if (candidate.Seconds < departureTime) { tranfers = c; return(candidate); } } tranfers = Constants.NoTransfers; stopId = Constants.NoStopId; return(StopProfile.Empty); }
/// <summary> /// Gets the profile that precedes the given one on a transit route. /// </summary> public static int GetPreceding(this IReadOnlyList <StopProfile> profiles, ProfileSearch search, int i) { var profile = profiles[i]; if (profile.IsEmpty) { // no previous connection, no preceding profile. return(-1); } // get preceding connection. var connections = search.Db.GetConnectionsEnumerator(Data.DefaultSorting.DepartureTime); connections.MoveTo(profile.PreviousConnectionId); var stopId = connections.DepartureStop; var departureTime = connections.DepartureTime; var profileId = connections.TripId; // get candidates and search best match. var profileCandidates = search.GetStopProfiles(connections.DepartureStop); // find exact match, same trip, no transfer. StopProfile candidate; if (i < profileCandidates.Count) { // check at same transfer count. candidate = profileCandidates[i]; connections.MoveTo(candidate.PreviousConnectionId); if (connections.TripId == profileId) { return(i); } } // not an exact match, return the one with the least transfers. for (var c = 0; c < i; c++) { candidate = profileCandidates[c]; if (candidate.Seconds < 0) { // empty. continue; } if (candidate.Seconds < departureTime) { return(c); } } return(-1); }
/// <summary> /// Creates a new profile search route builder. /// </summary> /// <param name="search">The search algorithm.</param> /// <param name="intermediateStops">True when the intermediate stops need to be added.</param> public ProfileSearchRouteBuilder(ProfileSearch search, bool intermediateStops = true) { _search = search; _intermediateStops = intermediateStops; }