diff --git a/include/customizer/edge_based_graph.hpp b/include/customizer/edge_based_graph.hpp index e2526f163..8414c5942 100644 --- a/include/customizer/edge_based_graph.hpp +++ b/include/customizer/edge_based_graph.hpp @@ -46,6 +46,10 @@ class MultiLevelGraph : public partitioner::MultiLevelGraph using Vector = util::ViewOrVector; public: + using NodeArrayEntry = typename SuperT::NodeArrayEntry; + using EdgeArrayEntry = typename SuperT::EdgeArrayEntry; + using EdgeOffset = typename SuperT::EdgeOffset; + MultiLevelGraph() = default; MultiLevelGraph(MultiLevelGraph &&) = default; MultiLevelGraph(const MultiLevelGraph &) = default; @@ -74,9 +78,9 @@ class MultiLevelGraph : public partitioner::MultiLevelGraph node_array_, - Vector edge_array_, - Vector node_to_edge_offset_, + MultiLevelGraph(Vector node_array_, + Vector edge_array_, + Vector node_to_edge_offset_, Vector node_weights_, Vector node_durations_, Vector is_forward_edge_, diff --git a/include/partitioner/multi_level_graph.hpp b/include/partitioner/multi_level_graph.hpp index f712e6d18..2d5635790 100644 --- a/include/partitioner/multi_level_graph.hpp +++ b/include/partitioner/multi_level_graph.hpp @@ -149,7 +149,7 @@ class MultiLevelGraph : public util::StaticGraph return max_border_node_id; } - auto data() && + auto data() && // rvalue ref-qualifier is a safety-belt { return std::make_tuple(std::move(SuperT::node_array), std::move(SuperT::edge_array), diff --git a/src/engine/routing_algorithms/alternative_path_mld.cpp b/src/engine/routing_algorithms/alternative_path_mld.cpp index 76de45971..7fbe37dab 100644 --- a/src/engine/routing_algorithms/alternative_path_mld.cpp +++ b/src/engine/routing_algorithms/alternative_path_mld.cpp @@ -470,10 +470,10 @@ RandIt filterUnpackedPathsBySharing(RandIt first, if (shortest_path.edges.empty()) return last; - std::unordered_set edges; - edges.reserve(size * shortest_path.edges.size() * (1.25)); + std::unordered_set nodes; + nodes.reserve(size * shortest_path.nodes.size() * (1.25)); - edges.insert(begin(shortest_path.edges), end(shortest_path.edges)); + nodes.insert(begin(shortest_path.nodes), end(shortest_path.nodes)); const auto over_sharing_limit = [&](auto &unpacked) { if (unpacked.edges.empty()) @@ -482,20 +482,20 @@ RandIt filterUnpackedPathsBySharing(RandIt first, } EdgeWeight total_duration = 0; - const auto add_if_seen = [&](const EdgeWeight duration, const EdgeID edge) { - auto edge_duration = facade.GetEdgeData(edge).duration; - total_duration += edge_duration; - if (edges.count(edge) > 0) + const auto add_if_seen = [&](const EdgeWeight duration, const NodeID node) { + auto node_duration = facade.GetNodeDuration(node); + total_duration += node_duration; + if (nodes.count(node) > 0) { - return duration + edge_duration; + return duration + node_duration; } return duration; }; - const auto shared_weight = - std::accumulate(begin(unpacked.edges), end(unpacked.edges), EdgeWeight{0}, add_if_seen); + const auto shared_duration = std::accumulate( + begin(unpacked.nodes), end(unpacked.nodes), EdgeDuration{0}, add_if_seen); - unpacked.sharing = shared_weight / static_cast(total_duration); + unpacked.sharing = shared_duration / static_cast(total_duration); BOOST_ASSERT(unpacked.sharing >= 0.); BOOST_ASSERT(unpacked.sharing <= 1.); @@ -505,7 +505,7 @@ RandIt filterUnpackedPathsBySharing(RandIt first, } else { - edges.insert(begin(unpacked.edges), end(unpacked.edges)); + nodes.insert(begin(unpacked.nodes), end(unpacked.nodes)); return false; } }; diff --git a/src/engine/routing_algorithms/many_to_many_mld.cpp b/src/engine/routing_algorithms/many_to_many_mld.cpp index 6f8300d9a..05a8a28d6 100644 --- a/src/engine/routing_algorithms/many_to_many_mld.cpp +++ b/src/engine/routing_algorithms/many_to_many_mld.cpp @@ -182,16 +182,15 @@ void relaxOutgoingEdges(const DataFacade &facade, } const auto turn_id = data.turn_id; - const auto node_weight = - facade.GetNodeWeight(DIRECTION == FORWARD_DIRECTION ? node : to); - const auto node_duration = facade.GetNodeDuration( - DIRECTION == FORWARD_DIRECTION ? node : to); // TODO: remove later - const auto edge_weight = node_weight + facade.GetWeightPenaltyForEdgeID(turn_id); - const auto edge_duration = node_duration + facade.GetDurationPenaltyForEdgeID(turn_id); + const auto node_id = DIRECTION == FORWARD_DIRECTION ? node : facade.GetTarget(edge); + const auto node_weight = facade.GetNodeWeight(node_id); + const auto node_duration = facade.GetNodeDuration(node_id); + const auto turn_weight = node_weight + facade.GetWeightPenaltyForEdgeID(turn_id); + const auto turn_duration = node_duration + facade.GetDurationPenaltyForEdgeID(turn_id); - BOOST_ASSERT_MSG(edge_weight > 0, "edge_weight invalid"); - const auto to_weight = weight + edge_weight; - const auto to_duration = duration + edge_duration; + BOOST_ASSERT_MSG(node_weight + turn_weight > 0, "edge weight is invalid"); + const auto to_weight = weight + turn_weight; + const auto to_duration = duration + turn_duration; // New Node discovered -> Add to Heap + Node Info Storage if (!query_heap.WasInserted(to)) @@ -315,15 +314,10 @@ oneToManySearch(SearchEngineData &engine_working_data, : facade.IsBackwardEdge(edge)) { const auto turn_id = data.turn_id; - const auto edge_weight = - initial_weight + - facade.GetNodeWeight(DIRECTION == FORWARD_DIRECTION ? node - : facade.GetTarget(edge)) + - facade.GetWeightPenaltyForEdgeID(turn_id); - const auto edge_duration = initial_duration + - +facade.GetNodeDuration(DIRECTION == FORWARD_DIRECTION - ? node - : facade.GetTarget(edge)) + + const auto node_id = DIRECTION == FORWARD_DIRECTION ? node : facade.GetTarget(edge); + const auto edge_weight = initial_weight + facade.GetNodeWeight(node_id) + + facade.GetWeightPenaltyForEdgeID(turn_id); + const auto edge_duration = initial_duration + facade.GetNodeDuration(node_id) + facade.GetDurationPenaltyForEdgeID(turn_id); query_heap.Insert(facade.GetTarget(edge), edge_weight, {node, edge_duration}); diff --git a/src/extractor/edge_based_graph_factory.cpp b/src/extractor/edge_based_graph_factory.cpp index 55fd5c9c2..85c34bda8 100644 --- a/src/extractor/edge_based_graph_factory.cpp +++ b/src/extractor/edge_based_graph_factory.cpp @@ -145,9 +145,13 @@ NBGToEBG EdgeBasedGraphFactory::InsertEdgeBasedNode(const NodeID node_u, const N BOOST_ASSERT(nbe_to_ebn_mapping[edge_id_1] != SPECIAL_NODEID || nbe_to_ebn_mapping[edge_id_2] != SPECIAL_NODEID); - // TODO: use the sign bit to distinguish oneway streets that must - // have INVALID_EDGE_WEIGHT node weight values to enforce loop edges - // in contraction + // ⚠ Use the sign bit of node weights to distinguish oneway streets: + // * MSB is set - a node corresponds to a one-way street + // * MSB is clear - a node corresponds to a bidirectional street + // Before using node weights data values must be adjusted: + // * in contraction if MSB is set the node weight is INVALID_EDGE_WEIGHT. + // This adjustment is needed to enforce loop creation for oneways. + // * in other cases node weights must be masked with 0x7fffffff to clear MSB if (nbe_to_ebn_mapping[edge_id_1] != SPECIAL_NODEID && nbe_to_ebn_mapping[edge_id_2] == SPECIAL_NODEID) m_edge_based_node_weights[nbe_to_ebn_mapping[edge_id_1]] |= 0x80000000;