Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

clasz routing search filter #72

Merged
merged 1 commit into from
Feb 27, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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
Loading