def run_router_with_reconstruction_test(router_type, from_stop, to_stop,
                                        des_dep_time_hhmmss, exp_nb_legs,
                                        exp_nb_pt_legs, exp_first_stop,
                                        exp_last_stop, exp_dep_time_hhmmss,
                                        exp_arr_time_hhmmss, exp_pt_in_stops,
                                        exp_pt_out_stops):
    cs_data = create_test_connectionscan_data()
    cs_core = ConnectionScanCore(cs_data)
    router = None
    if router_type == RouterWithReconstructionType.UNOPTIMIZED_EARLIEST_ARRIVAL_WITH_RECONSTRUCTION:
        router = cs_core.route_earliest_arrival_with_reconstruction
    elif router_type == RouterWithReconstructionType.OPTIMIZED_EARLIEST_ARRIVAL_WITH_RECONSTRUCTION:
        router = cs_core.route_optimized_earliest_arrival_with_reconstruction
    else:
        ValueError("router not known")
    journey = router(from_stop.id, to_stop.id,
                     hhmmss_to_sec(des_dep_time_hhmmss))
    assert exp_nb_legs == journey.get_nb_journey_legs()
    assert exp_nb_pt_legs == journey.get_nb_pt_journey_legs()
    assert (exp_first_stop.id if exp_first_stop is not None else
            None) == journey.get_first_stop_id()
    assert (exp_last_stop.id if exp_last_stop is not None else
            None) == journey.get_last_stop_id()
    assert (exp_dep_time_hhmmss if exp_dep_time_hhmmss else
            None) == seconds_to_hhmmss(journey.get_dep_time())
    assert (exp_arr_time_hhmmss if exp_arr_time_hhmmss else
            None) == seconds_to_hhmmss(journey.get_arr_time())
    assert [s.id for s in exp_pt_in_stops] == journey.get_pt_in_stop_ids()
    assert [s.id for s in exp_pt_out_stops] == journey.get_pt_out_stop_ids()
 def __init__(self, in_connection, out_connection, footpath):
     if in_connection is None and out_connection is None and footpath is None:
         raise ValueError(
             "either in_connection and out_connection or footpath or all three must be not None"
         )
     if (in_connection is None and out_connection is not None) or (
             in_connection is not None and out_connection is None):
         raise ValueError(
             "in_connection {} and out_connection {} must both either be None or not None"
             .format(in_connection, out_connection))
     if in_connection is not None and out_connection is not None:
         if in_connection.trip_id != out_connection.trip_id:
             raise ValueError(
                 "trip_id {} of in_connection is not equal to trip_id {} of out_connection."
                 .format(in_connection.trip_id, out_connection.trip_id))
         if in_connection != out_connection:
             if in_connection.dep_time > out_connection.arr_time:
                 raise ValueError(
                     "dep_time {} of in_connection is after arr_time {} of out_connection."
                     .format(seconds_to_hhmmss(in_connection.dep_time),
                             seconds_to_hhmmss(out_connection.arr_time)))
     if footpath is not None and out_connection is not None:
         if out_connection.to_stop_id != footpath.from_stop_id:
             raise ValueError(
                 "to_stop_id {} of out_connection is not equal to from_stop_id {} of footpath"
                 .format(out_connection.to_stop_id, footpath.from_stop_id))
     self.in_connection = in_connection
     self.out_connection = out_connection
     self.footpath = footpath
 def __str__(self):
     return (
         "[id={}, trip_type={}, first_stop_id={}, last_stop_id={}, dep_in_first_stop={}, "
         "arr_in_last_stop={}, #connections={}]").format(
             self.id, self.trip_type,
             self.connections[0].from_stop_id if self.connections else "",
             self.connections[-1].to_stop_id if self.connections else "",
             seconds_to_hhmmss(self.connections[0].dep_time)
             if self.connections else "",
             seconds_to_hhmmss(self.connections[-1].arr_time)
             if self.connections else "", len(self.connections))
Exemple #4
0
def test_unoptimized_earliest_arrival_bern_zuerich_hb():
    cs_data = create_test_connectionscan_data()
    cs_core = ConnectionScanCore(cs_data)
    assert "08:58:00" == seconds_to_hhmmss(
        cs_core.route_earliest_arrival(bern.id, zuerich_hb.id,
                                       hhmmss_to_sec("07:35:00")))
    assert "08:58:00" == seconds_to_hhmmss(
        cs_core.route_earliest_arrival(bern.id, zuerich_hb.id,
                                       hhmmss_to_sec("08:02:00")))
    assert cs_core.route_earliest_arrival(bern.id, zuerich_hb.id,
                                          hhmmss_to_sec("23:33:00")) is None
def test_create_trips():
    dep_first_trip_first_stop = 5 * 60 * 60 + 42 * 60
    trips_fri_sg = create_trips(
        [fribourg, bern, zuerich_hb, winterthur, st_gallen],
        [14 * 60, 58 * 60, 20 * 60, 38 * 60], [6 * 60, 5 * 60, 3 * 60],
        dep_first_trip_first_stop, 32, 30 * 60)
    assert len(trips_fri_sg) == 32
    assert "1" == trips_fri_sg[3].connections[0].from_stop_id
    assert "2" == trips_fri_sg[3].connections[0].to_stop_id
    assert "2" == trips_fri_sg[3].connections[1].from_stop_id
    assert "3" == trips_fri_sg[3].connections[1].to_stop_id
    assert "4" == trips_fri_sg[3].connections[-1].from_stop_id
    assert "5" == trips_fri_sg[3].connections[-1].to_stop_id

    assert "08:12:00" == seconds_to_hhmmss(
        trips_fri_sg[5].connections[0].dep_time)
    assert "08:26:00" == seconds_to_hhmmss(
        trips_fri_sg[5].connections[0].arr_time)
    assert "08:32:00" == seconds_to_hhmmss(
        trips_fri_sg[5].connections[1].dep_time)
    assert "09:30:00" == seconds_to_hhmmss(
        trips_fri_sg[5].connections[1].arr_time)
    assert "09:35:00" == seconds_to_hhmmss(
        trips_fri_sg[5].connections[2].dep_time)
    assert "09:55:00" == seconds_to_hhmmss(
        trips_fri_sg[5].connections[2].arr_time)
    assert "09:58:00" == seconds_to_hhmmss(
        trips_fri_sg[5].connections[3].dep_time)
    assert "10:36:00" == seconds_to_hhmmss(
        trips_fri_sg[5].connections[3].arr_time)
def test_unoptimized_earliest_arrival_with_reconstruction_by_name_bern_bahnhof_samedan_bahnhof(
):
    cs_data = create_test_connectionscan_data()
    cs_core = ConnectionScanCore(cs_data)
    journey = cs_core.route_earliest_arrival_with_reconstruction_by_name(
        bern_bahnhof.name, samedan_bahnhof.name, "08:26:00")
    assert 4 == journey.get_nb_journey_legs()
    assert 3 == journey.get_nb_pt_journey_legs()
    assert bern_bahnhof.id == journey.get_first_stop_id()
    assert samedan_bahnhof.id == journey.get_last_stop_id()
    assert "08:27:00" == seconds_to_hhmmss(journey.get_dep_time())
    assert "12:48:00" == seconds_to_hhmmss(journey.get_arr_time())
    assert [bern.id, zuerich_hb.id, chur.id] == journey.get_pt_in_stop_ids()
    assert [zuerich_hb.id, chur.id,
            samedan.id] == journey.get_pt_out_stop_ids()
Exemple #7
0
def test_unoptimized_earliest_arrival_bern_duebystrasse_ostermundigen_bahnhof(
):
    cs_data = create_test_connectionscan_data()
    cs_core = ConnectionScanCore(cs_data)
    assert "12:34:00" == seconds_to_hhmmss(
        cs_core.route_earliest_arrival(bern_duebystrasse.id,
                                       ostermundigen_bahnhof.id,
                                       hhmmss_to_sec("12:09:46")))
Exemple #8
0
def test_unoptimized_earliest_arrival_bern_samedan():
    cs_data = create_test_connectionscan_data()
    cs_core = ConnectionScanCore(cs_data)
    assert "12:45:00" == seconds_to_hhmmss(
        cs_core.route_earliest_arrival(bern.id, samedan.id,
                                       hhmmss_to_sec("08:30:00")))
    assert cs_core.route_earliest_arrival(bern.id, samedan.id,
                                          hhmmss_to_sec("21:00:00")) is None
    def route_earliest_arrival(self, from_stop_id, to_stop_id,
                               desired_dep_time):
        """Executes the unoptimized earliest arrival version (figure 3 of https://arxiv.org/pdf/1703.05997.pdf) of the
        connection scan algorithm from the source to the target stop respecting the desired departure time.

        Note:
            - In order to correctly model the footpaths at the start and end of the journey,
            the algorithm from the pseudo code is slightly modified.
            - the data structures are not optimized for performance.

        Args:
            from_stop_id (str): id of the source stop.
            to_stop_id (str): id of the target stop.
            desired_dep_time (int): desired departure time in seconds after midnight.

        Returns:
            int: earliest possible arrival time at the target stop.
        """

        log_start(
            "unoptimized earliest arrival routing from {} to {} at {}".format(
                self.connection_scan_data.stops_per_id[from_stop_id].name,
                self.connection_scan_data.stops_per_id[to_stop_id].name,
                seconds_to_hhmmss(desired_dep_time)), log)

        # TODO implement task 1 here
        # Some hints:
        # - First get familiar with the data structures from the classes module and the ConnectionScanData class
        # - In order to correctly model the footpaths at the start and end of the journey,
        #   the algorithm from the pseudo code must be slightly modified.
        # - You could use the following dynamic data structures:
        #    - a dict for the earliest arrival including transfer/walking times per stop.
        #    - a int for the earliest arrival time at the target stop.
        #    - a dict to mark if a trip is set or not.

        res = -1
        log_end(additional_message="earliest arrival time: {}".format(
            seconds_to_hhmmss(res) if res else res))
        return res
    def route_earliest_arrival_with_reconstruction(self, from_stop_id,
                                                   to_stop_id,
                                                   desired_dep_time):
        """Executes the unoptimized earliest arrival with reconstruction version
        (figure 6 of https://arxiv.org/pdf/1703.05997.pdf) of the
        connection scan algorithm from the source to the target stop respecting the desired departure time.

        Note:
            - In order to correctly model the footpaths at the start and end of the journey,
            the algorithm from the pseudo code is slightly modified.
            - the data structures are not optimized for performance.

        Args:
            from_stop_id (str): id of the source stop.
            to_stop_id (str): id of the target stop.
            desired_dep_time (int): desired departure time in seconds after midnight.

        Returns:
            Journey: a Journey with earliest possible arrival time from the source to the target stop.
        """
        log_start(
            "unoptimized earliest arrival routing with journey reconstruction from {} to {} at {}"
            .format(self.connection_scan_data.stops_per_id[from_stop_id].name,
                    self.connection_scan_data.stops_per_id[to_stop_id].name,
                    seconds_to_hhmmss(desired_dep_time)), log)

        # TODO implement task 2 here
        # Some hints:
        # - Implement task 1 first.
        # - In order to correctly model the footpaths at the start and end of the journey,
        #   the algorithm from the pseudo code must be slightly modified.
        # - You could use the following dynamic data structures:
        #    - a dict for the earliest arrival including transfer/walking times per stop.
        #    - a int for the earliest arrival time at the target stop.
        #    - a dict for the in/boarding connection per trip.
        #    - a JourneyLeg for the last journey leg at the target stop.
        # - Construct the resulting Journey with the reconstruction logic from the pseudo code.

        res = Journey()
        log_end(additional_message="# journey legs: {}".format(
            0 if res is None else res.get_nb_journey_legs()))
        return res
def create_trips(stops, running_times, stop_times, first_departure, nb_trips,
                 headway):
    trips = []
    for trip_index in range(nb_trips):
        dep_first_stop = first_departure + trip_index * headway
        trip_id = "{}_{}_{}_{}".format(stops[0].name, stops[-1].name,
                                       seconds_to_hhmmss(dep_first_stop),
                                       trip_index)
        cons = []
        arr = None
        for stop_index in range(len(stops) - 1):
            dep = dep_first_stop if stop_index == 0 else arr + stop_times[
                stop_index - 1]
            arr = dep + running_times[stop_index]
            cons += [
                Connection(trip_id, stops[stop_index].id,
                           stops[stop_index + 1].id, dep, arr)
            ]
        trips += [Trip(trip_id, cons)]
    return trips
    def route_optimized_earliest_arrival_with_reconstruction(
            self, from_stop_id, to_stop_id, desired_dep_time):
        """Executes the optimized earliest arrival with reconstruction version
        (figure 4 and 6 of https://arxiv.org/pdf/1703.05997.pdf) of the
        connection scan algorithm from the source to the target stop respecting the desired departure time.

        Note:
            - In order to correctly model the footpaths at the start and end of the journey,
            the algorithm from the pseudo code is slightly modified.
            - the data structures are not optimized for performance.

        Args:
            from_stop_id (str): id of the source stop.
            to_stop_id (str): id of the target stop.
            desired_dep_time (int): desired departure time in seconds after midnight.

        Returns:
            Journey: a Journey with earliest possible arrival time from the source to the target stop.
        """
        log_start(
            "optimized earliest arrival routing with journey reconstruction from {} to {} at {}"
            .format(self.connection_scan_data.stops_per_id[from_stop_id].name,
                    self.connection_scan_data.stops_per_id[to_stop_id].name,
                    seconds_to_hhmmss(desired_dep_time)), log)

        # TODO implement task 3 here
        # Some hints:
        # - Implement task 2 first.
        # - In order to correctly model the footpaths at the start and end of the journey,
        #   the algorithm from the pseudo code must be slightly modified.
        # - You could use the same dynamic data structures and reconstruction logic as in task 2.
        # - Implement the three optimization criterion's described in the paper (on page 8):
        #   stopping criterion, starting criterion and limited walking.
        #   For the starting criterion you can use the function binary_search from the funs module.

        res = Journey()
        log_end(additional_message="# journey legs: {}".format(
            0 if res is None else res.get_nb_journey_legs()))
        return res
 def __str__(self):
     return "[trip_id={}, from_stop_id={}, to_stop_id={}, dep_time={}, arr_time={}]".format(
         self.trip_id, self.from_stop_id, self.to_stop_id,
         seconds_to_hhmmss(self.dep_time), seconds_to_hhmmss(self.arr_time))
Exemple #14
0
def test_unoptimized_earliest_arrival_by_name_bern_bern_bahnhof():
    cs_data = create_test_connectionscan_data()
    cs_core = ConnectionScanCore(cs_data)
    assert "12:14:46" == seconds_to_hhmmss(
        cs_core.route_earliest_arrival_by_name(bern.name, bern_bahnhof.name,
                                               "12:09:46"))
Exemple #15
0
def test_unoptimized_earliest_arrival_bern_bern():
    cs_data = create_test_connectionscan_data()
    cs_core = ConnectionScanCore(cs_data)
    assert "12:09:46" == seconds_to_hhmmss(
        cs_core.route_earliest_arrival(bern.id, bern.id,
                                       hhmmss_to_sec("12:09:46")))
Exemple #16
0
def test_unoptimized_earliest_arrival_basel_st_gallen():
    cs_data = create_test_connectionscan_data()
    cs_core = ConnectionScanCore(cs_data)
    assert "09:41:00" == seconds_to_hhmmss(
        cs_core.route_earliest_arrival(basel_sbb.id, st_gallen.id,
                                       hhmmss_to_sec("07:30:00")))
 def __str__(self):
     return "[trip_id={}, in_stop_id={}, out_stop_id={}, dep_time={}, arr_time={}]".format(
         self.get_trip_id(), self.get_in_stop_id(), self.get_out_stop_id(),
         seconds_to_hhmmss(self.get_dep_time_in_stop_id()),
         seconds_to_hhmmss(self.get_arr_time_out_stop_id()))
def test_seconds_to_hhmmss():
    assert "00:00:00" == seconds_to_hhmmss(0.012879)
    assert "00:00:02" == seconds_to_hhmmss(2.012379)
    assert "03:05:02" == seconds_to_hhmmss(3 * 60 * 60 + 5 * 60 + 2 + 0.112)
    assert "03:05:02" == seconds_to_hhmmss(3 * 60 * 60 + 5 * 60 + 2)