package org.opentripplanner.analyst.scenario;
import org.opentripplanner.profile.RaptorWorkerTimetable;
import java.util.stream.IntStream;
/**
* A transfer rule allows specification, on a per-stop basis, of a different assumption for transfer
* boarding times than that used in the graph-wide search.
*/
public class TransferRule extends Modification {
private static final long serialVersionUID = 1L;
/** The boarding assumption to use for matched transfers */
public RaptorWorkerTimetable.BoardingAssumption assumption;
/** From GTFS modes; note constants in Route */
public int[] fromMode;
/** To GTFS modes */
public int[] toMode;
/** Stop label; if null will be applied to all stops. */
public String stop;
/**
* The transfer time in seconds; only applied if assumption == FIXED.
* If specified and assumption == FIXED, this transfer will always take this amount of time,
* so this should be the time difference between vehicles. No provision is made for additional
* slack for walking, etc., so be sure to allow enough time to be reasonable for transferring
* at this stop.
*/
public Integer transferTimeSeconds;
/**
* The proportion of the headway to apply when transferring, when assumption = PROPORTION.
*
* So, for example, if you set this to 0.33, and the buses run at thirty-minute frequency,
* the wait time will be ten minutes.
*
* There is theoretical justification for setting this below 0.5 when the frequency-based network
* under consideration will eventually have a schedule, even if transfers have not been and will
* not be explicitly synchronized. Suppose all possible transfer times as a
* proportion of headway are drawn from a distribution centered on 0.5. Now consider that there are
* likely several competing options for each trip (how many depends on how well-connected the
* network is). The trip planner will pick the best one, and the best one is likely to have a
* transfer time of less than half headway (because transfer time is correlated with total trip
* time, the objective function). Thus the average transfer time in optimal trips is less than
* half headway.
*
* The same is not true of the initial wait, assuming the user gets to their the same way each time
* they go there (which is probably true of most people who do not write transportation analytics
* software for a living). If you leave your origin at random and do the same thing every day,
* you will experience, on average, half headway waits. However, the schedule is fixed (the fact
* that you're hitting a slightly different part of it each day notwithstanding), so it is reasonable
* to optimize the choice of which sequence of routes to take, just not which to take on a given day.
*/
public Double waitProportion;
@Override public String getType() {
return "transfer-rule";
}
public boolean matches (RaptorWorkerTimetable from, RaptorWorkerTimetable to) {
if (fromMode != null && !IntStream.of(fromMode).anyMatch(m -> m == from.mode))
return false;
if (toMode != null && !IntStream.of(toMode).anyMatch(m -> m == to.mode))
return false;
return true;
}
}