Skip to content

Commit c3d666c

Browse files
committed
Split implementation of RaptorState and LabelManager
1 parent 6ad5b2d commit c3d666c

6 files changed

Lines changed: 324 additions & 215 deletions

File tree

CMakeLists.txt

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -22,9 +22,13 @@ FetchContent_Declare(
2222

2323
FetchContent_MakeAvailable(just_gtfs nanoflann)
2424

25-
set(SOURCES src/raptor/raptor.cpp src/schedule/Schedule.cpp
25+
set(SOURCES src/raptor/raptor.cpp
26+
src/raptor/label_manager.cpp
27+
src/raptor/state.cpp
28+
src/raptor/StopKDTree.cpp
29+
src/schedule/Schedule.cpp
2630
src/schedule/gtfs.cpp
27-
src/raptor/StopKDTree.cpp)
31+
)
2832

2933
option(PT_ROUTING_BUILD_TESTS "Build unit tests" ON)
3034
include(FetchContent)
@@ -33,7 +37,7 @@ FetchContent_Declare(
3337
URL https://github.com/google/googletest/archive/03597a01ee50ed33e9dfd640b249b4be3799d395.zip
3438
)
3539
FetchContent_MakeAvailable(googletest)
36-
if(PT_ROUTING_BUILD_TESTS)
40+
if (PT_ROUTING_BUILD_TESTS)
3741
enable_testing()
3842
add_subdirectory(tests)
3943
endif ()

include/raptor/raptor.h

Lines changed: 3 additions & 206 deletions
Original file line numberDiff line numberDiff line change
@@ -3,218 +3,15 @@
33

44
#include <ranges>
55
#include <unordered_map>
6-
#include <unordered_set>
76

87
#include "reconstruction.h"
98
#include "schedule/Schedule.h"
9+
#include "raptor/state.h"
1010

1111
namespace raptor {
1212

13-
using StopIndex = std::ranges::range_difference_t<decltype(std::declval<Route>().stop_sequence())>;
14-
using TripIndex = std::ranges::range_difference_t<decltype(std::declval<Route>().get_trips())>;
15-
using StopTimeIndex = std::ranges::range_difference_t<decltype(std::declval<Trip>().get_stop_times())>;
16-
17-
/**
18-
* Contains information about reaching a stop. The algorithm supports two types of reaching a stop: either on
19-
* foot or using public transport. When travelling on foot the route_and_trip_index member is set to std::nullopt.
20-
*
21-
* The boarding_stop member is set to std::nullopt for the starting point of the journey.
22-
*/
23-
struct JourneyInformation {
24-
Time arrival_time;
25-
std::optional<std::reference_wrapper<const Stop>> boarding_stop;
26-
std::optional<std::pair<std::reference_wrapper<const Route>, TripIndex>> route_and_trip_index;
27-
};
28-
29-
struct JourneyInformationPTExtension {
30-
const Route& route;
31-
TripIndex trip_index;
32-
StopIndex stop_index;
33-
};
34-
35-
/**
36-
* LabelManager is responsible for controlling the labels associated with each Stop.
37-
* It keeps track of two sets of the current and previous sets of labels.
38-
*
39-
* All modifications to the labels apply to the current set.
40-
*/
41-
class LabelManager {
42-
using LabelType = JourneyInformation;
43-
using LabelContainer = std::unordered_map<std::reference_wrapper<const Stop>, LabelType>;
44-
45-
LabelContainer current_round_labels;
46-
LabelContainer previous_round_labels;
47-
48-
static std::optional<LabelType> get_label(const Stop& stop, const LabelContainer& labels) {
49-
const auto label = labels.find(stop);
50-
return label == labels.end() ? std::nullopt : std::make_optional(label->second);
51-
}
52-
53-
public:
54-
LabelManager() = default;
55-
56-
/**
57-
* Initialises the object and adds a label to the current set.
58-
*/
59-
LabelManager(const Stop& stop,
60-
const Time& arrival_time,
61-
const std::optional<std::reference_wrapper<const Stop>> boarding_stop,
62-
const std::optional<std::pair<std::reference_wrapper<const Route>, TripIndex>>
63-
route_with_trip_index) {
64-
add_label(stop, arrival_time, boarding_stop, route_with_trip_index);
65-
}
66-
67-
/**
68-
* Copies the labels of the current round to the previous round
69-
*/
70-
void new_round() {
71-
previous_round_labels = current_round_labels;
72-
}
73-
74-
/**
75-
* Adds or changes the value of the label for the latest set.
76-
* @param stop
77-
* @param arrival_time Arrival time at the stop.
78-
* @param boarding_stop Stop where the line is boarded to reach the stop.
79-
* @param route_with_trip_index Route used to travel between the stops along with the index of the trip used.
80-
*/
81-
void add_label(const Stop& stop,
82-
const Time& arrival_time,
83-
const std::optional<std::reference_wrapper<const Stop>>& boarding_stop,
84-
const std::optional<std::pair<std::reference_wrapper<const Route>, TripIndex>>
85-
& route_with_trip_index) {
86-
current_round_labels.insert_or_assign(
87-
stop, JourneyInformation(arrival_time, boarding_stop, route_with_trip_index));
88-
}
89-
90-
std::optional<LabelType> get_latest_label(const Stop& stop) const {
91-
return get_label(stop, current_round_labels);
92-
}
93-
94-
std::optional<LabelType> get_previous_label(const Stop& stop) const {
95-
return get_label(stop, previous_round_labels);
96-
}
97-
98-
using IndexWithTime = std::pair<StopIndex, Time>;
99-
100-
/**
101-
* Get the first stop of the route that was reached in the previous round.
102-
* @param stops Range containing stop objects for this route in travel order.
103-
* @return Pair containing a reference to the stop and the arrival time to the stop. No value if there is no
104-
* stop in the given route that can be reached with the given number of transfers.
105-
*/
106-
template <std::ranges::input_range R>
107-
requires std::is_convertible_v<std::ranges::range_value_t<R>, Stop>
108-
std::optional<IndexWithTime> find_hop_on_stop(
109-
R&& stops) {
110-
auto stops_with_journeys = previous_round_labels | std::views::keys;
111-
auto hop_on_stop = std::ranges::find_first_of(stops, stops_with_journeys,
112-
{}, {}, &LabelContainer::value_type::first);
113-
if (hop_on_stop == std::ranges::end(stops)) {
114-
return std::nullopt;
115-
}
116-
return std::make_pair(std::ranges::distance(std::ranges::begin(stops), hop_on_stop),
117-
previous_round_labels.at(*hop_on_stop).arrival_time);
118-
}
119-
};
120-
121-
/**
122-
* Manages the internal state of the algorithm.
123-
*/
124-
class RaptorStatus {
125-
LabelManager label_manager;
126-
std::unordered_map<std::reference_wrapper<const Stop>, Time> earliest_arrival_time;
127-
std::unordered_set<std::reference_wrapper<const Stop>> improved_stops;
128-
int n_round = 0;
129-
const Stop& destination;
130-
131-
bool can_improve_current_journey_to_stop(const Time& new_arrival_time, const Stop& current_stop) const {
132-
auto arrival_time_to_current_stop = earliest_arrival_time.find(current_stop);
133-
if (arrival_time_to_current_stop == earliest_arrival_time.end())
134-
return true;
135-
auto arrival_time_to_destination = earliest_arrival_time.find(destination);
136-
if (arrival_time_to_destination == earliest_arrival_time.end()) {
137-
return new_arrival_time.get_sys_time() < arrival_time_to_current_stop->second.get_sys_time();
138-
}
139-
return new_arrival_time.get_sys_time() < std::min(arrival_time_to_current_stop->second.get_sys_time(),
140-
arrival_time_to_destination->second.get_sys_time());
141-
}
142-
143-
public:
144-
RaptorStatus() = delete;
145-
146-
// Copying this object is probably an error. Delete to avoid doing it by mistake.
147-
RaptorStatus(const RaptorStatus& other) = delete;
148-
RaptorStatus& operator=(const RaptorStatus& other) = delete;
149-
150-
RaptorStatus(const Stop& origin_stop, const Stop& destination, const Time& departure_time) :
151-
destination(destination) {
152-
// TODO: Remove the need for nullopt boarding_stop
153-
label_manager.add_label(origin_stop, departure_time, std::nullopt, std::nullopt);
154-
earliest_arrival_time[origin_stop] = departure_time;
155-
improved_stops.insert(origin_stop);
156-
}
157-
158-
int new_round() {
159-
n_round++;
160-
label_manager.new_round();
161-
return n_round;
162-
}
163-
164-
bool have_stops_to_improve() const {
165-
return !improved_stops.empty();
166-
}
167-
168-
bool try_improve_stop(const Stop& stop, const Time& new_arrival_time,
169-
const std::optional<std::reference_wrapper<const Stop>>& boarding_stop,
170-
const std::optional<std::pair<std::reference_wrapper<const Route>, TripIndex>>&
171-
route_with_trip_index) {
172-
if (can_improve_current_journey_to_stop(new_arrival_time, stop)) {
173-
label_manager.add_label(stop, new_arrival_time, boarding_stop, route_with_trip_index);
174-
earliest_arrival_time[stop] = new_arrival_time;
175-
improved_stops.insert(std::cref(stop));
176-
return true;
177-
}
178-
return false;
179-
}
180-
181-
bool might_catch_earlier_trip(const Stop& stop, const Time& departure_time) const {
182-
const auto previous_journey = label_manager.get_previous_label(stop);
183-
return previous_journey.has_value() &&
184-
previous_journey->arrival_time.get_sys_time() <= departure_time.get_sys_time();
185-
}
186-
187-
std::unordered_set<std::reference_wrapper<const Stop>> get_and_clear_improved_stops() {
188-
auto old_improved_stops = std::move(improved_stops);
189-
improved_stops.clear();
190-
return old_improved_stops;
191-
}
192-
193-
std::unordered_set<std::reference_wrapper<const Stop>> get_improved_stops() const {
194-
return improved_stops;
195-
}
196-
197-
Time current_arrival_time_to_stop(const Stop& stop) const {
198-
return earliest_arrival_time.at(stop);
199-
}
200-
201-
Time previous_arrival_time_to_stop(const Stop& stop) const {
202-
return label_manager.get_previous_label(stop)->arrival_time;
203-
}
204-
205-
// TODO: Remove this, currently used when building journeys.
206-
const LabelManager& get_label_manager() const {
207-
return label_manager;
208-
}
209-
};
210-
21113
class Raptor {
21214

213-
// struct RouteWithStopIndex {
214-
// std::reference_wrapper<const Route> route;
215-
// StopIndex stop_idx;
216-
// };
217-
21815
// Make the reference wrapper const so it can be used to directly extract pairs from the unordered_map
21916
using RouteWithStopIndex = std::pair<const std::reference_wrapper<const Route>, StopIndex>;
22017

@@ -271,9 +68,9 @@ namespace raptor {
27168
std::vector<Movement> build_trip(const Stop& origin,
27269
const Stop& destination,
27370
const LabelManager& stop_labels);
274-
void process_transfers(RaptorStatus& status);
71+
void process_transfers(RaptorState& status);
27572

276-
void process_route(const Route& route, StopIndex hop_on_stop_idx, Time hop_on_time, RaptorStatus& status);
73+
void process_route(const Route& route, StopIndex hop_on_stop_idx, Time hop_on_time, RaptorState& status);
27774

27875

27976
template <std::ranges::input_range R>

0 commit comments

Comments
 (0)