예제 #1
0
    def _run(self):
        previous_departure_time = float("inf")
        n_connections_tot = len(self._all_connections)
        for i, connection in enumerate(self._all_connections):
            # basic checking + printing progress:
            if self._verbose and i % 1000 == 0:
                print("\r", i, "/", n_connections_tot, " : ", "%.2f" % round(float(i) / n_connections_tot, 3), end='', flush=True)
            assert (isinstance(connection, Connection))
            assert (connection.departure_time <= previous_departure_time)
            previous_departure_time = connection.departure_time

            # Get labels from the stop (possibly subject to buffer time)
            arrival_node_labels = self._get_modified_arrival_node_labels(connection)
            # This is for the labels staying "in the vehicle"
            trip_labels = self._get_trip_labels(connection)

            # Then, compute Pareto-frontier of these alternatives:
            all_pareto_optimal_labels = merge_pareto_frontiers(arrival_node_labels, trip_labels)

            # Update labels for this trip
            if not connection.is_walk:
                self.__trip_labels[connection.trip_id] = all_pareto_optimal_labels

            # Update labels for the departure stop profile (later: with the sets of pareto-optimal labels)
            self._stop_profiles[connection.departure_stop].update(all_pareto_optimal_labels,
                                                                  connection.departure_time)


        print("finalizing profiles!")
        self._finalize_profiles()
예제 #2
0
    def test_merge_pareto_frontiers(self):
        label_a = LabelTimeWithBoardingsCount(
            departure_time=1,
            arrival_time_target=2,
            n_boardings=1,
            first_leg_is_walk=False)  # optimal
        label_b = LabelTimeWithBoardingsCount(
            departure_time=1,
            arrival_time_target=5,
            n_boardings=0,
            first_leg_is_walk=False)  # d dominates
        label_c = LabelTimeWithBoardingsCount(
            departure_time=3,
            arrival_time_target=4,
            n_boardings=1,
            first_leg_is_walk=False)  # optimal
        label_d = LabelTimeWithBoardingsCount(
            departure_time=4,
            arrival_time_target=5,
            n_boardings=0,
            first_leg_is_walk=False)  # optimal
        front_1 = [label_a, label_b]
        front_2 = [label_c, label_d]

        pareto_front = merge_pareto_frontiers(front_1, front_2)
        self.assertEqual(3, len(pareto_front))
        self.assertNotIn(label_b, pareto_front)
예제 #3
0
    def evaluate(self,
                 dep_time,
                 first_leg_can_be_walk=True,
                 connection_arrival_time=None):
        """
        Get the pareto_optimal set of Labels, given a departure time.

        Parameters
        ----------
        dep_time : float, int
            time in unix seconds
        first_leg_can_be_walk : bool, optional
            whether to allow walking to target to be included into the profile
            (I.e. whether this function is called when scanning a pseudo-connection:
            "double" walks are not allowed.)
        connection_arrival_time: float, int, optional
            used for computing the walking label if dep_time, i.e., connection.arrival_stop_next_departure_time, is infinity)
        connection: connection object

        Returns
        -------
        pareto_optimal_labels : set
            Set of Labels
        """
        walk_labels = list()
        # walk label towards target
        if first_leg_can_be_walk and self._walk_to_target_duration != float(
                'inf'):
            # add walk_label
            if connection_arrival_time is not None:
                walk_labels.append(
                    self._get_label_to_target(connection_arrival_time))
            else:
                walk_labels.append(self._get_label_to_target(dep_time))

        # if dep time is larger than the largest dep time -> only walk labels are possible
        if dep_time in self.dep_times_to_index:
            assert (dep_time != float('inf'))
            index = self.dep_times_to_index[dep_time]
            labels = self._label_bags[index]
            pareto_optimal_labels = merge_pareto_frontiers(labels, walk_labels)
        else:
            pareto_optimal_labels = walk_labels

        if not first_leg_can_be_walk:
            pareto_optimal_labels = [
                label for label in pareto_optimal_labels
                if not label.first_leg_is_walk
            ]
        return pareto_optimal_labels
예제 #4
0
    def update(self, new_labels, departure_time_backup=None):
        """
        Update the profile with the new labels.
        Each new label should have the same departure_time.

        Parameters
        ----------
        new_labels: list[LabelTime]

        Returns
        -------
        added: bool
            whether new_pareto_tuple was added to the set of pareto-optimal tuples
        """
        if self._closed:
            raise RuntimeError("Profile is closed, no updates can be made")
        try:
            departure_time = next(iter(new_labels)).departure_time
        except StopIteration:
            departure_time = departure_time_backup
        self._check_dep_time_is_valid(departure_time)

        for new_label in new_labels:
            assert (new_label.departure_time == departure_time)
        dep_time_index = self.dep_times_to_index[departure_time]

        if dep_time_index > 0:
            # Departure time is modified in order to not pass on labels which are not Pareto-optimal when departure time is ignored.
            mod_prev_labels = [
                label.get_copy_with_specified_departure_time(departure_time)
                for label in self._label_bags[dep_time_index - 1]
            ]
        else:
            mod_prev_labels = list()
        mod_prev_labels += self._label_bags[dep_time_index]

        walk_label = self._get_label_to_target(departure_time)
        if walk_label:
            new_labels = new_labels + [walk_label]
        new_frontier = merge_pareto_frontiers(new_labels, mod_prev_labels)

        self._label_bags[dep_time_index] = new_frontier
        return True
예제 #5
0
 def test_merge_pareto_frontiers_empty(self):
     pareto_front = merge_pareto_frontiers([], [])
     self.assertEqual(0, len(pareto_front))