def test_pareto_optimality2(self): node_profile = NodeProfileSimple() pt2 = LabelTimeSimple(departure_time=10, arrival_time_target=35) self.assertTrue(node_profile.update_pareto_optimal_tuples(pt2)) pt1 = LabelTimeSimple(departure_time=5, arrival_time_target=35) self.assertFalse(node_profile.update_pareto_optimal_tuples(pt1)) self.assertEquals(len(node_profile.get_final_optimal_labels()), 1)
def test_walk_duration(self): node_profile = NodeProfileSimple(walk_to_target_duration=27) self.assertEqual(27, node_profile.get_walk_to_target_duration()) pt1 = LabelTimeSimple(departure_time=5, arrival_time_target=35) self.assertFalse(node_profile.update_pareto_optimal_tuples(pt1)) pt2 = LabelTimeSimple(departure_time=10, arrival_time_target=35) self.assertTrue(node_profile.update_pareto_optimal_tuples(pt2))
def get_time_profile_analyzer(self, max_n_boardings=None): """ Parameters ---------- max_n_boardings: int The maximum number of boardings allowed for the labels used to construct the "temporal distance profile" Returns ------- analyzer: NodeProfileAnalyzerTime """ if max_n_boardings is None: max_n_boardings = self.max_trip_n_boardings() # compute only if not yet computed if not max_n_boardings in self._n_boardings_to_simple_time_analyzers: if max_n_boardings == 0: valids = [] else: candidate_labels = [ LabelTimeSimple(label.departure_time, label.arrival_time_target) for label in self._node_profile_final_labels if ((self.start_time_dep <= label.departure_time) and label.n_boardings <= max_n_boardings) ] valids = compute_pareto_front(candidate_labels) valids.sort(key=lambda label: -label.departure_time) profile = NodeProfileSimple(self._walk_to_target_duration) for valid in valids: profile.update_pareto_optimal_tuples(valid) npat = NodeProfileAnalyzerTime.from_profile( profile, self.start_time_dep, self.end_time_dep) self._n_boardings_to_simple_time_analyzers[max_n_boardings] = npat return self._n_boardings_to_simple_time_analyzers[max_n_boardings]
def test_identity_profile(self): identity_profile = NodeProfileSimple(0) self.assertFalse( identity_profile.update_pareto_optimal_tuples( LabelTimeSimple(10, 10))) self.assertEqual( 10, identity_profile.evaluate_earliest_arrival_time_at_target(10, 0))
def plot_plain_profile(): profile = NodeProfileSimple(walk_to_target_duration=10 * 60) for label in labels_t_dep_dur_b: profile.update_pareto_optimal_tuples( LabelTimeSimple(departure_time=label[0] * 60, arrival_time_target=(label[0] + label[1]) * 60)) analyzer = NodeProfileAnalyzerTime(profile, 0 * 60, 20 * 60) fig = plt.figure(figsize=(5.5, 3.5)) ax1 = plt.subplot(gs[:, :4]) analyzer.plot_temporal_distance_profile(format_string="%M", plot_journeys=True, lw=3, ax=ax1, plot_tdist_stats=True, alpha=0.15, plot_trip_stats=False, duration_divider=60.0) ax2 = plt.subplot(gs[:, 4:]) # ax2 = plt.subplot2grid(subplot_grid, (0, 4), colspan=2, rowspan=1) fig = analyzer.plot_temporal_distance_pdf_horizontal(use_minutes=True, ax=ax2, legend_font_size=9) ax2.set_ylabel("") ax2.set_yticks([]) ax1.set_ylim(0, 11.5) ax2.set_ylim(0, 11.5) ax2.set_xlim(0, 0.3) ax2.set_yticklabels(["" for _ in ax2.get_yticks()]) ax2.set_xticks([0.1, 0.2, 0.3]) ax1.set_xlabel("Departure time $t_{\\text{dep}}$ (min)") ax1.set_ylabel("Temporal distance $\\tau$ (min)") handles, labels = ax1.get_legend_handles_labels() ax1.legend(handles, labels, loc="best", fancybox=True, ncol=2, shadow=False, prop={'size': 9}) for _ax, letter in zip([ax1, ax2], "AB"): _ax.text(0.04, 0.98, "\\textbf{" + letter + "}", horizontalalignment="left", verticalalignment="top", transform=_ax.transAxes, fontsize=15, color="black") fig.savefig(settings.FIGS_DIRECTORY + "schematic_temporal_distance.pdf")
def test_temporal_distances_no_transit_trips_within_range(self): pairs = [ LabelTimeSimple(departure_time=11, arrival_time_target=12), ] profile = NodeProfileSimple(walk_to_target_duration=5) for pair in pairs: profile.update_pareto_optimal_tuples(pair) analyzer = NodeProfileAnalyzerTime.from_profile(profile, 0, 10) self.assertAlmostEqual(5, analyzer.max_temporal_distance()) self.assertAlmostEqual(2, analyzer.min_temporal_distance()) self.assertAlmostEqual((7 * 5 + 3 * (5 + 2) / 2.) / 10.0, analyzer.mean_temporal_distance()) self.assertAlmostEqual(5, analyzer.median_temporal_distance())
def test_temporal_distance_statistics_with_walk2(self): pt1 = LabelTimeSimple(departure_time=10, arrival_time_target=30) profile = NodeProfileSimple(25) profile.update_pareto_optimal_tuples(pt1) analyzer = NodeProfileAnalyzerTime.from_profile(profile, 0, 10) # analyzer.plot_temporal_distance_profile() # plt.show() self.assertAlmostEqual( 25, analyzer.max_temporal_distance()) # 1 -wait-> 2 -travel->4 self.assertAlmostEqual(20, analyzer.min_temporal_distance()) self.assertAlmostEqual((7.5 * 25 + 2.5 * 20) / 10.0, analyzer.mean_temporal_distance()) self.assertAlmostEqual(25, analyzer.median_temporal_distance())
def test_trip_duration_statistics_simple(self): pairs = [ LabelTimeSimple(1.0, 2.0), LabelTimeSimple(2.0, 4.0), LabelTimeSimple(4.0, 5.0) ] profile = NodeProfileSimple() for pair in pairs: profile.update_pareto_optimal_tuples(pair) analyzer = NodeProfileAnalyzerTime.from_profile(profile, 0, 100) self.assertAlmostEqual(2, analyzer.max_trip_duration()) self.assertAlmostEqual(1, analyzer.min_trip_duration()) self.assertAlmostEqual(4 / 3.0, analyzer.mean_trip_duration()) self.assertAlmostEqual(1, analyzer.median_trip_duration())
def test_time_offset(self): max_distances = [] for offset in [0, 10, 100, 1000]: labels = [ LabelTimeSimple(departure_time=7248 + offset, arrival_time_target=14160 + offset), ] profile = NodeProfileSimple(walk_to_target_duration=float('inf')) for label in labels: profile.update_pareto_optimal_tuples(label) analyzer = NodeProfileAnalyzerTime.from_profile( profile, 0 + offset, 7200 + offset) max_distances.append(analyzer.max_temporal_distance()) max_distances = numpy.array(max_distances) assert ((max_distances == max_distances[0]).all())
def test_temporal_distance_statistics_with_walk(self): pt1 = LabelTimeSimple(departure_time=1, arrival_time_target=2) pt2 = LabelTimeSimple( departure_time=4, arrival_time_target=5) # not taken into account by the analyzer profile = NodeProfileSimple(1.5) assert isinstance(pt1, LabelTimeSimple), type(pt1) profile.update_pareto_optimal_tuples(pt1) profile.update_pareto_optimal_tuples(pt2) analyzer = NodeProfileAnalyzerTime.from_profile(profile, 0, 3) self.assertAlmostEqual( 1.5, analyzer.max_temporal_distance()) # 1 -wait-> 2 -travel->4 self.assertAlmostEqual(1, analyzer.min_temporal_distance()) self.assertAlmostEqual((2.5 * 1.5 + 0.5 * 1.25) / 3., analyzer.mean_temporal_distance()) self.assertAlmostEqual(1.5, analyzer.median_temporal_distance())
def test_temporal_distance_statistics(self): pairs = [ LabelTimeSimple(1, 2), LabelTimeSimple(2, 4), LabelTimeSimple(4, 5) ] profile = NodeProfileSimple() for pair in pairs: profile.update_pareto_optimal_tuples(pair) analyzer = NodeProfileAnalyzerTime.from_profile(profile, 0, 3) self.assertAlmostEqual( 4 - 1, analyzer.max_temporal_distance()) # 1 -wait-> 2 -travel->4 self.assertAlmostEqual(1, analyzer.min_temporal_distance()) self.assertAlmostEqual((1.5 * 1 + 2.5 * 1 + 2.5 * 1) / 3., analyzer.mean_temporal_distance()) self.assertAlmostEqual(2.25, analyzer.median_temporal_distance())
def test_earliest_arrival_time(self): node_profile = NodeProfileSimple() self.assertEquals( float("inf"), node_profile.evaluate_earliest_arrival_time_at_target(0, 0)) node_profile.update_pareto_optimal_tuples( LabelTimeSimple(departure_time=1, arrival_time_target=1)) self.assertEquals( 1, node_profile.evaluate_earliest_arrival_time_at_target(0, 0)) node_profile.update_pareto_optimal_tuples( LabelTimeSimple(departure_time=3, arrival_time_target=4)) self.assertEquals( 4, node_profile.evaluate_earliest_arrival_time_at_target(2, 0))
def test_pareto_optimality_with_transfers(self): node_profile = NodeProfileSimple( label_class=LabelTimeWithBoardingsCount) pt3 = LabelTimeWithBoardingsCount(departure_time=5, arrival_time_target=35, n_boardings=0, first_leg_is_walk=True) pt2 = LabelTimeWithBoardingsCount(departure_time=5, arrival_time_target=35, n_boardings=1, first_leg_is_walk=True) pt1 = LabelTimeWithBoardingsCount(departure_time=5, arrival_time_target=35, n_boardings=2, first_leg_is_walk=True) self.assertTrue(node_profile.update_pareto_optimal_tuples(pt1)) self.assertTrue(node_profile.update_pareto_optimal_tuples(pt2)) self.assertTrue(node_profile.update_pareto_optimal_tuples(pt3)) self.assertEqual(1, len(node_profile.get_final_optimal_labels()))
def test_temporal_distance_pdf_with_walk(self): profile = NodeProfileSimple(25) pt1 = LabelTimeSimple(10, 30) profile.update_pareto_optimal_tuples(pt1) analyzer = NodeProfileAnalyzerTime.from_profile(profile, 0, 10) self.assertEqual( len(analyzer.profile_block_analyzer._temporal_distance_pdf()), 3) split_points, densities, delta_peaks = analyzer.profile_block_analyzer._temporal_distance_pdf( ) self.assertEqual(len(split_points), 2) self.assertEqual(split_points[0], 20) self.assertEqual(split_points[1], 25) self.assertEqual(len(densities), 1) self.assertEqual(densities[0], 0.1) self.assertIn(25, delta_peaks) self.assertEqual(delta_peaks[25], 0.5)
def test_trip_duration_statistics_empty_profile(self): profile = NodeProfileSimple() analyzer = NodeProfileAnalyzerTime.from_profile(profile, 0, 10) self.assertEqual(float('inf'), analyzer.max_trip_duration()) self.assertEqual(float('inf'), analyzer.min_trip_duration()) self.assertEqual(float('inf'), analyzer.mean_trip_duration()) self.assertEqual(float('inf'), analyzer.median_trip_duration()) self.assertEqual(float('inf'), analyzer.max_temporal_distance()) self.assertEqual(float('inf'), analyzer.min_temporal_distance()) self.assertEqual(float('inf'), analyzer.mean_temporal_distance()) self.assertEqual(float('inf'), analyzer.median_temporal_distance())
def test_pareto_optimality(self): node_profile = NodeProfileSimple() pair1 = LabelTimeSimple(departure_time=1, arrival_time_target=2) self.assertTrue(node_profile.update_pareto_optimal_tuples(pair1)) pair2 = LabelTimeSimple(departure_time=2, arrival_time_target=3) self.assertTrue(node_profile.update_pareto_optimal_tuples(pair2)) self.assertEquals(2, len(node_profile._labels)) pair3 = LabelTimeSimple(departure_time=1, arrival_time_target=1) self.assertTrue(node_profile.update_pareto_optimal_tuples(pair3)) self.assertEquals(2, len(node_profile._labels), msg=str(node_profile.get_final_optimal_labels())) pair4 = LabelTimeSimple(departure_time=1, arrival_time_target=2) self.assertFalse(node_profile.update_pareto_optimal_tuples(pair4))
def test_all_plots(self): profile = NodeProfileSimple(25) pt1 = LabelTimeSimple(departure_time=10, arrival_time_target=30) profile.update_pareto_optimal_tuples(pt1) analyzer = NodeProfileAnalyzerTime.from_profile(profile, 0, 10) analyzer.plot_temporal_distance_profile(plot_tdist_stats=True) analyzer.plot_temporal_distance_cdf() analyzer.plot_temporal_distance_pdf() plt.show() profile = NodeProfileSimple() profile.update_pareto_optimal_tuples( LabelTimeSimple(departure_time=2 * 60, arrival_time_target=11 * 60)) profile.update_pareto_optimal_tuples( LabelTimeSimple(departure_time=20 * 60, arrival_time_target=25 * 60)) profile.update_pareto_optimal_tuples( LabelTimeSimple(departure_time=40 * 60, arrival_time_target=45 * 60)) analyzer = NodeProfileAnalyzerTime.from_profile(profile, 0, 60 * 60) analyzer.plot_temporal_distance_profile() analyzer.plot_temporal_distance_cdf() analyzer.plot_temporal_distance_pdf() profile = NodeProfileSimple() profile.update_pareto_optimal_tuples( LabelTimeSimple(departure_time=2 * 60, arrival_time_target=3 * 60)) profile.update_pareto_optimal_tuples( LabelTimeSimple(departure_time=4 * 60, arrival_time_target=25 * 60)) analyzer = NodeProfileAnalyzerTime.from_profile(profile, 0, 5 * 60) analyzer.plot_temporal_distance_profile() analyzer.plot_temporal_distance_cdf() analyzer.plot_temporal_distance_pdf() pt1 = LabelTimeSimple(departure_time=1, arrival_time_target=2) pt2 = LabelTimeSimple( departure_time=4, arrival_time_target=5) # not taken into account by the analyzer profile = NodeProfileSimple(1.5) profile.update_pareto_optimal_tuples(pt1) profile.update_pareto_optimal_tuples(pt2) analyzer = NodeProfileAnalyzerTime.from_profile(profile, 0, 3) analyzer.plot_temporal_distance_profile() analyzer.plot_temporal_distance_cdf() plt.show()
def __init__(self, transit_events, target_stop, start_time=None, end_time=None, transfer_margin=0, walk_network=None, walk_speed=1.5, verbose=False): """ Parameters ---------- transit_events: list[Connection] events are assumed to be ordered in DECREASING departure_time (!) target_stop: int index of the target stop start_time : int, optional start time in unixtime seconds end_time: int, optional end time in unixtime seconds (no connections will be scanned after this time) transfer_margin: int, optional required extra margin required for transfers in seconds walk_speed: float, optional walking speed between stops in meters / second. walk_network: networkx.Graph, optional each edge should have the walking distance as a data attribute ("distance_shape") expressed in meters verbose: boolean, optional whether to print out progress """ AbstractRoutingAlgorithm.__init__(self) self._target = target_stop self._connections = transit_events if start_time is None: start_time = transit_events[-1].departure_time if end_time is None: end_time = transit_events[0].departure_time self._start_time = start_time self._end_time = end_time self._transfer_margin = transfer_margin if walk_network is None: walk_network = networkx.Graph() self._walk_network = walk_network self._walk_speed = float(walk_speed) self._verbose = verbose # algorithm internals # trip flags: self.__trip_min_arrival_time = defaultdict(lambda: float("inf")) # initialize stop_profiles self._stop_profiles = defaultdict(lambda: NodeProfileSimple()) # initialize stop_profiles for target stop, and its neighbors self._stop_profiles[self._target] = NodeProfileSimple(0) if target_stop in walk_network.nodes(): for target_neighbor in walk_network.neighbors(target_stop): edge_data = walk_network.get_edge_data(target_neighbor, target_stop) walk_duration = edge_data["d_walk"] / self._walk_speed self._stop_profiles[target_neighbor] = NodeProfileSimple( walk_duration)