Refactor to reuse relaxOutgoingEdges in many-to-many plugin
This commit is contained in:
parent
2ed4f6eb0c
commit
454487dd41
@ -132,44 +132,16 @@ retrievePackedPathFromHeap(const SearchEngineData<Algorithm>::QueryHeap &forward
|
||||
}
|
||||
|
||||
template <bool DIRECTION, typename Algorithm, typename... Args>
|
||||
void routingStep(const DataFacade<Algorithm> &facade,
|
||||
void relaxOutgoingEdges(const DataFacade<Algorithm> &facade,
|
||||
typename SearchEngineData<Algorithm>::QueryHeap &forward_heap,
|
||||
typename SearchEngineData<Algorithm>::QueryHeap &reverse_heap,
|
||||
NodeID &middle_node,
|
||||
EdgeWeight &path_upper_bound,
|
||||
const bool force_loop_forward,
|
||||
const bool force_loop_reverse,
|
||||
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<Algorithm> &facade,
|
||||
}
|
||||
}
|
||||
|
||||
template <bool DIRECTION, typename Algorithm, typename... Args>
|
||||
void routingStep(const DataFacade<Algorithm> &facade,
|
||||
typename SearchEngineData<Algorithm>::QueryHeap &forward_heap,
|
||||
typename SearchEngineData<Algorithm>::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<DIRECTION>(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
|
||||
|
@ -145,7 +145,8 @@ class SVGPrinter (gdb.Command):
|
||||
self.to_svg = {
|
||||
'const osrm::engine::datafacade::ContiguousInternalMemoryDataFacade<osrm::engine::routing_algorithms::ch::Algorithm> &': self.Facade,
|
||||
'const osrm::engine::datafacade::ContiguousInternalMemoryDataFacade<osrm::engine::routing_algorithms::corech::Algorithm> &': self.Facade,
|
||||
'const osrm::engine::datafacade::ContiguousInternalMemoryDataFacade<osrm::engine::routing_algorithms::mld::Algorithm> &': self.Facade}
|
||||
'const osrm::engine::datafacade::ContiguousInternalMemoryDataFacade<osrm::engine::routing_algorithms::mld::Algorithm> &': self.Facade,
|
||||
'osrm::engine::DataFacade': self.Facade}
|
||||
|
||||
|
||||
@staticmethod
|
||||
@ -258,9 +259,19 @@ class SVGPrinter (gdb.Command):
|
||||
geometry_first = geometry['_M_impl']['_M_start']
|
||||
for segment, weight in enumerate(iterate(weights)):
|
||||
ref = 's' + str(node) + '.' + str(segment)
|
||||
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 += '<text class="segment weight ' + direction \
|
||||
+ '" x="' + str(tx(fr[0])) + '" y="' + str(ty(fr[1])) \
|
||||
+ '" font="Arial" font-size="32" rotate="0" text-anchor="middle" >' \
|
||||
+ '🚦 ' + segment_weight(weight) + '</text>\n'
|
||||
else:
|
||||
## normal segment
|
||||
result += '<path id="' + ref + '" class="segment" d="' \
|
||||
+ 'M' + t(lonlat(call(facade, 'GetCoordinateOfNode', geometry_first.dereference()))) + ' ' \
|
||||
+ 'L' + t(lonlat(call(facade, 'GetCoordinateOfNode', (geometry_first+1).dereference()))) + '" />'\
|
||||
+ 'M' + t(fr) + ' ' \
|
||||
+ 'L' + t(to) + '" />'\
|
||||
+ '<text class="segment weight ' + direction + '">'\
|
||||
+ '<textPath xlink:href="#' + ref + '" startOffset="50%">' \
|
||||
+ segment_weight(weight) + '</textPath></text>\n'
|
||||
@ -268,7 +279,7 @@ class SVGPrinter (gdb.Command):
|
||||
|
||||
## 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))
|
||||
|
@ -120,13 +120,28 @@ addLoopWeight(const DataFacade<mld::Algorithm> &, const NodeID, EdgeWeight &, Ed
|
||||
return false;
|
||||
}
|
||||
|
||||
template <bool DIRECTION>
|
||||
template <typename MultiLevelPartition>
|
||||
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 <bool DIRECTION, typename... Args>
|
||||
void relaxOutgoingEdges(const DataFacade<mld::Algorithm> &facade,
|
||||
const NodeID node,
|
||||
const EdgeWeight weight,
|
||||
const EdgeDuration duration,
|
||||
typename SearchEngineData<mld::Algorithm>::ManyToManyQueryHeap &query_heap,
|
||||
const PhantomNode &phantom_node)
|
||||
Args... args)
|
||||
{
|
||||
BOOST_ASSERT(!facade.ExcludeNode(node));
|
||||
|
||||
@ -134,13 +149,7 @@ void relaxOutgoingEdges(const DataFacade<mld::Algorithm> &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);
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user