diff --git a/include/engine/routing_algorithms/routing_base_mld.hpp b/include/engine/routing_algorithms/routing_base_mld.hpp index 30a79f09d..e82e7e5bc 100644 --- a/include/engine/routing_algorithms/routing_base_mld.hpp +++ b/include/engine/routing_algorithms/routing_base_mld.hpp @@ -132,44 +132,16 @@ retrievePackedPathFromHeap(const SearchEngineData::QueryHeap &forward } template -void routingStep(const DataFacade &facade, - typename SearchEngineData::QueryHeap &forward_heap, - typename SearchEngineData::QueryHeap &reverse_heap, - NodeID &middle_node, - EdgeWeight &path_upper_bound, - const bool force_loop_forward, - const bool force_loop_reverse, - Args... args) +void relaxOutgoingEdges(const DataFacade &facade, + typename SearchEngineData::QueryHeap &forward_heap, + const NodeID node, + const EdgeWeight weight, + Args... args) { const auto &partition = facade.GetMultiLevelPartition(); const auto &cells = facade.GetCellStorage(); const auto &metric = facade.GetCellMetric(); - const auto node = forward_heap.DeleteMin(); - const auto weight = forward_heap.GetKey(node); - - BOOST_ASSERT(!facade.ExcludeNode(node)); - - // Upper bound for the path source -> target with - // weight(source -> node) = weight weight(to -> target) ≤ reverse_weight - // is weight + reverse_weight - // More tighter upper bound requires additional condition reverse_heap.WasRemoved(to) - // with weight(to -> target) = reverse_weight and all weights ≥ 0 - if (reverse_heap.WasInserted(node)) - { - auto reverse_weight = reverse_heap.GetKey(node); - auto path_weight = weight + reverse_weight; - - // if loops are forced, they are so at the source - if (!(force_loop_forward && forward_heap.GetData(node).parent == node) && - !(force_loop_reverse && reverse_heap.GetData(node).parent == node) && - (path_weight >= 0) && (path_weight < path_upper_bound)) - { - middle_node = node; - path_upper_bound = path_weight; - } - } - const auto level = getNodeQueryLevel(partition, node, args...); if (level >= 1 && !forward_heap.GetData(node).from_clique_arc) @@ -258,6 +230,45 @@ void routingStep(const DataFacade &facade, } } +template +void routingStep(const DataFacade &facade, + typename SearchEngineData::QueryHeap &forward_heap, + typename SearchEngineData::QueryHeap &reverse_heap, + NodeID &middle_node, + EdgeWeight &path_upper_bound, + const bool force_loop_forward, + const bool force_loop_reverse, + Args... args) +{ + const auto node = forward_heap.DeleteMin(); + const auto weight = forward_heap.GetKey(node); + + BOOST_ASSERT(!facade.ExcludeNode(node)); + + // Upper bound for the path source -> target with + // weight(source -> node) = weight weight(to -> target) ≤ reverse_weight + // is weight + reverse_weight + // More tighter upper bound requires additional condition reverse_heap.WasRemoved(to) + // with weight(to -> target) = reverse_weight and all weights ≥ 0 + if (reverse_heap.WasInserted(node)) + { + auto reverse_weight = reverse_heap.GetKey(node); + auto path_weight = weight + reverse_weight; + + // if loops are forced, they are so at the source + if (!(force_loop_forward && forward_heap.GetData(node).parent == node) && + !(force_loop_reverse && reverse_heap.GetData(node).parent == node) && + (path_weight >= 0) && (path_weight < path_upper_bound)) + { + middle_node = node; + path_upper_bound = path_weight; + } + } + + // Relax outgoing edges from node + relaxOutgoingEdges(facade, forward_heap, node, weight, args...); +} + // With (s, middle, t) we trace back the paths middle -> s and middle -> t. // This gives us a packed path (node ids) from the base graph around s and t, // and overlay node ids otherwise. We then have to unpack the overlay clique diff --git a/scripts/gdb_printers.py b/scripts/gdb_printers.py index 277f2ba79..65a469dc3 100644 --- a/scripts/gdb_printers.py +++ b/scripts/gdb_printers.py @@ -145,7 +145,8 @@ class SVGPrinter (gdb.Command): self.to_svg = { 'const osrm::engine::datafacade::ContiguousInternalMemoryDataFacade &': self.Facade, 'const osrm::engine::datafacade::ContiguousInternalMemoryDataFacade &': self.Facade, - 'const osrm::engine::datafacade::ContiguousInternalMemoryDataFacade &': self.Facade} + 'const osrm::engine::datafacade::ContiguousInternalMemoryDataFacade &': self.Facade, + 'osrm::engine::DataFacade': self.Facade} @staticmethod @@ -258,17 +259,27 @@ class SVGPrinter (gdb.Command): geometry_first = geometry['_M_impl']['_M_start'] for segment, weight in enumerate(iterate(weights)): ref = 's' + str(node) + '.' + str(segment) - result += ''\ - + ''\ - + '' \ - + segment_weight(weight) + '\n' + fr = lonlat(call(facade, 'GetCoordinateOfNode', geometry_first.dereference())) + to = lonlat(call(facade, 'GetCoordinateOfNode', (geometry_first+1).dereference())) + if fr == to: + ## node penalty on zero length segment (traffic light) + result += '' \ + + '🚦 ' + segment_weight(weight) + '\n' + else: + ## normal segment + result += ''\ + + ''\ + + '' \ + + segment_weight(weight) + '\n' geometry_first += 1 ## add edge-based edges s0, s1 = geometry['_M_impl']['_M_start'].dereference(), (geometry['_M_impl']['_M_start'] + 1).dereference() - for edge in range(call(facade, 'BeginEdges', node), call(facade, 'EndEdges', node)): + for edge in []: # range(call(facade, 'BeginEdges', node), call(facade, 'EndEdges', node)): adjust to GetAdjacentEdgeRange target, edge_data = call(facade, 'GetTarget', edge), call(facade, 'GetEdgeData', edge) direction = 'both' if edge_data['forward'] and edge_data['backward'] else 'forward' if edge_data['forward'] else 'backward' target_geometry = SVGPrinter.getByGeometryId(facade, call(facade, 'GetGeometryIndex', target), 'Geometry') @@ -323,7 +334,8 @@ class SVGPrinter (gdb.Command): re_float = '[-+]?[0-9]*\.?[0-9]+' bbox = re.search('(' + re_float + '),(' + re_float + ');(' + re_float + '),(' + re_float +')', arg) bbox = [float(x) for x in bbox.groups()] if bbox else [-180, -90, 180, 90] - svg = self.to_svg[str(val.type)](val, width, height, bbox) + type = val.type.target().unqualified() if val.type.code == gdb.TYPE_CODE_REF else val.type + svg = self.to_svg[str(type)](val, width, height, bbox) self.show_svg(svg, width, height) except KeyError as e: print ('no SVG printer for: ' + str(e)) diff --git a/src/engine/routing_algorithms/many_to_many.cpp b/src/engine/routing_algorithms/many_to_many.cpp index 0878ac379..3f7e4b15a 100644 --- a/src/engine/routing_algorithms/many_to_many.cpp +++ b/src/engine/routing_algorithms/many_to_many.cpp @@ -120,13 +120,28 @@ addLoopWeight(const DataFacade &, const NodeID, EdgeWeight &, Ed return false; } -template +template +inline LevelID getNodeQueryLevel(const MultiLevelPartition &partition, + NodeID node, + const PhantomNode &phantom_node) +{ + auto highest_diffrent_level = [&partition, node](const SegmentID &phantom_node) { + if (phantom_node.enabled) + return partition.GetHighestDifferentLevel(phantom_node.id, node); + return INVALID_LEVEL_ID; + }; + + return std::min(highest_diffrent_level(phantom_node.forward_segment_id), + highest_diffrent_level(phantom_node.reverse_segment_id)); +} + +template void relaxOutgoingEdges(const DataFacade &facade, const NodeID node, const EdgeWeight weight, const EdgeDuration duration, typename SearchEngineData::ManyToManyQueryHeap &query_heap, - const PhantomNode &phantom_node) + Args... args) { BOOST_ASSERT(!facade.ExcludeNode(node)); @@ -134,13 +149,7 @@ void relaxOutgoingEdges(const DataFacade &facade, const auto &cells = facade.GetCellStorage(); const auto &metric = facade.GetCellMetric(); - auto highest_diffrent_level = [&partition, node](const SegmentID &phantom_node) { - if (phantom_node.enabled) - return partition.GetHighestDifferentLevel(phantom_node.id, node); - return INVALID_LEVEL_ID; - }; - const auto level = std::min(highest_diffrent_level(phantom_node.forward_segment_id), - highest_diffrent_level(phantom_node.reverse_segment_id)); + const auto level = getNodeQueryLevel(partition, node, args...); const auto &node_data = query_heap.GetData(node);