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>
|
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 &forward_heap,
|
||||||
typename SearchEngineData<Algorithm>::QueryHeap &reverse_heap,
|
const NodeID node,
|
||||||
NodeID &middle_node,
|
const EdgeWeight weight,
|
||||||
EdgeWeight &path_upper_bound,
|
Args... args)
|
||||||
const bool force_loop_forward,
|
|
||||||
const bool force_loop_reverse,
|
|
||||||
Args... args)
|
|
||||||
{
|
{
|
||||||
const auto &partition = facade.GetMultiLevelPartition();
|
const auto &partition = facade.GetMultiLevelPartition();
|
||||||
const auto &cells = facade.GetCellStorage();
|
const auto &cells = facade.GetCellStorage();
|
||||||
const auto &metric = facade.GetCellMetric();
|
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...);
|
const auto level = getNodeQueryLevel(partition, node, args...);
|
||||||
|
|
||||||
if (level >= 1 && !forward_heap.GetData(node).from_clique_arc)
|
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.
|
// 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,
|
// 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
|
// and overlay node ids otherwise. We then have to unpack the overlay clique
|
||||||
|
@ -145,7 +145,8 @@ class SVGPrinter (gdb.Command):
|
|||||||
self.to_svg = {
|
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::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::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
|
@staticmethod
|
||||||
@ -258,17 +259,27 @@ class SVGPrinter (gdb.Command):
|
|||||||
geometry_first = geometry['_M_impl']['_M_start']
|
geometry_first = geometry['_M_impl']['_M_start']
|
||||||
for segment, weight in enumerate(iterate(weights)):
|
for segment, weight in enumerate(iterate(weights)):
|
||||||
ref = 's' + str(node) + '.' + str(segment)
|
ref = 's' + str(node) + '.' + str(segment)
|
||||||
result += '<path id="' + ref + '" class="segment" d="' \
|
fr = lonlat(call(facade, 'GetCoordinateOfNode', geometry_first.dereference()))
|
||||||
+ 'M' + t(lonlat(call(facade, 'GetCoordinateOfNode', geometry_first.dereference()))) + ' ' \
|
to = lonlat(call(facade, 'GetCoordinateOfNode', (geometry_first+1).dereference()))
|
||||||
+ 'L' + t(lonlat(call(facade, 'GetCoordinateOfNode', (geometry_first+1).dereference()))) + '" />'\
|
if fr == to:
|
||||||
+ '<text class="segment weight ' + direction + '">'\
|
## node penalty on zero length segment (traffic light)
|
||||||
+ '<textPath xlink:href="#' + ref + '" startOffset="50%">' \
|
result += '<text class="segment weight ' + direction \
|
||||||
+ segment_weight(weight) + '</textPath></text>\n'
|
+ '" 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(fr) + ' ' \
|
||||||
|
+ 'L' + t(to) + '" />'\
|
||||||
|
+ '<text class="segment weight ' + direction + '">'\
|
||||||
|
+ '<textPath xlink:href="#' + ref + '" startOffset="50%">' \
|
||||||
|
+ segment_weight(weight) + '</textPath></text>\n'
|
||||||
geometry_first += 1
|
geometry_first += 1
|
||||||
|
|
||||||
## add edge-based edges
|
## add edge-based edges
|
||||||
s0, s1 = geometry['_M_impl']['_M_start'].dereference(), (geometry['_M_impl']['_M_start'] + 1).dereference()
|
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)
|
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'
|
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')
|
target_geometry = SVGPrinter.getByGeometryId(facade, call(facade, 'GetGeometryIndex', target), 'Geometry')
|
||||||
@ -323,7 +334,8 @@ class SVGPrinter (gdb.Command):
|
|||||||
re_float = '[-+]?[0-9]*\.?[0-9]+'
|
re_float = '[-+]?[0-9]*\.?[0-9]+'
|
||||||
bbox = re.search('(' + re_float + '),(' + re_float + ');(' + re_float + '),(' + re_float +')', arg)
|
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]
|
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)
|
self.show_svg(svg, width, height)
|
||||||
except KeyError as e:
|
except KeyError as e:
|
||||||
print ('no SVG printer for: ' + str(e))
|
print ('no SVG printer for: ' + str(e))
|
||||||
|
@ -120,13 +120,28 @@ addLoopWeight(const DataFacade<mld::Algorithm> &, const NodeID, EdgeWeight &, Ed
|
|||||||
return false;
|
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,
|
void relaxOutgoingEdges(const DataFacade<mld::Algorithm> &facade,
|
||||||
const NodeID node,
|
const NodeID node,
|
||||||
const EdgeWeight weight,
|
const EdgeWeight weight,
|
||||||
const EdgeDuration duration,
|
const EdgeDuration duration,
|
||||||
typename SearchEngineData<mld::Algorithm>::ManyToManyQueryHeap &query_heap,
|
typename SearchEngineData<mld::Algorithm>::ManyToManyQueryHeap &query_heap,
|
||||||
const PhantomNode &phantom_node)
|
Args... args)
|
||||||
{
|
{
|
||||||
BOOST_ASSERT(!facade.ExcludeNode(node));
|
BOOST_ASSERT(!facade.ExcludeNode(node));
|
||||||
|
|
||||||
@ -134,13 +149,7 @@ void relaxOutgoingEdges(const DataFacade<mld::Algorithm> &facade,
|
|||||||
const auto &cells = facade.GetCellStorage();
|
const auto &cells = facade.GetCellStorage();
|
||||||
const auto &metric = facade.GetCellMetric();
|
const auto &metric = facade.GetCellMetric();
|
||||||
|
|
||||||
auto highest_diffrent_level = [&partition, node](const SegmentID &phantom_node) {
|
const auto level = getNodeQueryLevel(partition, node, args...);
|
||||||
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 &node_data = query_heap.GetData(node);
|
const auto &node_data = query_heap.GetData(node);
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user