Skip to content

Commit

Permalink
clasz routing search filter (#72)
Browse files Browse the repository at this point in the history
  • Loading branch information
felixguendling authored Feb 27, 2024
1 parent d806245 commit bf9b9e9
Show file tree
Hide file tree
Showing 10 changed files with 395 additions and 45 deletions.
29 changes: 29 additions & 0 deletions include/nigiri/routing/clasz_mask.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
#pragma once

#include <cinttypes>
#include <limits>
#include <string>

#include "nigiri/types.h"

namespace nigiri::routing {

using clasz_mask_t = std::uint16_t;

constexpr inline clasz_mask_t all_clasz_allowed() {
return std::numeric_limits<clasz_mask_t>::max();
}

constexpr inline clasz_mask_t to_mask(clasz const c) {
auto const c_as_int = static_cast<std::underlying_type_t<clasz>>(c);
return static_cast<clasz_mask_t>(1U << c_as_int);
}

constexpr inline bool is_allowed(clasz_mask_t const mask, clasz const c) {
auto const c_as_mask = to_mask(c);
return (mask & c_as_mask) == c_as_mask;
}

std::string to_str(clasz_mask_t const x);

} // namespace nigiri::routing
3 changes: 3 additions & 0 deletions include/nigiri/routing/query.h
Original file line number Diff line number Diff line change
@@ -1,11 +1,13 @@
#pragma once

#include <cinttypes>
#include <limits>
#include <variant>
#include <vector>

#include "nigiri/common/interval.h"
#include "nigiri/footpath.h"
#include "nigiri/routing/clasz_mask.h"
#include "nigiri/routing/limits.h"
#include "nigiri/routing/location_match_mode.h"
#include "nigiri/types.h"
Expand Down Expand Up @@ -45,6 +47,7 @@ struct query {
bool extend_interval_earlier_{false};
bool extend_interval_later_{false};
profile_idx_t prf_idx_{0};
clasz_mask_t allowed_claszes_{all_clasz_allowed()};
};

} // namespace nigiri::routing
71 changes: 54 additions & 17 deletions include/nigiri/routing/raptor/raptor.h
Original file line number Diff line number Diff line change
Expand Up @@ -55,7 +55,8 @@ struct raptor {
std::vector<bool>& is_dest,
std::vector<std::uint16_t>& dist_to_dest,
std::vector<std::uint16_t>& lb,
day_idx_t const base)
day_idx_t const base,
clasz_mask_t const allowed_claszes)
: tt_{tt},
rtt_{rtt},
state_{state},
Expand All @@ -66,7 +67,8 @@ struct raptor {
n_days_{tt_.internal_interval_days().size().count()},
n_locations_{tt_.n_locations()},
n_routes_{tt.n_routes()},
n_rt_transports_{Rt ? rtt->n_rt_transports() : 0U} {
n_rt_transports_{Rt ? rtt->n_rt_transports() : 0U},
allowed_claszes_{allowed_claszes} {
state_.resize(n_locations_, n_routes_, n_rt_transports_);
utl::fill(time_at_dest_, kInvalid);
state_.round_times_.reset(kInvalid);
Expand Down Expand Up @@ -144,22 +146,13 @@ struct raptor {
std::swap(state_.prev_station_mark_, state_.station_mark_);
utl::fill(state_.station_mark_, false);

any_marked = false;
for (auto r_id = 0U; r_id != n_routes_; ++r_id) {
if (state_.route_mark_[r_id]) {
++stats_.n_routes_visited_;
trace("┊ ├k={} updating route {}\n", k, r_id);
any_marked |= update_route(k, route_idx_t{r_id});
}
}
any_marked = (allowed_claszes_ == all_clasz_allowed())
? loop_routes<false>(k)
: loop_routes<true>(k);
if constexpr (Rt) {
for (auto rt_t = 0U; rt_t != n_rt_transports_; ++rt_t) {
if (state_.rt_transport_mark_[rt_t]) {
++stats_.n_routes_visited_;
trace("┊ ├k={} updating rt transport {}\n", k, rt_t);
any_marked |= update_rt_transport(k, rt_transport_idx_t{rt_t});
}
}
any_marked |= (allowed_claszes_ == all_clasz_allowed())
? loop_rt_routes<false>(k)
: loop_rt_routes<true>(k);
}

if (!any_marked) {
Expand Down Expand Up @@ -216,6 +209,49 @@ struct raptor {
return tt_.internal_interval_days().from_ + as_int(base_) * date::days{1};
}

template <bool WithClaszFilter>
bool loop_routes(unsigned const k) {
auto any_marked = false;
for (auto r_idx = 0U; r_idx != n_routes_; ++r_idx) {
auto const r = route_idx_t{r_idx};

if (state_.route_mark_[r_idx]) {
if constexpr (WithClaszFilter) {
if (!is_allowed(allowed_claszes_, tt_.route_clasz_[r])) {
continue;
}
}

++stats_.n_routes_visited_;
trace("┊ ├k={} updating route {}\n", k, r);
any_marked |= update_route(k, r);
}
}
return any_marked;
}

template <bool WithClaszFilter>
bool loop_rt_routes(unsigned const k) {
auto any_marked = false;
for (auto rt_t_idx = 0U; rt_t_idx != n_rt_transports_; ++rt_t_idx) {
if (state_.rt_transport_mark_[rt_t_idx]) {
auto const rt_t = rt_transport_idx_t{rt_t_idx};

if constexpr (WithClaszFilter) {
if (!is_allowed(allowed_claszes_,
rtt_->rt_transport_section_clasz_[rt_t][0])) {
continue;
}
}

++stats_.n_routes_visited_;
trace("┊ ├k={} updating rt transport {}\n", k, rt_t);
any_marked |= update_rt_transport(k, rt_t);
}
}
return any_marked;
}

void update_transfers(unsigned const k) {
for (auto i = 0U; i != n_locations_; ++i) {
if (!state_.prev_station_mark_[i]) {
Expand Down Expand Up @@ -687,6 +723,7 @@ struct raptor {
int n_days_;
raptor_stats stats_;
std::uint32_t n_locations_, n_routes_, n_rt_transports_;
clasz_mask_t allowed_claszes_;
};

} // namespace nigiri::routing
7 changes: 4 additions & 3 deletions include/nigiri/routing/search.h
Original file line number Diff line number Diff line change
Expand Up @@ -55,7 +55,7 @@ struct search {
static constexpr auto const kFwd = (SearchDir == direction::kForward);
static constexpr auto const kBwd = (SearchDir == direction::kBackward);

Algo init(algo_state_t& algo_state) {
Algo init(clasz_mask_t const allowed_claszes, algo_state_t& algo_state) {
stats_.fastest_direct_ =
static_cast<std::uint64_t>(fastest_direct_.count());

Expand Down Expand Up @@ -102,7 +102,8 @@ struct search {
state_.travel_time_lower_bound_,
day_idx_t{std::chrono::duration_cast<date::days>(
search_interval_.from_ - tt_.internal_interval().from_)
.count()}};
.count()},
allowed_claszes};
}

search(timetable const& tt,
Expand All @@ -125,7 +126,7 @@ struct search {
}},
q_.start_time_)},
fastest_direct_{get_fastest_direct(tt_, q_, SearchDir)},
algo_{init(algo_state)},
algo_{init(q_.allowed_claszes_, algo_state)},
timeout_(timeout) {}

routing_result<algo_stats_t> execute() {
Expand Down
7 changes: 7 additions & 0 deletions include/nigiri/timetable.h
Original file line number Diff line number Diff line change
Expand Up @@ -163,12 +163,16 @@ struct timetable {
route_idx_t register_route(
std::basic_string<stop::value_type> const& stop_seq,
std::basic_string<clasz> const& clasz_sections) {
assert(!stop_seq.empty() && stop_seq.size() > 1U);
assert(!clasz_sections.empty());

auto const idx = route_location_seq_.size();
route_transport_ranges_.emplace_back(
transport_idx_t{transport_traffic_days_.size()},
transport_idx_t::invalid());
route_location_seq_.emplace_back(stop_seq);
route_section_clasz_.emplace_back(clasz_sections);
route_clasz_.emplace_back(clasz_sections[0]);
return route_idx_t{idx};
}

Expand Down Expand Up @@ -376,6 +380,9 @@ struct timetable {
// Route -> list of stops
vecvec<route_idx_t, stop::value_type> route_location_seq_;

// Route -> clasz
vector_map<route_idx_t, clasz> route_clasz_;

// Route -> clasz per section
vecvec<route_idx_t, clasz> route_section_clasz_;

Expand Down
21 changes: 12 additions & 9 deletions include/nigiri/types.h
Original file line number Diff line number Diff line change
Expand Up @@ -326,15 +326,6 @@ inline std::ostream& operator<<(std::ostream& out,

} // namespace std::chrono

template <>
struct fmt::formatter<nigiri::duration_t> : ostream_formatter {};

template <>
struct fmt::formatter<nigiri::unixtime_t> : ostream_formatter {};

template <>
struct fmt::formatter<nigiri::debug> : ostream_formatter {};

#include <iostream>

namespace nigiri {
Expand Down Expand Up @@ -431,3 +422,15 @@ inline local_time to_local_time(timezone const& tz, unixtime_t const t) {
}

} // namespace nigiri

template <>
struct fmt::formatter<nigiri::duration_t> : ostream_formatter {};

template <>
struct fmt::formatter<nigiri::unixtime_t> : ostream_formatter {};

template <>
struct fmt::formatter<nigiri::debug> : ostream_formatter {};

template <>
struct fmt::formatter<nigiri::delta> : ostream_formatter {};
16 changes: 16 additions & 0 deletions src/routing/clasz_mask.cc
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
#include "nigiri/routing/clasz_mask.h"

namespace nigiri::routing {

std::string to_str(clasz_mask_t const x) {
auto s = std::string{};
s += ", x=" + std::to_string(x);
for (auto i = std::underlying_type_t<clasz>{0U};
i != sizeof(clasz_mask_t) * 8; ++i) {
auto const allowed = is_allowed(x, clasz{i});
s.insert(0, 1, allowed ? '1' : '0');
}
return s;
}

} // namespace nigiri::routing
11 changes: 7 additions & 4 deletions test/raptor_search.cc
Original file line number Diff line number Diff line change
Expand Up @@ -57,15 +57,17 @@ pareto_set<routing::journey> raptor_search(timetable const& tt,
std::string_view from,
std::string_view to,
routing::start_time_t time,
direction const search_dir) {
direction const search_dir,
routing::clasz_mask_t const mask) {
auto const src = source_idx_t{0};
auto q = routing::query{
.start_time_ = time,
.start_ = {{tt.locations_.location_id_to_idx_.at({from, src}), 0_minutes,
0U}},
.destination_ = {{tt.locations_.location_id_to_idx_.at({to, src}),
0_minutes, 0U}},
.prf_idx_ = 0};
.prf_idx_ = 0,
.allowed_claszes_ = mask};
return raptor_search(tt, rtt, std::move(q), search_dir);
}

Expand All @@ -74,9 +76,10 @@ pareto_set<routing::journey> raptor_search(timetable const& tt,
std::string_view from,
std::string_view to,
std::string_view time,
direction const search_dir) {
direction const search_dir,
routing::clasz_mask_t mask) {
return raptor_search(tt, rtt, from, to, parse_time(time, "%Y-%m-%d %H:%M %Z"),
search_dir);
search_dir, mask);
}

pareto_set<routing::journey> raptor_intermodal_search(
Expand Down
28 changes: 16 additions & 12 deletions test/raptor_search.h
Original file line number Diff line number Diff line change
Expand Up @@ -9,19 +9,23 @@ struct rt_timetable;

namespace nigiri::test {

pareto_set<routing::journey> raptor_search(timetable const&,
rt_timetable const*,
std::string_view from,
std::string_view to,
std::string_view time,
direction = direction::kForward);
pareto_set<routing::journey> raptor_search(
timetable const&,
rt_timetable const*,
std::string_view from,
std::string_view to,
std::string_view time,
direction = direction::kForward,
routing::clasz_mask_t mask = routing::all_clasz_allowed());

pareto_set<routing::journey> raptor_search(timetable const&,
rt_timetable const*,
std::string_view from,
std::string_view to,
routing::start_time_t,
direction = direction::kForward);
pareto_set<routing::journey> raptor_search(
timetable const&,
rt_timetable const*,
std::string_view from,
std::string_view to,
routing::start_time_t,
direction = direction::kForward,
routing::clasz_mask_t mask = routing::all_clasz_allowed());

pareto_set<routing::journey> raptor_search(timetable const&,
rt_timetable const*,
Expand Down
Loading

0 comments on commit bf9b9e9

Please sign in to comment.