Preserve heap state in map matching

This commit is contained in:
Patrick Niklaus
2018-04-27 05:36:52 +00:00
committed by Patrick Niklaus
parent 89fabc1b9c
commit b630b4e32a
7 changed files with 185 additions and 98 deletions
@@ -242,7 +242,8 @@ void calculateDistances(typename SearchEngineData<ch::Algorithm>::ManyToManyQuer
{
EdgeDistance annotation =
ch::calculateEBGNodeAnnotations(facade, packed_leg.begin(), packed_leg.end());
adjustPathDistanceToPhantomNodes(packed_leg, source_phantom, target_phantom, annotation);
annotation = adjustPathDistanceToPhantomNodes(
packed_leg, source_phantom, target_phantom, annotation);
distances_table[row_index * number_of_targets + column_index] = annotation;
}
+14 -8
View File
@@ -227,6 +227,9 @@ SubMatchingList mapMatching(SearchEngineData<Algorithm> &engine_working_data,
{
continue;
}
forward_heap.Clear();
const auto &source_phantom = prev_unbroken_timestamps_list[s].phantom_node;
insertSourceInHeap(forward_heap, source_phantom);
for (const auto s_prime : util::irange<std::size_t>(0UL, current_viterbi.size()))
{
@@ -237,14 +240,17 @@ SubMatchingList mapMatching(SearchEngineData<Algorithm> &engine_working_data,
continue;
}
double network_distance =
getNetworkDistance(engine_working_data,
facade,
forward_heap,
reverse_heap,
prev_unbroken_timestamps_list[s].phantom_node,
current_timestamps_list[s_prime].phantom_node,
weight_upper_bound);
reverse_heap.Clear();
const auto &target_phantom = current_timestamps_list[s_prime].phantom_node;
insertTargetInHeap(reverse_heap, target_phantom);
double network_distance = getNetworkDistance(engine_working_data,
facade,
forward_heap,
reverse_heap,
source_phantom,
target_phantom,
weight_upper_bound);
// get distance diff between loc1/2 and locs/s_prime
const auto d_t = std::abs(network_distance - haversine_distance);
+11 -4
View File
@@ -33,11 +33,12 @@ bool needsLoopBackwards(const PhantomNodes &phantoms)
return needsLoopBackwards(phantoms.source_phantom, phantoms.target_phantom);
}
void adjustPathDistanceToPhantomNodes(const std::vector<NodeID> &path,
const PhantomNode &source_phantom,
const PhantomNode &target_phantom,
EdgeDistance &distance)
EdgeDistance adjustPathDistanceToPhantomNodes(const std::vector<NodeID> &path,
const PhantomNode &source_phantom,
const PhantomNode &target_phantom,
const EdgeDistance uncorrected_distance)
{
EdgeDistance distance = uncorrected_distance;
if (!path.empty())
{
@@ -97,6 +98,12 @@ void adjustPathDistanceToPhantomNodes(const std::vector<NodeID> &path,
distance = target_phantom.GetReverseDistance() - source_phantom.GetReverseDistance();
}
}
BOOST_ASSERT_MSG(distance >= 0 || distance > -1.0f,
"Distance correction generated negative number");
// guard against underflow errors caused by rounding
distance = std::max(EdgeDistance{0}, distance);
return distance;
}
} // namespace routing_algorithms
@@ -100,7 +100,7 @@ void search(SearchEngineData<Algorithm> & /*engine_working_data*/,
const PhantomNodes & /*phantom_nodes*/,
const EdgeWeight weight_upper_bound)
{
if (forward_heap.Empty() || reverse_heap.Empty())
if (forward_heap.Empty() && reverse_heap.Empty())
{
weight = INVALID_EDGE_WEIGHT;
return;
@@ -110,10 +110,14 @@ void search(SearchEngineData<Algorithm> & /*engine_working_data*/,
weight = weight_upper_bound;
// get offset to account for offsets on phantom nodes on compressed edges
const auto min_edge_offset = std::min(0, forward_heap.MinKey());
BOOST_ASSERT(min_edge_offset <= 0);
EdgeWeight min_edge_offset = 0;
if (forward_heap.Size() > 0)
{
min_edge_offset = std::min(min_edge_offset, forward_heap.MinKey());
BOOST_ASSERT(min_edge_offset <= 0);
}
// we only every insert negative offsets for nodes in the forward heap
BOOST_ASSERT(reverse_heap.MinKey() >= 0);
BOOST_ASSERT(reverse_heap.Empty() || reverse_heap.MinKey() >= 0);
// run two-Target Dijkstra routing step.
while (0 < (forward_heap.Size() + reverse_heap.Size()))
@@ -176,11 +180,6 @@ double getNetworkDistance(SearchEngineData<Algorithm> &engine_working_data,
const PhantomNode &target_phantom,
EdgeWeight weight_upper_bound)
{
forward_heap.Clear();
reverse_heap.Clear();
insertNodesInHeaps(forward_heap, reverse_heap, {source_phantom, target_phantom});
EdgeWeight weight = INVALID_EDGE_WEIGHT;
std::vector<NodeID> packed_path;
search(engine_working_data,
@@ -199,8 +198,6 @@ double getNetworkDistance(SearchEngineData<Algorithm> &engine_working_data,
return std::numeric_limits<double>::max();
}
BOOST_ASSERT(nodes_number > 0);
EdgeDistance distance = 0;
std::vector<NodeID> unpacked_nodes;
@@ -208,24 +205,24 @@ double getNetworkDistance(SearchEngineData<Algorithm> &engine_working_data,
if (!packed_path.empty())
{
unpacked_nodes.push_back(packed_path.front());
unpackPath(facade,
packed_path.begin(),
packed_path.end(),
[&](std::pair<NodeID, NodeID> &edge, const auto &) {
BOOST_ASSERT(edge.first == unpacked_nodes.back());
unpacked_nodes.push_back(edge.second);
});
unpackPath(
facade, packed_path.begin(), packed_path.end(), [&](const auto &edge, const auto &) {
BOOST_ASSERT(edge.first == unpacked_nodes.back());
unpacked_nodes.push_back(edge.second);
});
for (auto node_iter = unpacked_nodes.begin(); node_iter != std::prev(unpacked_nodes.end());
node_iter++)
{
distance += computeEdgeDistance(facade, *node_iter);
}
distance = std::accumulate(unpacked_nodes.begin(),
std::prev(unpacked_nodes.end()),
EdgeDistance{0},
[&](const EdgeDistance distance, const auto node_id) {
return distance + computeEdgeDistance(facade, node_id);
});
}
adjustPathDistanceToPhantomNodes(unpacked_nodes, source_phantom, target_phantom, distance);
distance =
adjustPathDistanceToPhantomNodes(unpacked_nodes, source_phantom, target_phantom, distance);
return distance / 10.;
return distance;
}
} // namespace ch
+1 -1
View File
@@ -25,7 +25,7 @@ namespace
// earth radius varies between 6,356.750-6,378.135 km (3,949.901-3,963.189mi)
// The IUGG value for the equatorial radius is 6378.137 km (3963.19 miles)
const constexpr long double EARTH_RADIUS = 6372797.560856;
const constexpr double EARTH_RADIUS = 6372797.560856;
class CheapRulerContainer
{