/** Calculate the wait time stats for boarding all (non-exact) frequency entries in this Ride. */ private Stats calcStatsForFreqs(TimeWindow window) { Stats stats = new Stats(); // all stats fields are initialized to zero stats.num = 0; // the total number of seconds that headway boarding is possible for (PatternRide patternRide : patternRides) { for (FrequencyEntry freq : patternRide.pattern.scheduledTimetable.frequencyEntries) { if (freq.exactTimes) { LOG.error("Exact times not yet supported in profile routing."); return null; } int overlap = window.overlap(freq.startTime, freq.endTime, freq.tripTimes.serviceCode); if (overlap > 0) { if (freq.headway > stats.max) stats.max = freq.headway; // weight the average of each headway by the number of seconds it is valid stats.avg += (freq.headway / 2) * overlap; stats.num += overlap; } } } if (stats.num == 0) return null; /* Some frequency entries were added to the stats. */ stats.avg /= stats.num; return stats; }
/** * Produce stats about boarding an initial Ride, which has no previous ride. This assumes arrival * times are uniformly distributed during the window. The Ride must contain some trips, and the * window must have a positive duration. */ public Stats calcStatsForBoarding(TimeWindow window) { Stats stats = new Stats(); stats.min = 0; // You can always arrive just before a train departs. List<Integer> departures = getSortedStoptimes(window, false); int last = window.from; double avgAccumulated = 0.0; /* All departures in the list are known to be running and within the window. */ for (int dep : departures) { int maxWait = dep - last; if (maxWait > stats.max) stats.max = maxWait; /* Weight the average of each interval by the number of seconds it contains. */ avgAccumulated += (maxWait / 2.0) * maxWait; stats.num += maxWait; last = dep; } if (stats.num > 0) { stats.avg = (int) (avgAccumulated / stats.num); } return stats; }