def test_transfer_connections_do_not_affect_transfers3(self): walk_speed = 1 target_stop = 0 start_time = 0 end_time = 60 transfer_margin = 0 transit_connections = [ Connection(3, 0, 10, 11, "t1", 1), Connection(2, 1, 5, 6, "t2", 1), Connection(7, 2, 3, 4, "tX", 1), Connection(5, 6, 2, 3, "--", 1), Connection(4, 3, 0, 1, "t3", 1) ] walk_network = networkx.Graph() walk_network.add_edge(7, 3, d_walk=1) walk_network.add_edge(1, 0, d_walk=1) walk_network.add_edge(5, 3, d_walk=1) csa_profiler = MultiObjectivePseudoCSAProfiler( transit_connections, target_stop, start_time, end_time, transfer_margin, walk_network, walk_speed) csa_profiler.run() profiles = csa_profiler.stop_profiles print(profiles[4].get_final_optimal_labels()[0]) optimal_labels = profiles[4].get_final_optimal_labels() assert (len(optimal_labels) == 2) boardings_to_arr_time = {} for label in optimal_labels: boardings_to_arr_time[ label.n_boardings] = label.arrival_time_target self.assertEqual(boardings_to_arr_time[2], 11) self.assertEqual(boardings_to_arr_time[3], 7)
def test_dominates(self): leg1 = Connection(departure_stop=0, arrival_stop=1, departure_time=0, arrival_time=1, trip_id="tripI", seq=1, is_walk=False) leg2 = Connection(departure_stop=1, arrival_stop=2, departure_time=1, arrival_time=2, trip_id="tripI", seq=1, is_walk=False) leg3 = Connection(departure_stop=1, arrival_stop=2, departure_time=1, arrival_time=3, trip_id="tripI", seq=1, is_walk=False) journey1 = ForwardJourney(legs=[leg1]) journey2 = ForwardJourney(legs=[leg2]) journey12 = ForwardJourney(legs=[leg1, leg2]) journey13 = ForwardJourney(legs=[leg1, leg3]) self.assertTrue(journey12.dominates(journey13)) self.assertFalse(journey1.dominates(journey2)) self.assertTrue( journey1.dominates(journey1, consider_time=False, consider_boardings=False))
def test_add_leg(self): journey = ForwardJourney() leg1 = Connection(departure_stop=0, arrival_stop=1, departure_time=0, arrival_time=1, trip_id="tripI", seq=1, is_walk=False) journey.add_leg(leg1) self.assertEqual(len(journey.legs), 1) self.assertEqual(journey.departure_time, leg1.departure_time) self.assertEqual(journey.arrival_time, leg1.arrival_time) self.assertEqual(journey.n_boardings, 1) leg2 = Connection(departure_stop=1, arrival_stop=2, departure_time=1, arrival_time=2, trip_id="tripI", seq=1, is_walk=False) journey.add_leg(leg2) self.assertEqual(len(journey.legs), 2) self.assertEqual(journey.departure_time, leg1.departure_time) self.assertEqual(journey.arrival_time, leg2.arrival_time) self.assertEqual(journey.n_boardings, 1)
def test_reset(self): walk_speed = 1 target_stop = 2 start_time = 0 end_time = 60 transfer_margin = 0 transit_connections = [ Connection(0, 1, 40, 50, "trip_1", 1), Connection(1, 2, 55, 60, "trip_1", 1), Connection(3, 1, 40, 60, "trip_2", 1) ] csa_profile = MultiObjectivePseudoCSAProfiler(transit_connections, target_stop, start_time, end_time, transfer_margin, networkx.Graph(), walk_speed) csa_profile.run() nodes = [0, 1, 2, 3] label_counts = [1, 1, 0, 0] for node, count in zip(nodes, label_counts): n_labels = len( csa_profile.stop_profiles[node].get_final_optimal_labels()) self.assertEqual(n_labels, count) target_stops = [1] csa_profile.reset(target_stops) csa_profile.run() label_counts = [1, 0, 0, 1] for node, count in zip(nodes, label_counts): n_labels = len( csa_profile.stop_profiles[node].get_final_optimal_labels()) self.assertEqual(n_labels, count)
def test_transfer_margin_with_walk(self): walk_speed = 1 target_stop = 3 start_time = 0 end_time = 2000 transit_connections = [ Connection(0, 1, 1000, 1010, "trip__2", 1), Connection(0, 1, 1010, 1020, "trip__1", 1), Connection(0, 1, 1020, 1030, "trip_0", 1), Connection(0, 1, 1000, 1010, "trip_1", 1), Connection(0, 1, 1010, 1020, "trip_2", 1), Connection(0, 1, 1020, 1030, "trip_3", 1), Connection(0, 1, 1030, 1040, "trip_4", 1), Connection(2, 3, 1060, 1070, "trip_6", 1), ] walk_network = networkx.Graph() walk_network.add_edge(1, 2, d_walk=5) transfer_margins = [10, 20, 30, 40, 0] journey_dep_times = [1030, 1020, 1010, 1000, 1030] for transfer_margin, dep_time in zip(transfer_margins, journey_dep_times): csa_profile = MultiObjectivePseudoCSAProfiler( transit_connections, target_stop, start_time, end_time, transfer_margin, walk_network, walk_speed) csa_profile.run() profile = csa_profile.stop_profiles[0] self.assertEqual(len(profile.get_final_optimal_labels()), 1, "transfer_margin=" + str(transfer_margin)) label = profile.get_final_optimal_labels()[0] self.assertEqual(label.departure_time, dep_time, "transfer_margin=" + str(transfer_margin))
def test_pareto_optimality(self): event_list_raw_data = [(0, 2, 0, 10, "trip_1", 1), (0, 1, 2, 5, "trip_2", 1), (1, 2, 5, 8, "trip_3", 1)] transit_connections = list( map(lambda el: Connection(*el), event_list_raw_data)) walk_speed = 2 source_stop = 0 target_stop = 2 transfer_margin = 0 start_time = 0 end_time = 20 walk_network = networkx.Graph() csa_profile = MultiObjectivePseudoCSAProfiler(transit_connections, target_stop, start_time, end_time, transfer_margin, walk_network, walk_speed) csa_profile.run() source_profile = csa_profile.stop_profiles[source_stop] self.assertEqual( min_arrival_time_target(source_profile.evaluate(0, 0)), 8) found_labels = source_profile.get_final_optimal_labels() labels_should_be = list() labels_should_be.append( LabelTimeWithBoardingsCount(0, 10, n_boardings=1, first_leg_is_walk=False)) labels_should_be.append( LabelTimeWithBoardingsCount(2, 8, n_boardings=2, first_leg_is_walk=False)) self._assert_label_sets_equal(found_labels, labels_should_be)
def test_no_multiple_walks(self): event_list_raw_data = [(0, 1, 0, 1, "trip_1", 1), (1, 0, 0, 1, "trip_2", 1), (0, 1, 2, 3, "trip_3", 1), (1, 0, 2, 3, "trip_4", 1), (0, 1, 4, 5, "trip_5", 1), (1, 0, 4, 5, "trip_6", 1), (1, 2, 5, 6, "trip_7", 1), (2, 1, 5, 6, "trip_8", 1), (1, 2, 2, 3, "trip_7", 2), (2, 1, 2, 3, "trip_8", 2)] transit_connections = list( map(lambda el: Connection(*el), event_list_raw_data)) walk_network = networkx.Graph() walk_network.add_edge(0, 1, d_walk=1) walk_network.add_edge(2, 1, d_walk=1) walk_speed = 10 transfer_margin = 0 start_time = 0 end_time = 50 csa_profile = MultiObjectivePseudoCSAProfiler(transit_connections, 2, start_time, end_time, transfer_margin, walk_network, walk_speed) csa_profile.run() source_profile = csa_profile.stop_profiles[0] print(source_profile.get_final_optimal_labels()) for label in source_profile.get_final_optimal_labels(): self.assertGreater(label.n_boardings, 0)
def test_walk_is_faster_than_by_trip(self): event_list_raw_data = [(0, 1, 0, 10, "trip_1", 1)] transit_connections = list( map(lambda el: Connection(*el), event_list_raw_data)) walk_speed = 0.5 source_stop = 0 target_stop = 1 transfer_margin = 0 start_time = 0 end_time = 50 walk_network = networkx.Graph() walk_network.add_edge(0, 1, d_walk=1) csa_profile = MultiObjectivePseudoCSAProfiler(transit_connections, target_stop, start_time, end_time, transfer_margin, walk_network, walk_speed) csa_profile.run() source_profile = csa_profile.stop_profiles[source_stop] self.assertEqual( min_arrival_time_target( source_profile.evaluate(0, first_leg_can_be_walk=True)), 2) found_tuples = source_profile.get_final_optimal_labels() self.assertEqual(len(found_tuples), 0)
def test_last_leg_is_walk(self): event_list_raw_data = [(0, 1, 0, 10, "trip_1", 1)] transit_connections = list( map(lambda el: Connection(*el), event_list_raw_data)) walk_network = networkx.Graph() walk_network.add_edge(1, 2, d_walk=20) walk_speed = 1 source_stop = 0 target_stop = 2 transfer_margin = 0 start_time = 0 end_time = 50 labels = list() labels.append( LabelTimeWithBoardingsCount(departure_time=0, arrival_time_target=30, n_boardings=1, first_leg_is_walk=False)) csa_profile = MultiObjectivePseudoCSAProfiler(transit_connections, target_stop, start_time, end_time, transfer_margin, walk_network, walk_speed) csa_profile.run() found_tuples = csa_profile.stop_profiles[ source_stop].get_final_optimal_labels() self._assert_label_sets_equal(found_tuples, labels)
def test_last_leg_is_walk(self): event_list_raw_data = [(0, 1, 0, 10, "trip_1", 1)] transit_connections = list( map(lambda el: Connection(*el), event_list_raw_data)) walk_network = networkx.Graph() walk_network.add_edge(1, 2, d_walk=20) walk_speed = 1 source_stop = 0 target_stop = 2 transfer_margin = 0 start_time = 0 end_time = 50 pareto_tuples = list() pareto_tuples.append( LabelTimeSimple(departure_time=0, arrival_time_target=30)) csa_profile = ConnectionScanProfiler(transit_connections, target_stop, start_time, end_time, transfer_margin, walk_network, walk_speed) csa_profile.run() found_tuples = csa_profile.stop_profiles[ source_stop].get_final_optimal_labels() self._assert_pareto_labels_equal(found_tuples, pareto_tuples)
def read_connections_csv(events_fname=HELSINKI_TRANSIT_CONNECTIONS_FNAME, routing_start_time_dep=ROUTING_START_TIME_DEP, routing_end_time_dep=ROUTING_END_TIME_DEP): """ Read events from a csv file, and create a list of Connection objects. Uses the built-in """ # header: from_stop_I, to_stop_I, dep_time_ut, arr_time_ut, route_type, trip_I, seq, route_I from_node_index = 0 to_node_index = 1 dep_time_index = 2 arr_time_index = 3 trip_I_index = 5 seq_index = 6 connections = [] with open(events_fname, 'r') as csvfile: events_reader = csv.reader(csvfile, delimiter=',') for _row in events_reader: break for row in events_reader: dep_time = int(row[dep_time_index]) if routing_start_time_dep <= dep_time <= routing_end_time_dep: connections.append( Connection(int(row[from_node_index]), int(row[to_node_index]), int(row[dep_time_index]), int(row[arr_time_index]), int(row[trip_I_index]), int(row[seq_index]))) connections = sorted(connections, key=lambda conn: -conn.departure_time) return connections
def _compute_final_pareto_optimal_labels(self, neighbor_label_bags, walk_durations, departure_arrival_stops): labels_from_neighbors = [] for i, (label_bag, walk_duration)in enumerate(zip(neighbor_label_bags, walk_durations)): for label in label_bag: if self.label_class == LabelTimeBoardingsAndRoute or self.label_class == LabelTimeAndRoute: departure_arrival_tuple = departure_arrival_stops[i] departure_time = label.departure_time - walk_duration arrival_time = label.departure_time connection = Connection(departure_arrival_tuple[0], departure_arrival_tuple[1], departure_time, arrival_time, Connection.WALK_TRIP_ID, Connection.WALK_SEQ, is_walk=True) labels_from_neighbors.append(label.get_copy_with_walk_added(walk_duration, connection)) else: labels_from_neighbors.append(label.get_copy_with_walk_added(walk_duration)) pareto_front = compute_pareto_front(self._real_connection_labels + labels_from_neighbors, finalization=True) if pareto_front and hasattr(pareto_front[0], "duration"): self._final_pareto_optimal_labels = list(filter(lambda label: label.duration() < self._walk_to_target_duration, pareto_front)) else: self._final_pareto_optimal_labels = pareto_front
def test_zero_length_journeys_potential_bug_1(self): event_list_raw_data = [(0, 1, 0, 0, "trip_1", 0), (1, 2, 0, 0, "trip_1", 1)] transit_connections = list( map(lambda el: Connection(*el), event_list_raw_data)) walk_network = networkx.Graph() walk_network.add_edge(10, 1, d_walk=20) walk_network.add_edge(1, 11, d_walk=20) walk_speed = 1 target_stop = 11 transfer_margin = 0 start_time = 0 end_time = 50 csa_profiler = MultiObjectivePseudoCSAProfiler(transit_connections, target_stop, start_time, end_time, transfer_margin, walk_network, walk_speed, track_vehicle_legs=True, track_time=True, track_route=True) csa_profiler.run() stop_profile_1 = csa_profiler._stop_profiles[1] all_labels_stop_profile_1 = [ label for label_bag in stop_profile_1._label_bags for label in label_bag ] for label in all_labels_stop_profile_1: self.assertLess( label.n_boardings, 1, "There should at most a walking label when going from 11 to 1 at any " "point in time, now one label has " + str(label.n_boardings) + " boardings")
def test_zero_length_journeys_potential_bug(self): s = 0 a = 1 b = 2 t = 3 event_list_raw_data = [(s, a, 0, 0, "trip_1", 1), (a, b, 0, 0, "trip_1", 2), (b, t, 1, 2, "trip_2", 0)] transit_connections = list( map(lambda el: Connection(*el), event_list_raw_data)) walk_network = networkx.Graph() walk_speed = 1 target_stop = t transfer_margin = 0 start_time = 0 end_time = 50 csa_profiler = MultiObjectivePseudoCSAProfiler(transit_connections, target_stop, start_time, end_time, transfer_margin, walk_network, walk_speed, track_vehicle_legs=True, track_time=True, track_route=True) csa_profiler.run() stop_profile_a_labels = csa_profiler.stop_profiles[ a].get_final_optimal_labels() stop_profile_s_labels = csa_profiler.stop_profiles[ s].get_final_optimal_labels() self.assertEqual(len(stop_profile_a_labels), 1) self.assertEqual(len(stop_profile_s_labels), 1)
def test_journeys_using_movement_duration_last_stop_walk(self): def unpack_route_from_labels(cur_label): route = [] last_arrival_stop = None print(cur_label) while True: print(cur_label.previous_label) connection = cur_label.connection if isinstance(connection, Connection): route.append(connection.departure_stop) if not cur_label.previous_label: break cur_label = cur_label.previous_label if isinstance(connection, Connection): last_arrival_stop = connection.arrival_stop route.append(last_arrival_stop) return route event_list_raw_data = [ (1, 2, 0, 10, "trip_1", 1), (2, 3, 10, 20, "trip_2", 1), (4, 5, 30, 40, "trip_3", 1), ] transit_connections = list( map(lambda el: Connection(*el), event_list_raw_data)) walk_network = networkx.Graph() walk_network.add_edge(2, 4, d_walk=10) walk_network.add_edge(3, 4, d_walk=10) walk_network.add_edge(5, 6, d_walk=10) walk_speed = 1 target_stop = 5 transfer_margin = 0 start_time = 0 end_time = 50 csa_profile = MultiObjectivePseudoCSAProfiler(transit_connections, target_stop, start_time, end_time, transfer_margin, walk_network, walk_speed, track_vehicle_legs=False, track_time=True, track_route=True) csa_profile.run() for stop, profile in csa_profile.stop_profiles.items(): for label_bag in profile._label_bags: for label in label_bag: print('origin:', stop, 'n_boardings/movement_duration:', label.movement_duration, 'route:', unpack_route_from_labels(label)) print('optimal labels:') for stop, profile in csa_profile.stop_profiles.items(): for label in profile.get_final_optimal_labels(): print('origin:', stop, 'n_boardings/movement_duration:', label.movement_duration, 'route:', unpack_route_from_labels(label))
def test_pseudo_connections_with_transfer_margin(self): event_list_raw_data = [(0, 1, 10, 20, "trip_6", 1), (2, 3, 42, 50, "trip_5", 1)] transit_connections = list( map(lambda el: Connection(*el), event_list_raw_data)) walk_network = networkx.Graph() walk_network.add_edge(1, 2, d_walk=10) walk_speed = 1 target_stop = 3 transfer_margin = 5 start_time = 0 end_time = 50 csa_profile = MultiObjectivePseudoCSAProfiler(transit_connections, target_stop, start_time, end_time, transfer_margin, walk_network, walk_speed) transfer_connection = csa_profile._all_connections[1] self.assertEqual(transfer_connection.arrival_stop, 2) self.assertEqual(transfer_connection.arrival_stop_next_departure_time, 42) self.assertEqual(transfer_connection.departure_stop, 1) self.assertEqual(transfer_connection.departure_time, 42 - 10) self.assertEqual(transfer_connection.is_walk, True) self.assertEqual(transfer_connection.arrival_time, 42)
def test_550_problem(self): # There used to be a problem when working with real unixtimes (c-side floating point number problems), # this test is one check for that event_data = StringIO( "from_stop_I,to_stop_I,dep_time_ut,arr_time_ut,route_type,route_id,trip_I,seq\n" + "2198,2247,1475530740,1475530860,3,2550,158249,36\n" + "2247,2177,1475530860,1475530980,3,2550,158249,37\n") import pandas as pd events = pd.read_csv(event_data) events.sort_values("dep_time_ut", ascending=False, inplace=True) connections = [ Connection(int(e.from_stop_I), int(e.to_stop_I), int(e.dep_time_ut), int(e.arr_time_ut), int(e.trip_I), int(e.seq)) for e in events.itertuples() ] csa_profiler = MultiObjectivePseudoCSAProfiler(connections, 2177, 0, 1475530860 * 10, 0, networkx.Graph(), 0) csa_profiler.run() profiles = csa_profiler.stop_profiles labels_2198 = profiles[2198].get_final_optimal_labels() self.assertEqual(len(labels_2198), 1) self.assertEqual(labels_2198[0].duration(), 1475530980 - 1475530740) labels_2247 = profiles[2247].get_final_optimal_labels() self.assertEqual(len(labels_2247), 1) self.assertEqual(labels_2247[0].duration(), 1475530980 - 1475530860)
def test_target_self_loops(self): event_list_raw_data = [(3, 1, 30, 40, "trip_3", 1)] transit_connections = list( map(lambda el: Connection(*el), event_list_raw_data)) walk_network = networkx.Graph() walk_network.add_edge(1, 3, d_walk=11) walk_speed = 1 target_stop = 1 transfer_margin = 0 start_time = 0 end_time = 50 print(walk_network.edges()) print(transit_connections) csa_profile = MultiObjectivePseudoCSAProfiler(transit_connections, target_stop, start_time, end_time, transfer_margin, walk_network, walk_speed, track_vehicle_legs=True, track_time=True, track_route=True) csa_profile.run() for stop, profile in csa_profile.stop_profiles.items(): if stop == target_stop: self.assertEqual(len(profile.get_final_optimal_labels()), 0)
def test_simple(self): event_list_raw_data = [ (2, 4, 40, 50, "trip_5", 1), ] transit_connections = list( map(lambda el: Connection(*el), event_list_raw_data)) walk_network = networkx.Graph() walk_network.add_edge(1, 2, d_walk=20) walk_network.add_edge(3, 4, d_walk=15) walk_speed = 1 source_stop = 1 target_stop = 4 transfer_margin = 0 start_time = 0 end_time = 50 pareto_tuples = list() pareto_tuples.append( LabelTimeSimple(departure_time=20, arrival_time_target=50)) csa_profile = ConnectionScanProfiler(transit_connections, target_stop, start_time, end_time, transfer_margin, walk_network, walk_speed) csa_profile.run() source_stop_profile = csa_profile.stop_profiles[source_stop] source_stop_pareto_tuples = source_stop_profile.get_final_optimal_labels( ) self._assert_pareto_labels_equal(pareto_tuples, source_stop_pareto_tuples)
def get_transit_connections(gtfs, start_time_ut, end_time_ut): """ Parameters ---------- gtfs: gtfspy.GTFS end_time_ut: int start_time_ut: int Returns ------- list[Connection] """ if start_time_ut + 20 * 3600 < end_time_ut: warn( "Note that it is possible that same trip_I's can take place during multiple days, " "which could (potentially) affect the outcomes of the CSA routing!" ) assert (isinstance(gtfs, GTFS)) events_df = temporal_network(gtfs, start_time_ut=start_time_ut, end_time_ut=end_time_ut) assert (isinstance(events_df, pandas.DataFrame)) return list( map( lambda e: Connection(e.from_stop_I, e.to_stop_I, e.dep_time_ut, e. arr_time_ut, e.trip_I, e.seq), events_df.itertuples()))
def test_transfers_only(self): event_list_raw_data = [ (7, 2, 20, 30, "trip_6", 1), (2, 4, 40, 50, "trip_5", 1), ] transit_connections = list( map(lambda el: Connection(*el), event_list_raw_data)) walk_network = networkx.Graph() walk_network.add_edge(1, 2, d_walk=20) walk_network.add_edge(3, 4, d_walk=15) walk_speed = 1 target_stop = 4 transfer_margin = 0 start_time = 0 end_time = 50 csa_profile = MultiObjectivePseudoCSAProfiler(transit_connections, target_stop, start_time, end_time, transfer_margin, walk_network, walk_speed, track_time=False) csa_profile.run() stop_to_n_boardings = {2: 1, 7: 2, 3: 0} for stop, n_veh_legs in stop_to_n_boardings.items(): labels = csa_profile.stop_profiles[stop].get_final_optimal_labels() self.assertEqual(len(labels), 1) self.assertEqual(labels[0].n_boardings, n_veh_legs)
def test_pseudo_connections(self): event_list_raw_data = [(0, 1, 10, 20, "trip_6", 1), (2, 3, 42, 50, "trip_5", 1)] transit_connections = list( map(lambda el: Connection(*el), event_list_raw_data)) walk_network = networkx.Graph() walk_network.add_edge(1, 2, d_walk=20) walk_speed = 1 target_stop = 3 transfer_margin = 0 start_time = 0 end_time = 50 csa_profile = MultiObjectivePseudoCSAProfiler(transit_connections, target_stop, start_time, end_time, transfer_margin, walk_network, walk_speed) self.assertEqual(len(csa_profile._all_connections), 3) pseudo_connection = csa_profile._all_connections[1] self.assertTrue(pseudo_connection.is_walk) self.assertEqual(pseudo_connection.departure_time, 42 - 20) self.assertEqual(pseudo_connection.arrival_time, 42) self.assertEqual(pseudo_connection.departure_stop, 1) self.assertEqual(pseudo_connection.arrival_stop, 2) node_to_connection_dep_times = { 0: [10], 1: [42 - 20], 2: [42], 3: [], } for node, dep_times in node_to_connection_dep_times.items(): profile = csa_profile._stop_profiles[node] for dep_time in dep_times: self.assertIn(dep_time, profile.dep_times_to_index, "Node: " + str(node)) for dep_time in profile.dep_times_to_index: self.assertIn(dep_time, dep_times, "Node: " + str(node)) for connection in csa_profile._all_connections: arrival_stop_profile = csa_profile._stop_profiles[ connection.arrival_stop] departure_stop_profile = csa_profile._stop_profiles[ connection.departure_stop] self.assertIsInstance(arrival_stop_profile, NodeProfileMultiObjective) self.assertIsInstance(departure_stop_profile, NodeProfileMultiObjective) self.assertIn(connection.departure_time, departure_stop_profile.dep_times_to_index) if connection.arrival_stop_next_departure_time != float('inf'): self.assertIn(connection.arrival_stop_next_departure_time, arrival_stop_profile.dep_times_to_index)
def test_transfer_on_same_stop_with_multiple_departures(self): walk_speed = 1000 target_stop = 5 start_time = 0 end_time = 60 transfer_margin = 0 transit_connections = [ Connection(0, 4, 30, 40, "trip_1", 1), Connection(4, 1, 50, 60, "trip_2", 1), Connection(4, 2, 50, 60, "trip_3", 1), Connection(4, 3, 50, 60, "trip_4", 1), Connection(4, target_stop, 70, 100, "trip_5", 1) ] csa_profiler = MultiObjectivePseudoCSAProfiler(transit_connections, target_stop, start_time, end_time, transfer_margin, networkx.Graph(), walk_speed) csa_profiler.run() profiles = csa_profiler.stop_profiles assert (profiles[0].get_final_optimal_labels()[0]) assert (len(profiles[0].get_final_optimal_labels()) > 0)
def test_possible_transfer_margin_bug_with_multiple_arrivals(self): walk_speed = 1 target_stop = 3 start_time = 0 end_time = 200 transfer_margin = 2 transit_connections = [ Connection(0, 1, 100, 101, "trip_0", 1), Connection(4, 1, 102, 104, "trip_1", 1), Connection(2, 3, 106, 108, "trip_2", 1) ] walk_network = networkx.Graph() walk_network.add_edge(1, 2, d_walk=1) csa_profile = MultiObjectivePseudoCSAProfiler(transit_connections, target_stop, start_time, end_time, transfer_margin, walk_network, walk_speed) csa_profile.run() profile = csa_profile.stop_profiles[4] self.assertEqual(len(profile.get_final_optimal_labels()), 0) profile = csa_profile.stop_profiles[0] self.assertEqual(len(profile.get_final_optimal_labels()), 1)
def test_transfer_margin(self): walk_speed = 1 target_stop = 2 start_time = 0 end_time = 60 transit_connections = [ Connection(0, 1, 40, 50, "trip_1", 1), Connection(1, 2, 50, 60, "trip_1", 2), Connection(3, 1, 40, 50, "trip_2", 1), ] # case without any transfer margin transfer_margin = 0 csa_profile = MultiObjectivePseudoCSAProfiler(transit_connections, target_stop, start_time, end_time, transfer_margin, networkx.Graph(), walk_speed) csa_profile.run() stop_profile_1 = csa_profile.stop_profiles[1] stop_profile_3 = csa_profile.stop_profiles[3] self.assertEqual(1, len(stop_profile_1.get_final_optimal_labels())) self.assertEqual(1, len(stop_profile_3.get_final_optimal_labels())) # case with transfer margin transfer_margin = 1 csa_profile = MultiObjectivePseudoCSAProfiler(transit_connections, target_stop, start_time, end_time, transfer_margin, networkx.Graph(), walk_speed) csa_profile.run() stop_profile_3 = csa_profile.stop_profiles[3] stop_profile_1 = csa_profile.stop_profiles[1] self.assertEqual(0, len(stop_profile_3.get_final_optimal_labels())) self.assertEqual(1, len(stop_profile_1.get_final_optimal_labels()))
def compute_pseudo_connections(transit_connections, start_time_dep, end_time_dep, transfer_margin, walk_network, walk_speed): """ Given a set of transit events and the static walk network, "transform" the static walking network into a set of "pseudo-connections". As a first approximation, we add pseudo-connections to depart after each arrival of a transit connection to it's arrival stop. Parameters ---------- transit_connections: list[Connection] start_time_dep : int start time in unixtime seconds end_time_dep: int end time in unixtime seconds (no new connections will be scanned after this time) transfer_margin: int required extra margin required for transfers in seconds walk_speed: float walking speed between stops in meters / second walk_network: networkx.Graph each edge should have the walking distance as a data attribute ("d_walk") expressed in meters Returns ------- pseudo_connections: set[Connection] """ # A pseudo-connection should be created after (each) arrival to a transit_connection's arrival stop. pseudo_connection_set = set() # use a set to ignore possible duplicates for c in transit_connections: if start_time_dep <= c.departure_time <= end_time_dep: walk_arr_stop = c.departure_stop walk_arr_time = c.departure_time - transfer_margin for _, walk_dep_stop, data in walk_network.edges( nbunch=[walk_arr_stop], data=True): walk_dep_time = walk_arr_time - data['d_walk'] / float( walk_speed) if walk_dep_time > end_time_dep or walk_dep_time < start_time_dep: continue pseudo_connection = Connection(walk_dep_stop, walk_arr_stop, walk_dep_time, walk_arr_time, Connection.WALK_TRIP_ID, Connection.WALK_SEQ, is_walk=True) pseudo_connection_set.add(pseudo_connection) return pseudo_connection_set
def test_transfer_connections_do_not_affect_transfers(self): walk_speed = 1000 target_stop = 1233412 start_time = 0 end_time = 60 transfer_margin = 0 transit_connections = [ Connection(0, 1, 30, 40, "trip_1", 1), Connection(3, 4, 45, 50, "trip_2", 1), Connection(4, 3, 45, 50, "trip_3", 1), Connection(5, 3, 45, 50, "trip_4", 1), Connection(1, target_stop, 70, 100, "trip_5", 1) ] walk_network = networkx.Graph() walk_network.add_edge(1, 3, d_walk=1) walk_network.add_edge(1, 4, d_walk=1) walk_network.add_edge(1, 5, d_walk=1) csa_profiler = MultiObjectivePseudoCSAProfiler( transit_connections, target_stop, start_time, end_time, transfer_margin, walk_network, walk_speed) csa_profiler.run() profiles = csa_profiler.stop_profiles assert (profiles[0].get_final_optimal_labels()[0]) assert (len(profiles[0].get_final_optimal_labels()) > 0)
def test_transfer_connections_do_not_affect_transfers2(self): walk_speed = 1 target_stop = 0 start_time = 0 end_time = 60 transfer_margin = 0 transit_connections = [ Connection(3, 0, 10, 11, "trip_1", 1), Connection(2, 1, 5, 6, "trip_2", 1), Connection(4, 3, 0, 1, "trip_3", 1) ] walk_network = networkx.Graph() walk_network.add_edge(2, 3, d_walk=1) walk_network.add_edge(1, 0, d_walk=1) csa_profiler = MultiObjectivePseudoCSAProfiler( transit_connections, target_stop, start_time, end_time, transfer_margin, walk_network, walk_speed) csa_profiler.run() profiles = csa_profiler.stop_profiles assert (len(profiles[4].get_final_optimal_labels()) == 1) optimal_label = profiles[4].get_final_optimal_labels()[0] self.assertEqual(optimal_label.departure_time, 0) self.assertEqual(optimal_label.arrival_time_target, 7) self.assertEqual(optimal_label.n_boardings, 2)
def setUp(self): event_list_raw_data = [(1, 2, 0, 10, "trip_1", 1), (1, 3, 1, 10, "trip_2", 1), (2, 3, 10, 11, "trip_1", 2), (3, 4, 11, 13, "trip_1", 3), (3, 6, 12, 14, "trip_3", 1)] self.transit_connections = map(lambda el: Connection(*el), event_list_raw_data) self.walk_network = networkx.Graph() self.walk_network.add_edge(4, 5, {"d_walk": 1000}) self.walk_speed = 10 self.source_stop = 1 self.end_time = 20 self.transfer_margin = 2 self.start_time = 0 - self.transfer_margin
def _get_label_to_target(self, departure_time): if departure_time != float( 'inf') and self._walk_to_target_duration != float('inf'): if self._walk_to_target_duration == 0: first_leg_is_walk = False else: first_leg_is_walk = True if self.label_class == LabelTimeBoardingsAndRoute or self.label_class == LabelTimeAndRoute: if self._walk_to_target_duration > 0: walk_connection = Connection(self.node_id, self.closest_target, departure_time, departure_time + self._walk_to_target_duration, Connection.WALK_TRIP_ID, Connection.WALK_SEQ, is_walk=True) else: walk_connection = None if self.label_class == LabelTimeAndRoute: label = self.label_class( departure_time=float(departure_time), arrival_time_target=float( departure_time + self._walk_to_target_duration), movement_duration=self._walk_to_target_duration, first_leg_is_walk=first_leg_is_walk, connection=walk_connection) else: label = self.label_class( departure_time=float(departure_time), arrival_time_target=float( departure_time + self._walk_to_target_duration), movement_duration=self._walk_to_target_duration, n_boardings=0, first_leg_is_walk=first_leg_is_walk, connection=walk_connection) else: label = self.label_class( departure_time=float(departure_time), arrival_time_target=float(departure_time + self._walk_to_target_duration), n_boardings=0, first_leg_is_walk=first_leg_is_walk) return label else: return None