Candidate query for match is now only depending on gps_precision
This commit is contained in:
@@ -91,13 +91,23 @@ template <class CandidateLists> struct HiddenMarkovModel
|
||||
: breakage(candidates_list.size()), candidates_list(candidates_list),
|
||||
emission_log_probability(emission_log_probability)
|
||||
{
|
||||
for (const auto &l : candidates_list)
|
||||
viterbi.resize(candidates_list.size());
|
||||
parents.resize(candidates_list.size());
|
||||
path_lengths.resize(candidates_list.size());
|
||||
suspicious.resize(candidates_list.size());
|
||||
pruned.resize(candidates_list.size());
|
||||
for (const auto i : osrm::irange<std::size_t>(0u, candidates_list.size()))
|
||||
{
|
||||
viterbi.emplace_back(l.size());
|
||||
parents.emplace_back(l.size());
|
||||
path_lengths.emplace_back(l.size());
|
||||
suspicious.emplace_back(l.size());
|
||||
pruned.emplace_back(l.size());
|
||||
const auto& num_candidates = candidates_list[i].size();
|
||||
// add empty vectors
|
||||
if (num_candidates > 0)
|
||||
{
|
||||
viterbi[i].resize(num_candidates);
|
||||
parents[i].resize(num_candidates);
|
||||
path_lengths[i].resize(num_candidates);
|
||||
suspicious[i].resize(num_candidates);
|
||||
pruned[i].resize(num_candidates);
|
||||
}
|
||||
}
|
||||
|
||||
clear(0);
|
||||
@@ -121,10 +131,11 @@ template <class CandidateLists> struct HiddenMarkovModel
|
||||
|
||||
std::size_t initialize(std::size_t initial_timestamp)
|
||||
{
|
||||
BOOST_ASSERT(initial_timestamp < candidates_list.size());
|
||||
|
||||
auto num_points = candidates_list.size();
|
||||
do
|
||||
{
|
||||
BOOST_ASSERT(initial_timestamp < num_points);
|
||||
|
||||
for (const auto s : osrm::irange<std::size_t>(0u, viterbi[initial_timestamp].size()))
|
||||
{
|
||||
viterbi[initial_timestamp][s] =
|
||||
@@ -139,9 +150,9 @@ template <class CandidateLists> struct HiddenMarkovModel
|
||||
}
|
||||
|
||||
++initial_timestamp;
|
||||
} while (breakage[initial_timestamp - 1]);
|
||||
} while (initial_timestamp < num_points && breakage[initial_timestamp - 1]);
|
||||
|
||||
if (initial_timestamp >= viterbi.size())
|
||||
if (initial_timestamp >= num_points)
|
||||
{
|
||||
return osrm::matching::INVALID_STATE;
|
||||
}
|
||||
|
||||
@@ -783,32 +783,18 @@ class StaticRTree
|
||||
// Returns elements within max_distance.
|
||||
// If the minium of elements could not be found in the search radius, widen
|
||||
// it until the minimum can be satisfied.
|
||||
// At the number of returned nodes is capped at the given maximum.
|
||||
bool IncrementalFindPhantomNodeForCoordinateWithDistance(
|
||||
const FixedPointCoordinate &input_coordinate,
|
||||
std::vector<std::pair<PhantomNode, double>> &result_phantom_node_vector,
|
||||
const double max_distance,
|
||||
const unsigned min_number_of_phantom_nodes,
|
||||
const unsigned max_number_of_phantom_nodes,
|
||||
const unsigned max_checked_elements = 4 * LEAF_NODE_SIZE)
|
||||
{
|
||||
unsigned inspected_elements = 0;
|
||||
unsigned number_of_elements_from_big_cc = 0;
|
||||
unsigned number_of_elements_from_tiny_cc = 0;
|
||||
|
||||
// is true if a big cc was added to the queue to we also have a lower bound
|
||||
// for them. it actives pruning for big components
|
||||
bool has_big_cc = false;
|
||||
|
||||
unsigned pruned_elements = 0;
|
||||
|
||||
std::pair<double, double> projected_coordinate = {
|
||||
mercator::lat2y(input_coordinate.lat / COORDINATE_PRECISION),
|
||||
input_coordinate.lon / COORDINATE_PRECISION};
|
||||
|
||||
// upper bound pruning technique
|
||||
upper_bound<float> pruning_bound(max_number_of_phantom_nodes);
|
||||
|
||||
// initialize queue with root element
|
||||
std::priority_queue<IncrementalQueryCandidate> traversal_queue;
|
||||
traversal_queue.emplace(0.f, m_search_tree[0]);
|
||||
@@ -818,6 +804,11 @@ class StaticRTree
|
||||
const IncrementalQueryCandidate current_query_node = traversal_queue.top();
|
||||
traversal_queue.pop();
|
||||
|
||||
if (current_query_node.min_dist > max_distance || inspected_elements >= max_checked_elements)
|
||||
{
|
||||
break;
|
||||
}
|
||||
|
||||
if (current_query_node.node.template is<TreeNode>())
|
||||
{ // current object is a tree node
|
||||
const TreeNode ¤t_tree_node =
|
||||
@@ -839,16 +830,9 @@ class StaticRTree
|
||||
// distance must be non-negative
|
||||
BOOST_ASSERT(0.f <= current_perpendicular_distance);
|
||||
|
||||
if (pruning_bound.get() >= current_perpendicular_distance ||
|
||||
(!has_big_cc && !current_edge.is_in_tiny_cc()))
|
||||
if (current_perpendicular_distance <= max_distance)
|
||||
{
|
||||
pruning_bound.insert(current_perpendicular_distance);
|
||||
traversal_queue.emplace(current_perpendicular_distance, current_edge);
|
||||
has_big_cc = has_big_cc || !current_edge.is_in_tiny_cc();
|
||||
}
|
||||
else
|
||||
{
|
||||
++pruned_elements;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -865,7 +849,10 @@ class StaticRTree
|
||||
child_rectangle.GetMinDist(input_coordinate);
|
||||
BOOST_ASSERT(0.f <= lower_bound_to_element);
|
||||
|
||||
traversal_queue.emplace(lower_bound_to_element, child_tree_node);
|
||||
if (lower_bound_to_element <= max_distance)
|
||||
{
|
||||
traversal_queue.emplace(lower_bound_to_element, child_tree_node);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -876,14 +863,6 @@ class StaticRTree
|
||||
const EdgeDataT ¤t_segment =
|
||||
current_query_node.node.template get<EdgeDataT>();
|
||||
|
||||
// continue searching for the first segment from a big component
|
||||
if (number_of_elements_from_big_cc == 0 &&
|
||||
number_of_elements_from_tiny_cc >= max_number_of_phantom_nodes - 1 &&
|
||||
current_segment.is_in_tiny_cc())
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
// check if it is smaller than what we had before
|
||||
float current_ratio = 0.f;
|
||||
FixedPointCoordinate foot_point_coordinate_on_segment;
|
||||
@@ -894,9 +873,7 @@ class StaticRTree
|
||||
m_coordinate_list->at(current_segment.v), input_coordinate,
|
||||
projected_coordinate, foot_point_coordinate_on_segment, current_ratio);
|
||||
|
||||
if (number_of_elements_from_big_cc > 0 &&
|
||||
result_phantom_node_vector.size() >= min_number_of_phantom_nodes &&
|
||||
current_perpendicular_distance >= max_distance)
|
||||
if (current_perpendicular_distance >= max_distance)
|
||||
{
|
||||
traversal_queue = std::priority_queue<IncrementalQueryCandidate>{};
|
||||
continue;
|
||||
@@ -920,36 +897,14 @@ class StaticRTree
|
||||
// set forward and reverse weights on the phantom node
|
||||
SetForwardAndReverseWeightsOnPhantomNode(current_segment,
|
||||
result_phantom_node_vector.back().first);
|
||||
|
||||
// update counts on what we found from which result class
|
||||
if (current_segment.is_in_tiny_cc())
|
||||
{ // found an element in tiny component
|
||||
++number_of_elements_from_tiny_cc;
|
||||
}
|
||||
else
|
||||
{ // found an element in a big component
|
||||
++number_of_elements_from_big_cc;
|
||||
}
|
||||
}
|
||||
|
||||
// stop the search by flushing the queue
|
||||
if ((result_phantom_node_vector.size() >= max_number_of_phantom_nodes &&
|
||||
number_of_elements_from_big_cc > 0) ||
|
||||
inspected_elements >= max_checked_elements)
|
||||
if (inspected_elements >= max_checked_elements)
|
||||
{
|
||||
traversal_queue = std::priority_queue<IncrementalQueryCandidate>{};
|
||||
}
|
||||
}
|
||||
// SimpleLogger().Write() << "result_phantom_node_vector.size(): " <<
|
||||
// result_phantom_node_vector.size();
|
||||
// SimpleLogger().Write() << "max_number_of_phantom_nodes: " << max_number_of_phantom_nodes;
|
||||
// SimpleLogger().Write() << "number_of_elements_from_big_cc: " <<
|
||||
// number_of_elements_from_big_cc;
|
||||
// SimpleLogger().Write() << "number_of_elements_from_tiny_cc: " <<
|
||||
// number_of_elements_from_tiny_cc;
|
||||
// SimpleLogger().Write() << "inspected_elements: " << inspected_elements;
|
||||
// SimpleLogger().Write() << "max_checked_elements: " << max_checked_elements;
|
||||
// SimpleLogger().Write() << "pruned_elements: " << pruned_elements;
|
||||
|
||||
return !result_phantom_node_vector.empty();
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user