Compare commits
2 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| eb50311d5e | |||
| 203314b1aa |
+593
-599
File diff suppressed because it is too large
Load Diff
@@ -460,19 +460,6 @@ void search(SearchEngineData<Algorithm> &engine_working_data,
|
||||
duration_upper_bound);
|
||||
}
|
||||
|
||||
inline std::vector<double> getNetworkDistances(
|
||||
SearchEngineData<Algorithm> &,
|
||||
const DataFacade<ch::Algorithm> &,
|
||||
SearchEngineData<Algorithm>::QueryHeap &,
|
||||
const std::vector<std::unique_ptr<typename SearchEngineData<Algorithm>::QueryHeap>> &,
|
||||
const PhantomNode &,
|
||||
const std::vector<PhantomNode> &,
|
||||
EdgeWeight /*duration_upper_bound*/ = INVALID_EDGE_WEIGHT)
|
||||
{
|
||||
std::vector<double> distances;
|
||||
return distances;
|
||||
}
|
||||
|
||||
// Requires the heaps for be empty
|
||||
// If heaps should be adjusted to be initialized outside of this function,
|
||||
// the addition of force_step parameters might be required
|
||||
|
||||
@@ -38,13 +38,10 @@ inline LevelID getNodeQueryLevel(const MultiLevelPartition &partition,
|
||||
return INVALID_LEVEL_ID;
|
||||
};
|
||||
|
||||
auto res = std::min(std::min(level(source.forward_segment_id, target.forward_segment_id),
|
||||
level(source.forward_segment_id, target.reverse_segment_id)),
|
||||
std::min(level(source.reverse_segment_id, target.forward_segment_id),
|
||||
level(source.reverse_segment_id, target.reverse_segment_id)));
|
||||
|
||||
// std::cerr << "OLD!!! " << (int)res << std::endl;
|
||||
return res;
|
||||
return std::min(std::min(level(source.forward_segment_id, target.forward_segment_id),
|
||||
level(source.forward_segment_id, target.reverse_segment_id)),
|
||||
std::min(level(source.reverse_segment_id, target.forward_segment_id),
|
||||
level(source.reverse_segment_id, target.reverse_segment_id)));
|
||||
}
|
||||
|
||||
template <typename MultiLevelPartition>
|
||||
@@ -95,7 +92,6 @@ inline LevelID getNodeQueryLevel(const MultiLevelPartition &partition,
|
||||
getNodeQueryLevel(partition, node, source, target));
|
||||
}));
|
||||
});
|
||||
// std::cerr << "NEW " << (int)min_level << std::endl;
|
||||
return min_level;
|
||||
}
|
||||
|
||||
@@ -144,8 +140,6 @@ inline LevelID getNodeQueryLevel(const MultiLevelPartition &partition,
|
||||
highest_different_level(phantom_node.reverse_segment_id));
|
||||
return std::min(current_level, highest_level);
|
||||
});
|
||||
|
||||
// std::cerr << "NEW!!! " << (int)node_level << std::endl;
|
||||
return node_level;
|
||||
}
|
||||
|
||||
@@ -306,6 +300,7 @@ void relaxOutgoingEdges(const DataFacade<Algorithm> &facade,
|
||||
const auto &metric = facade.GetCellMetric();
|
||||
|
||||
const auto level = getNodeQueryLevel(partition, heapNode.node, args...);
|
||||
|
||||
static constexpr auto IS_MAP_MATCHING =
|
||||
std::is_same_v<typename SearchEngineData<mld::Algorithm>::MapMatchingQueryHeap, Heap>;
|
||||
|
||||
@@ -462,15 +457,6 @@ void routingStep(const DataFacade<Algorithm> &facade,
|
||||
|
||||
BOOST_ASSERT(!facade.ExcludeNode(heapNode.node));
|
||||
|
||||
if (DIRECTION == FORWARD_DIRECTION)
|
||||
{
|
||||
// std::cerr << "FORWARDO " << heapNode.node << std::endl;
|
||||
}
|
||||
else
|
||||
{
|
||||
// std::cerr << "REVERSEO " << heapNode.node << std::endl;
|
||||
}
|
||||
|
||||
// Upper bound for the path source -> target with
|
||||
// weight(source -> node) = weight weight(to -> target) ≤ reverse_weight
|
||||
// is weight + reverse_weight
|
||||
@@ -658,7 +644,6 @@ searchDistance(SearchEngineData<Algorithm> &,
|
||||
|
||||
auto [middle, _] = *searchResult;
|
||||
|
||||
// std::cerr << "old " << middle << std::endl;
|
||||
auto distance = forward_heap.GetData(middle).distance + reverse_heap.GetData(middle).distance;
|
||||
|
||||
return distance;
|
||||
@@ -778,307 +763,6 @@ double getNetworkDistance(SearchEngineData<Algorithm> &engine_working_data,
|
||||
return from_alias<double>(distance);
|
||||
}
|
||||
|
||||
|
||||
template <typename Algorithm, typename Heap>
|
||||
std::vector<NodeID>
|
||||
runSearch2(const DataFacade<Algorithm> &facade,
|
||||
Heap &forward_heap,
|
||||
const std::vector<std::unique_ptr<Heap>> &reverse_heap,
|
||||
size_t candidatesCount,
|
||||
const std::vector<NodeID> &force_step_nodes,
|
||||
EdgeWeight weight_upper_bound,
|
||||
const PhantomEndpointCandidates &candidates)
|
||||
{
|
||||
// if (forward_heap.Empty() || reverse_heap.Empty())
|
||||
// {
|
||||
// return {};
|
||||
// }
|
||||
|
||||
// BOOST_ASSERT(!forward_heap.Empty() && forward_heap.MinKey() < INVALID_EDGE_WEIGHT);
|
||||
// BOOST_ASSERT(!reverse_heap.Empty() && reverse_heap.MinKey() < INVALID_EDGE_WEIGHT);
|
||||
|
||||
std::vector<NodeID> middles;
|
||||
std::vector<EdgeWeight> weights;
|
||||
|
||||
middles.resize(candidatesCount, SPECIAL_NODEID);
|
||||
weights.resize(candidatesCount, weight_upper_bound);
|
||||
|
||||
// run two-Target Dijkstra routing step.
|
||||
EdgeWeight forward_heap_min = forward_heap.MinKey();
|
||||
std::vector<EdgeWeight> reverse_heap_mins;
|
||||
for (size_t i = 0; i < candidatesCount; ++i)
|
||||
{
|
||||
reverse_heap_mins.push_back(reverse_heap[i]->MinKey());
|
||||
}
|
||||
|
||||
auto shouldContinue = [&]()
|
||||
{
|
||||
bool cont = false;
|
||||
for (size_t i = 0; i < candidatesCount; ++i)
|
||||
{
|
||||
if ((forward_heap.Size() + reverse_heap[i]->Size() > 0) &&
|
||||
(forward_heap_min + reverse_heap_mins[i]) < weights[i])
|
||||
{
|
||||
cont = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
return cont;
|
||||
};
|
||||
|
||||
bool cont = shouldContinue();
|
||||
while (cont)
|
||||
{
|
||||
if (!forward_heap.Empty())
|
||||
{
|
||||
const auto heapNode = forward_heap.DeleteMinGetHeapNode();
|
||||
// std::cerr << "FORWARDN " << heapNode.node << std::endl;
|
||||
// auto heapNode = routingStep2<FORWARD_DIRECTION>(facade, forward_heap, args...);
|
||||
|
||||
for (size_t i = 0; i < candidatesCount; ++i)
|
||||
{
|
||||
auto &rh = reverse_heap[i];
|
||||
const auto reverseHeapNode = rh->GetHeapNodeIfWasInserted(heapNode.node);
|
||||
if (reverseHeapNode)
|
||||
{
|
||||
auto reverse_weight = reverseHeapNode->weight;
|
||||
auto path_weight = heapNode.weight + reverse_weight;
|
||||
|
||||
if (!shouldForceStep(force_step_nodes, heapNode, *reverseHeapNode) &&
|
||||
(path_weight >= EdgeWeight{0}) && (path_weight < weights[i]))
|
||||
{
|
||||
middles[i] = heapNode.node;
|
||||
weights[i] = path_weight;
|
||||
|
||||
// auto distance =
|
||||
// forward_heap.GetData(middles[i]).distance +
|
||||
// reverse_heap[i]->GetData(middles[i]).distance;
|
||||
// std::cerr << "RFOUNDN " << i <<" " << distance << std::endl;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
relaxOutgoingEdges<FORWARD_DIRECTION>(facade, forward_heap, heapNode, candidates);
|
||||
|
||||
if (!forward_heap.Empty())
|
||||
forward_heap_min = forward_heap.MinKey();
|
||||
}
|
||||
|
||||
cont = false;
|
||||
for (size_t i = 0; i < candidatesCount; ++i)
|
||||
{
|
||||
if ((forward_heap.Size() + reverse_heap[i]->Size() > 0) &&
|
||||
(forward_heap_min + reverse_heap_mins[i]) < weights[i])
|
||||
{
|
||||
cont = true;
|
||||
}
|
||||
if (!reverse_heap[i]->Empty() && (forward_heap_min + reverse_heap_mins[i]) < weights[i])
|
||||
{
|
||||
const auto heapNode = reverse_heap[i]->DeleteMinGetHeapNode();
|
||||
// std::cerr << "REVERSEN " << i << " " << heapNode.node << std::endl;
|
||||
|
||||
const auto reverseHeapNode = forward_heap.GetHeapNodeIfWasInserted(heapNode.node);
|
||||
if (reverseHeapNode)
|
||||
{
|
||||
auto reverse_weight = reverseHeapNode->weight;
|
||||
auto path_weight = heapNode.weight + reverse_weight;
|
||||
|
||||
if (!shouldForceStep(force_step_nodes, heapNode, *reverseHeapNode) &&
|
||||
(path_weight >= EdgeWeight{0}) && (path_weight < weights[i]))
|
||||
{
|
||||
|
||||
middles[i] = heapNode.node;
|
||||
weights[i] = path_weight;
|
||||
|
||||
// auto distance =
|
||||
// forward_heap.GetData(middles[i]).distance +
|
||||
// reverse_heap[i]->GetData(middles[i]).distance;
|
||||
// std::cerr << "FFOUNDN " << i << " " << distance << std::endl;
|
||||
}
|
||||
}
|
||||
relaxOutgoingEdges<REVERSE_DIRECTION>(
|
||||
facade, *reverse_heap[i], heapNode, candidates);
|
||||
|
||||
if (!reverse_heap[i]->Empty())
|
||||
reverse_heap_mins[i] = reverse_heap[i]->MinKey();
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
return middles;
|
||||
// std::vector<std::optional<std::pair<NodeID, EdgeWeight>>> results;
|
||||
// results.reserve(candidatesCount);
|
||||
// for (size_t i = 0; i < candidatesCount; ++i)
|
||||
// {
|
||||
// if (weights[i] >= weight_upper_bound || SPECIAL_NODEID == middles[i])
|
||||
// {
|
||||
// results.push_back({});
|
||||
// }
|
||||
// else
|
||||
// {
|
||||
// results.push_back({{middles[i], weights[i]}});
|
||||
// }
|
||||
// }
|
||||
// return results;
|
||||
|
||||
// // run two-Target Dijkstra routing step.
|
||||
// NodeID middle = SPECIAL_NODEID;
|
||||
// EdgeWeight weight = weight_upper_bound;
|
||||
// EdgeWeight forward_heap_min = forward_heap.MinKey();
|
||||
// EdgeWeight reverse_heap_min = reverse_heap.MinKey();
|
||||
// while (forward_heap.Size() + reverse_heap.Size() > 0 &&
|
||||
// forward_heap_min + reverse_heap_min < weight)
|
||||
// {
|
||||
// if (!forward_heap.Empty())
|
||||
// {
|
||||
// routingStep<FORWARD_DIRECTION>(
|
||||
// facade, forward_heap, reverse_heap, middle, weight, force_step_nodes, args...);
|
||||
// if (!forward_heap.Empty())
|
||||
// forward_heap_min = forward_heap.MinKey();
|
||||
// }
|
||||
// if (!reverse_heap.Empty())
|
||||
// {
|
||||
// routingStep<REVERSE_DIRECTION>(
|
||||
// facade, reverse_heap, forward_heap, middle, weight, force_step_nodes, args...);
|
||||
// if (!reverse_heap.Empty())
|
||||
// reverse_heap_min = reverse_heap.MinKey();
|
||||
// }
|
||||
// };
|
||||
|
||||
// // No path found for both target nodes?
|
||||
// if (weight >= weight_upper_bound || SPECIAL_NODEID == middle)
|
||||
// {
|
||||
// return {};
|
||||
// }
|
||||
|
||||
// return {{middle, weight}};
|
||||
}
|
||||
|
||||
template <typename Algorithm>
|
||||
std::vector<double> searchDistance2(
|
||||
SearchEngineData<Algorithm> &,
|
||||
const DataFacade<Algorithm> &facade,
|
||||
typename SearchEngineData<Algorithm>::MapMatchingQueryHeap &forward_heap,
|
||||
const std::vector<std::unique_ptr<typename SearchEngineData<Algorithm>::MapMatchingQueryHeap>>
|
||||
&reverse_heaps,
|
||||
size_t candidatesCount,
|
||||
const std::vector<NodeID> &force_step_nodes,
|
||||
EdgeWeight weight_upper_bound,
|
||||
const PhantomEndpointCandidates &candidates)
|
||||
{
|
||||
auto searchResults = runSearch2(facade,
|
||||
forward_heap,
|
||||
reverse_heaps,
|
||||
candidatesCount,
|
||||
force_step_nodes,
|
||||
weight_upper_bound,
|
||||
candidates);
|
||||
std::vector<double> res;
|
||||
res.reserve(candidatesCount);
|
||||
for (size_t i = 0; i < searchResults.size(); ++i)
|
||||
{
|
||||
if (searchResults[i] == SPECIAL_NODEID)
|
||||
{
|
||||
res.push_back(std::numeric_limits<double>::max());
|
||||
}
|
||||
else
|
||||
{
|
||||
auto middle = searchResults[i];
|
||||
|
||||
// std::cerr << "new " << i << " " << middle << std::endl;
|
||||
|
||||
auto distance =
|
||||
forward_heap.GetData(middle).distance + reverse_heaps[i]->GetData(middle).distance;
|
||||
res.push_back(from_alias<double>(distance));
|
||||
}
|
||||
}
|
||||
return res;
|
||||
}
|
||||
template <typename Algorithm>
|
||||
std::vector<double> getNetworkDistances(
|
||||
SearchEngineData<Algorithm> &engine_working_data,
|
||||
const DataFacade<Algorithm> &facade,
|
||||
typename SearchEngineData<Algorithm>::MapMatchingQueryHeap &forward_heap,
|
||||
const std::vector<std::unique_ptr<typename SearchEngineData<Algorithm>::MapMatchingQueryHeap>>
|
||||
&reverse_heaps,
|
||||
const PhantomNode &source_phantom,
|
||||
const std::vector<PhantomNode> &target_phantoms,
|
||||
EdgeWeight weight_upper_bound = INVALID_EDGE_WEIGHT)
|
||||
{
|
||||
forward_heap.Clear();
|
||||
for (const auto &heap : reverse_heaps)
|
||||
{
|
||||
heap->Clear();
|
||||
}
|
||||
// std::vector<std::unique_ptr<Heap>> reverse_heaps;
|
||||
// const auto nodes_number = facade.GetNumberOfNodes();
|
||||
// const auto border_nodes_number = facade.GetMaxBorderNodeID() + 1;
|
||||
// for (const auto &target_phantom : target_phantoms)
|
||||
// {
|
||||
// (void)target_phantom;
|
||||
// reverse_heaps.emplace_back(std::make_unique<Heap>(nodes_number, border_nodes_number));
|
||||
// }
|
||||
|
||||
if (source_phantom.IsValidForwardSource())
|
||||
{
|
||||
forward_heap.Insert(source_phantom.forward_segment_id.id,
|
||||
EdgeWeight{0} - source_phantom.GetForwardWeightPlusOffset(),
|
||||
{source_phantom.forward_segment_id.id,
|
||||
false,
|
||||
EdgeDistance{0} - source_phantom.GetForwardDistance()});
|
||||
}
|
||||
|
||||
if (source_phantom.IsValidReverseSource())
|
||||
{
|
||||
forward_heap.Insert(source_phantom.reverse_segment_id.id,
|
||||
EdgeWeight{0} - source_phantom.GetReverseWeightPlusOffset(),
|
||||
{source_phantom.reverse_segment_id.id,
|
||||
false,
|
||||
EdgeDistance{0} - source_phantom.GetReverseDistance()});
|
||||
}
|
||||
|
||||
for (size_t i = 0; i < target_phantoms.size(); ++i)
|
||||
{
|
||||
auto &reverse_heap = *reverse_heaps[i];
|
||||
const auto &target_phantom = target_phantoms[i];
|
||||
if (target_phantom.IsValidForwardTarget())
|
||||
{
|
||||
reverse_heap.Insert(
|
||||
target_phantom.forward_segment_id.id,
|
||||
target_phantom.GetForwardWeightPlusOffset(),
|
||||
{target_phantom.forward_segment_id.id, false, target_phantom.GetForwardDistance()});
|
||||
}
|
||||
|
||||
if (target_phantom.IsValidReverseTarget())
|
||||
{
|
||||
reverse_heap.Insert(
|
||||
target_phantom.reverse_segment_id.id,
|
||||
target_phantom.GetReverseWeightPlusOffset(),
|
||||
{target_phantom.reverse_segment_id.id, false, target_phantom.GetReverseDistance()});
|
||||
}
|
||||
}
|
||||
|
||||
// PhantomEndpoints endpoints{};
|
||||
// endpoints.push_back(source_phantom);
|
||||
// for (const auto &target_phantom : target_phantoms)
|
||||
// {
|
||||
// endpoints.push_back(target_phantom);
|
||||
// }
|
||||
std::vector<PhantomNode> source_phantomes;
|
||||
source_phantomes.push_back(source_phantom);
|
||||
PhantomEndpointCandidates phantom_candidates{source_phantomes, target_phantoms};
|
||||
|
||||
auto distances = searchDistance2(engine_working_data,
|
||||
facade,
|
||||
forward_heap,
|
||||
reverse_heaps,
|
||||
target_phantoms.size(),
|
||||
{},
|
||||
weight_upper_bound,
|
||||
phantom_candidates);
|
||||
return distances;
|
||||
}
|
||||
|
||||
} // namespace osrm::engine::routing_algorithms::mld
|
||||
|
||||
#endif // OSRM_ENGINE_ROUTING_BASE_MLD_HPP
|
||||
|
||||
@@ -56,7 +56,6 @@ template <> struct SearchEngineData<routing_algorithms::ch::Algorithm>
|
||||
static thread_local ManyToManyHeapPtr many_to_many_heap;
|
||||
static thread_local SearchEngineHeapPtr map_matching_forward_heap_1;
|
||||
static thread_local SearchEngineHeapPtr map_matching_reverse_heap_1;
|
||||
static thread_local std::vector<SearchEngineHeapPtr> map_matching_reverse_heaps;
|
||||
|
||||
void InitializeOrClearMapMatchingThreadLocalStorage(unsigned number_of_nodes);
|
||||
|
||||
@@ -134,15 +133,13 @@ template <> struct SearchEngineData<routing_algorithms::mld::Algorithm>
|
||||
static thread_local SearchEngineHeapPtr reverse_heap_1;
|
||||
static thread_local MapMatchingHeapPtr map_matching_forward_heap_1;
|
||||
static thread_local MapMatchingHeapPtr map_matching_reverse_heap_1;
|
||||
static thread_local std::vector<MapMatchingHeapPtr> map_matching_reverse_heaps;
|
||||
|
||||
static thread_local ManyToManyHeapPtr many_to_many_heap;
|
||||
|
||||
void InitializeOrClearFirstThreadLocalStorage(unsigned number_of_nodes,
|
||||
unsigned number_of_boundary_nodes);
|
||||
void InitializeOrClearMapMatchingThreadLocalStorage(unsigned number_of_nodes,
|
||||
unsigned number_of_boundary_nodes,
|
||||
size_t max_candidates);
|
||||
unsigned number_of_boundary_nodes);
|
||||
|
||||
void InitializeOrClearManyToManyThreadLocalStorage(unsigned number_of_nodes,
|
||||
unsigned number_of_boundary_nodes);
|
||||
|
||||
@@ -0,0 +1,113 @@
|
||||
#pragma once
|
||||
|
||||
#include <boost/assert.hpp>
|
||||
#include <functional>
|
||||
#include <limits>
|
||||
#include <utility>
|
||||
#include <vector>
|
||||
|
||||
namespace osrm::util
|
||||
{
|
||||
template <typename HeapData, int Arity, typename Comparator = std::less<HeapData>> class DAryHeap
|
||||
{
|
||||
public:
|
||||
using HeapHandle = size_t;
|
||||
|
||||
static constexpr HeapHandle INVALID_HANDLE = std::numeric_limits<size_t>::max();
|
||||
|
||||
public:
|
||||
const HeapData &top() const { return heap[0]; }
|
||||
|
||||
size_t size() const { return heap.size(); }
|
||||
|
||||
bool empty() const { return heap.empty(); }
|
||||
|
||||
const HeapData &operator[](HeapHandle handle) const { return heap[handle]; }
|
||||
|
||||
template <typename ReorderHandler>
|
||||
void emplace(HeapData &&data, ReorderHandler &&reorderHandler)
|
||||
{
|
||||
heap.emplace_back(std::forward<HeapData>(data));
|
||||
heapifyUp(heap.size() - 1, std::forward<ReorderHandler>(reorderHandler));
|
||||
}
|
||||
|
||||
template <typename ReorderHandler>
|
||||
void decrease(HeapHandle handle, HeapData &&data, ReorderHandler &&reorderHandler)
|
||||
{
|
||||
BOOST_ASSERT(handle < heap.size());
|
||||
|
||||
heap[handle] = std::forward<HeapData>(data);
|
||||
heapifyUp(handle, std::forward<ReorderHandler>(reorderHandler));
|
||||
}
|
||||
|
||||
void clear() { heap.clear(); }
|
||||
|
||||
template <typename ReorderHandler> void pop(ReorderHandler &&reorderHandler)
|
||||
{
|
||||
BOOST_ASSERT(!heap.empty());
|
||||
heap[0] = std::move(heap.back());
|
||||
heap.pop_back();
|
||||
if (!heap.empty())
|
||||
{
|
||||
heapifyDown(0, std::forward<ReorderHandler>(reorderHandler));
|
||||
}
|
||||
}
|
||||
|
||||
private:
|
||||
size_t parent(size_t index) { return (index - 1) / Arity; }
|
||||
|
||||
size_t kthChild(size_t index, size_t k) { return Arity * index + k + 1; }
|
||||
|
||||
template <typename ReorderHandler> void heapifyUp(size_t index, ReorderHandler &&reorderHandler)
|
||||
{
|
||||
HeapData temp = std::move(heap[index]);
|
||||
while (index > 0 && comp(temp, heap[parent(index)]))
|
||||
{
|
||||
size_t parentIndex = parent(index);
|
||||
heap[index] = std::move(heap[parentIndex]);
|
||||
reorderHandler(heap[index], index);
|
||||
index = parentIndex;
|
||||
}
|
||||
heap[index] = std::move(temp);
|
||||
reorderHandler(heap[index], index);
|
||||
}
|
||||
|
||||
template <typename ReorderHandler>
|
||||
void heapifyDown(size_t index, ReorderHandler &&reorderHandler)
|
||||
{
|
||||
HeapData temp = std::move(heap[index]);
|
||||
size_t child;
|
||||
while (kthChild(index, 0) < heap.size())
|
||||
{
|
||||
child = minChild(index);
|
||||
if (!comp(heap[child], temp))
|
||||
{
|
||||
break;
|
||||
}
|
||||
heap[index] = std::move(heap[child]);
|
||||
reorderHandler(heap[index], index);
|
||||
index = child;
|
||||
}
|
||||
heap[index] = std::move(temp);
|
||||
reorderHandler(heap[index], index);
|
||||
}
|
||||
|
||||
size_t minChild(size_t index)
|
||||
{
|
||||
size_t bestChild = kthChild(index, 0);
|
||||
for (size_t k = 1; k < Arity; ++k)
|
||||
{
|
||||
size_t pos = kthChild(index, k);
|
||||
if (pos < heap.size() && comp(heap[pos], heap[bestChild]))
|
||||
{
|
||||
bestChild = pos;
|
||||
}
|
||||
}
|
||||
return bestChild;
|
||||
}
|
||||
|
||||
private:
|
||||
Comparator comp;
|
||||
std::vector<HeapData> heap;
|
||||
};
|
||||
} // namespace osrm::util
|
||||
+49
-28
@@ -4,8 +4,10 @@
|
||||
#include <boost/assert.hpp>
|
||||
#include <boost/heap/d_ary_heap.hpp>
|
||||
|
||||
#include "d_ary_heap.hpp"
|
||||
#include <algorithm>
|
||||
#include <cstdint>
|
||||
#include <cstdlib>
|
||||
#include <limits>
|
||||
#include <map>
|
||||
#include <optional>
|
||||
@@ -133,20 +135,17 @@ class QueryHeap
|
||||
Weight weight;
|
||||
Key index;
|
||||
|
||||
bool operator>(const HeapData &other) const
|
||||
bool operator<(const HeapData &other) const
|
||||
{
|
||||
if (weight == other.weight)
|
||||
{
|
||||
return index > other.index;
|
||||
return index < other.index;
|
||||
}
|
||||
return weight > other.weight;
|
||||
return weight < other.weight;
|
||||
}
|
||||
};
|
||||
using HeapContainer = boost::heap::d_ary_heap<HeapData,
|
||||
boost::heap::arity<4>,
|
||||
boost::heap::mutable_<true>,
|
||||
boost::heap::compare<std::greater<HeapData>>>;
|
||||
using HeapHandle = typename HeapContainer::handle_type;
|
||||
using HeapContainer = DAryHeap<HeapData, 4>;
|
||||
using HeapHandle = typename HeapContainer::HeapHandle;
|
||||
|
||||
public:
|
||||
using WeightType = Weight;
|
||||
@@ -178,11 +177,31 @@ class QueryHeap
|
||||
|
||||
void Insert(NodeID node, Weight weight, const Data &data)
|
||||
{
|
||||
checkInvariants();
|
||||
|
||||
BOOST_ASSERT(node < std::numeric_limits<NodeID>::max());
|
||||
const auto index = static_cast<Key>(inserted_nodes.size());
|
||||
const auto handle = heap.emplace(HeapData{weight, index});
|
||||
inserted_nodes.emplace_back(HeapNode{handle, node, weight, data});
|
||||
inserted_nodes.emplace_back(HeapNode{heap.size(), node, weight, data});
|
||||
|
||||
heap.emplace(HeapData{weight, index},
|
||||
[this](const auto &heapData, auto new_handle)
|
||||
{ inserted_nodes[heapData.index].handle = new_handle; });
|
||||
node_index[node] = index;
|
||||
|
||||
checkInvariants();
|
||||
}
|
||||
|
||||
void checkInvariants()
|
||||
{
|
||||
#ifndef NDEBUG
|
||||
for (size_t handle = 0; handle < heap.size(); ++handle)
|
||||
{
|
||||
auto &in_heap = heap[handle];
|
||||
auto &inserted = inserted_nodes[in_heap.index];
|
||||
BOOST_ASSERT(in_heap.weight == inserted.weight);
|
||||
BOOST_ASSERT(inserted.handle == handle);
|
||||
}
|
||||
#endif // !NDEBUG
|
||||
}
|
||||
|
||||
Data &GetData(NodeID node)
|
||||
@@ -216,16 +235,7 @@ class QueryHeap
|
||||
{
|
||||
BOOST_ASSERT(WasInserted(node));
|
||||
const Key index = node_index.peek_index(node);
|
||||
|
||||
// Use end iterator as a reliable "non-existent" handle.
|
||||
// Default-constructed handles are singular and
|
||||
// can only be checked-compared to another singular instance.
|
||||
// Behaviour investigated at https://lists.boost.org/boost-users/2017/08/87787.php,
|
||||
// eventually confirmation at https://stackoverflow.com/a/45622940/151641.
|
||||
// Corrected in https://github.com/Project-OSRM/osrm-backend/pull/4396
|
||||
auto const end_it = const_cast<HeapContainer &>(heap).end(); // non-const iterator
|
||||
auto const none_handle = heap.s_handle_from_iterator(end_it); // from non-const iterator
|
||||
return inserted_nodes[index].handle == none_handle;
|
||||
return inserted_nodes[index].handle == HeapContainer::INVALID_HANDLE;
|
||||
}
|
||||
|
||||
bool WasInserted(const NodeID node) const
|
||||
@@ -276,26 +286,30 @@ class QueryHeap
|
||||
{
|
||||
BOOST_ASSERT(!heap.empty());
|
||||
const Key removedIndex = heap.top().index;
|
||||
heap.pop();
|
||||
inserted_nodes[removedIndex].handle = heap.s_handle_from_iterator(heap.end());
|
||||
inserted_nodes[removedIndex].handle = HeapContainer::INVALID_HANDLE;
|
||||
|
||||
heap.pop([this](const auto &heapData, auto new_handle)
|
||||
{ inserted_nodes[heapData.index].handle = new_handle; });
|
||||
return inserted_nodes[removedIndex].node;
|
||||
}
|
||||
|
||||
HeapNode &DeleteMinGetHeapNode()
|
||||
{
|
||||
BOOST_ASSERT(!heap.empty());
|
||||
checkInvariants();
|
||||
const Key removedIndex = heap.top().index;
|
||||
heap.pop();
|
||||
inserted_nodes[removedIndex].handle = heap.s_handle_from_iterator(heap.end());
|
||||
inserted_nodes[removedIndex].handle = HeapContainer::INVALID_HANDLE;
|
||||
heap.pop([this](const auto &heapData, auto new_handle)
|
||||
{ inserted_nodes[heapData.index].handle = new_handle; });
|
||||
checkInvariants();
|
||||
return inserted_nodes[removedIndex];
|
||||
}
|
||||
|
||||
void DeleteAll()
|
||||
{
|
||||
auto const none_handle = heap.s_handle_from_iterator(heap.end());
|
||||
std::for_each(inserted_nodes.begin(),
|
||||
inserted_nodes.end(),
|
||||
[&none_handle](auto &node) { node.handle = none_handle; });
|
||||
[&](auto &node) { node.handle = HeapContainer::INVALID_HANDLE; });
|
||||
heap.clear();
|
||||
}
|
||||
|
||||
@@ -305,13 +319,19 @@ class QueryHeap
|
||||
const auto index = node_index.peek_index(node);
|
||||
auto &reference = inserted_nodes[index];
|
||||
reference.weight = weight;
|
||||
heap.increase(reference.handle, HeapData{weight, static_cast<Key>(index)});
|
||||
heap.decrease(reference.handle,
|
||||
HeapData{weight, static_cast<Key>(index)},
|
||||
[this](const auto &heapData, auto new_handle)
|
||||
{ inserted_nodes[heapData.index].handle = new_handle; });
|
||||
}
|
||||
|
||||
void DecreaseKey(const HeapNode &heapNode)
|
||||
{
|
||||
BOOST_ASSERT(!WasRemoved(heapNode.node));
|
||||
heap.increase(heapNode.handle, HeapData{heapNode.weight, (*heapNode.handle).index});
|
||||
heap.decrease(heapNode.handle,
|
||||
HeapData{heapNode.weight, heap[heapNode.handle].index},
|
||||
[this](const auto &heapData, auto new_handle)
|
||||
{ inserted_nodes[heapData.index].handle = new_handle; });
|
||||
}
|
||||
|
||||
private:
|
||||
@@ -319,6 +339,7 @@ class QueryHeap
|
||||
HeapContainer heap;
|
||||
IndexStorage node_index;
|
||||
};
|
||||
|
||||
} // namespace osrm::util
|
||||
|
||||
#endif // OSRM_UTIL_QUERY_HEAP_HPP
|
||||
|
||||
@@ -50,27 +50,26 @@ function measure_peak_ram_and_time {
|
||||
}
|
||||
|
||||
function run_benchmarks_for_folder {
|
||||
rm -rf $RESULTS_FOLDER
|
||||
mkdir -p $RESULTS_FOLDER
|
||||
|
||||
BENCHMARKS_FOLDER="$BINARIES_FOLDER/src/benchmarks"
|
||||
|
||||
# echo "Running match-bench MLD"
|
||||
# $BENCHMARKS_FOLDER/match-bench "$FOLDER/test/data/mld/monaco.osrm" mld > "$RESULTS_FOLDER/match_mld.bench"
|
||||
# echo "Running match-bench CH"
|
||||
# $BENCHMARKS_FOLDER/match-bench "$FOLDER/test/data/ch/monaco.osrm" ch > "$RESULTS_FOLDER/match_ch.bench"
|
||||
# echo "Running route-bench MLD"
|
||||
# $BENCHMARKS_FOLDER/route-bench "$FOLDER/test/data/mld/monaco.osrm" mld > "$RESULTS_FOLDER/route_mld.bench"
|
||||
# echo "Running route-bench CH"
|
||||
# $BENCHMARKS_FOLDER/route-bench "$FOLDER/test/data/ch/monaco.osrm" ch > "$RESULTS_FOLDER/route_ch.bench"
|
||||
# echo "Running alias"
|
||||
# $BENCHMARKS_FOLDER/alias-bench > "$RESULTS_FOLDER/alias.bench"
|
||||
# echo "Running json-render-bench"
|
||||
# $BENCHMARKS_FOLDER/json-render-bench "$FOLDER/test/data/portugal_to_korea.json" > "$RESULTS_FOLDER/json-render.bench"
|
||||
# echo "Running packedvector-bench"
|
||||
# $BENCHMARKS_FOLDER/packedvector-bench > "$RESULTS_FOLDER/packedvector.bench"
|
||||
# echo "Running rtree-bench"
|
||||
# $BENCHMARKS_FOLDER/rtree-bench "$FOLDER/test/data/monaco.osrm.ramIndex" "$FOLDER/test/data/monaco.osrm.fileIndex" "$FOLDER/test/data/monaco.osrm.nbg_nodes" > "$RESULTS_FOLDER/rtree.bench"
|
||||
echo "Running match-bench MLD"
|
||||
$BENCHMARKS_FOLDER/match-bench "$FOLDER/test/data/mld/monaco.osrm" mld > "$RESULTS_FOLDER/match_mld.bench"
|
||||
echo "Running match-bench CH"
|
||||
$BENCHMARKS_FOLDER/match-bench "$FOLDER/test/data/ch/monaco.osrm" ch > "$RESULTS_FOLDER/match_ch.bench"
|
||||
echo "Running route-bench MLD"
|
||||
$BENCHMARKS_FOLDER/route-bench "$FOLDER/test/data/mld/monaco.osrm" mld > "$RESULTS_FOLDER/route_mld.bench"
|
||||
echo "Running route-bench CH"
|
||||
$BENCHMARKS_FOLDER/route-bench "$FOLDER/test/data/ch/monaco.osrm" ch > "$RESULTS_FOLDER/route_ch.bench"
|
||||
echo "Running alias"
|
||||
$BENCHMARKS_FOLDER/alias-bench > "$RESULTS_FOLDER/alias.bench"
|
||||
echo "Running json-render-bench"
|
||||
$BENCHMARKS_FOLDER/json-render-bench "$FOLDER/test/data/portugal_to_korea.json" > "$RESULTS_FOLDER/json-render.bench"
|
||||
echo "Running packedvector-bench"
|
||||
$BENCHMARKS_FOLDER/packedvector-bench > "$RESULTS_FOLDER/packedvector.bench"
|
||||
echo "Running rtree-bench"
|
||||
$BENCHMARKS_FOLDER/rtree-bench "$FOLDER/test/data/monaco.osrm.ramIndex" "$FOLDER/test/data/monaco.osrm.fileIndex" "$FOLDER/test/data/monaco.osrm.nbg_nodes" > "$RESULTS_FOLDER/rtree.bench"
|
||||
|
||||
cp -rf $OSM_PBF $FOLDER/data.osm.pbf
|
||||
|
||||
@@ -84,19 +83,19 @@ function run_benchmarks_for_folder {
|
||||
measure_peak_ram_and_time "$BINARIES_FOLDER/osrm-contract $FOLDER/data.osrm" "$RESULTS_FOLDER/osrm_contract.bench"
|
||||
|
||||
|
||||
# for ALGORITHM in ch mld; do
|
||||
# for BENCH in nearest table trip route match; do
|
||||
# echo "Running node $BENCH $ALGORITHM"
|
||||
# START=$(date +%s.%N)
|
||||
# node $SCRIPTS_FOLDER/scripts/ci/bench.js $FOLDER/lib/binding/node_osrm.node $FOLDER/data.osrm $ALGORITHM $BENCH $GPS_TRACES > "$RESULTS_FOLDER/node_${BENCH}_${ALGORITHM}.bench" 5
|
||||
# END=$(date +%s.%N)
|
||||
# DIFF=$(echo "$END - $START" | bc)
|
||||
# echo "Took: ${DIFF}s"
|
||||
# done
|
||||
# done
|
||||
|
||||
for ALGORITHM in mld; do
|
||||
for BENCH in match; do
|
||||
for ALGORITHM in ch mld; do
|
||||
for BENCH in nearest table trip route match; do
|
||||
echo "Running node $BENCH $ALGORITHM"
|
||||
START=$(date +%s.%N)
|
||||
node $SCRIPTS_FOLDER/scripts/ci/bench.js $FOLDER/lib/binding/node_osrm.node $FOLDER/data.osrm $ALGORITHM $BENCH $GPS_TRACES > "$RESULTS_FOLDER/node_${BENCH}_${ALGORITHM}.bench" 5
|
||||
END=$(date +%s.%N)
|
||||
DIFF=$(echo "$END - $START" | bc)
|
||||
echo "Took: ${DIFF}s"
|
||||
done
|
||||
done
|
||||
|
||||
for ALGORITHM in ch mld; do
|
||||
for BENCH in nearest table trip route match; do
|
||||
echo "Running random $BENCH $ALGORITHM"
|
||||
START=$(date +%s.%N)
|
||||
$BENCHMARKS_FOLDER/bench "$FOLDER/data.osrm" $ALGORITHM $GPS_TRACES ${BENCH} > "$RESULTS_FOLDER/random_${BENCH}_${ALGORITHM}.bench" 5 || true
|
||||
@@ -107,28 +106,28 @@ function run_benchmarks_for_folder {
|
||||
done
|
||||
|
||||
|
||||
# for ALGORITHM in ch mld; do
|
||||
# $BINARIES_FOLDER/osrm-routed --algorithm $ALGORITHM $FOLDER/data.osrm > /dev/null 2>&1 &
|
||||
# OSRM_ROUTED_PID=$!
|
||||
for ALGORITHM in ch mld; do
|
||||
$BINARIES_FOLDER/osrm-routed --algorithm $ALGORITHM $FOLDER/data.osrm > /dev/null 2>&1 &
|
||||
OSRM_ROUTED_PID=$!
|
||||
|
||||
# # wait for osrm-routed to start
|
||||
# if ! curl --retry-delay 3 --retry 10 --retry-all-errors "http://127.0.0.1:5000/route/v1/driving/13.388860,52.517037;13.385983,52.496891?steps=true" > /dev/null 2>&1; then
|
||||
# echo "osrm-routed failed to start for algorithm $ALGORITHM"
|
||||
# kill -9 $OSRM_ROUTED_PID
|
||||
# continue
|
||||
# fi
|
||||
# wait for osrm-routed to start
|
||||
if ! curl --retry-delay 3 --retry 10 --retry-all-errors "http://127.0.0.1:5000/route/v1/driving/13.388860,52.517037;13.385983,52.496891?steps=true" > /dev/null 2>&1; then
|
||||
echo "osrm-routed failed to start for algorithm $ALGORITHM"
|
||||
kill -9 $OSRM_ROUTED_PID
|
||||
continue
|
||||
fi
|
||||
|
||||
# for METHOD in route nearest trip table match; do
|
||||
# echo "Running e2e benchmark for $METHOD $ALGORITHM"
|
||||
# START=$(date +%s.%N)
|
||||
# python3 $SCRIPTS_FOLDER/scripts/ci/e2e_benchmark.py --host http://localhost:5000 --method $METHOD --iterations 5 --num_requests 1000 --gps_traces_file_path $GPS_TRACES > $RESULTS_FOLDER/e2e_${METHOD}_${ALGORITHM}.bench
|
||||
# END=$(date +%s.%N)
|
||||
# DIFF=$(echo "$END - $START" | bc)
|
||||
# echo "Took: ${DIFF}s"
|
||||
# done
|
||||
for METHOD in route nearest trip table match; do
|
||||
echo "Running e2e benchmark for $METHOD $ALGORITHM"
|
||||
START=$(date +%s.%N)
|
||||
python3 $SCRIPTS_FOLDER/scripts/ci/e2e_benchmark.py --host http://localhost:5000 --method $METHOD --iterations 5 --num_requests 1000 --gps_traces_file_path $GPS_TRACES > $RESULTS_FOLDER/e2e_${METHOD}_${ALGORITHM}.bench
|
||||
END=$(date +%s.%N)
|
||||
DIFF=$(echo "$END - $START" | bc)
|
||||
echo "Took: ${DIFF}s"
|
||||
done
|
||||
|
||||
# kill -9 $OSRM_ROUTED_PID
|
||||
# done
|
||||
kill -9 $OSRM_ROUTED_PID
|
||||
done
|
||||
}
|
||||
|
||||
run_benchmarks_for_folder
|
||||
|
||||
@@ -222,7 +222,6 @@ oneToManySearch(SearchEngineData<Algorithm> &engine_working_data,
|
||||
std::vector<EdgeDuration> durations_table(target_indices.size(), MAXIMAL_EDGE_DURATION);
|
||||
std::vector<EdgeDistance> distances_table(calculate_distance ? target_indices.size() : 0,
|
||||
MAXIMAL_EDGE_DISTANCE);
|
||||
std::vector<NodeID> middle_nodes_table(target_indices.size(), SPECIAL_NODEID);
|
||||
|
||||
// Collect destination (source) nodes into a map
|
||||
std::unordered_multimap<NodeID, std::tuple<std::size_t, EdgeWeight, EdgeDuration, EdgeDistance>>
|
||||
@@ -307,7 +306,6 @@ oneToManySearch(SearchEngineData<Algorithm> &engine_working_data,
|
||||
weights_table[index] = path_weight;
|
||||
durations_table[index] = path_duration;
|
||||
current_distance = path_distance;
|
||||
middle_nodes_table[index] = node;
|
||||
}
|
||||
|
||||
// Remove node from destinations list
|
||||
|
||||
@@ -45,8 +45,7 @@ unsigned getMedianSampleTime(const std::vector<unsigned> ×tamps)
|
||||
|
||||
template <typename Algorithm>
|
||||
inline void initializeHeap(SearchEngineData<Algorithm> &engine_working_data,
|
||||
const DataFacade<Algorithm> &facade,
|
||||
size_t)
|
||||
const DataFacade<Algorithm> &facade)
|
||||
{
|
||||
|
||||
const auto nodes_number = facade.GetNumberOfNodes();
|
||||
@@ -55,92 +54,14 @@ inline void initializeHeap(SearchEngineData<Algorithm> &engine_working_data,
|
||||
|
||||
template <>
|
||||
inline void initializeHeap<mld::Algorithm>(SearchEngineData<mld::Algorithm> &engine_working_data,
|
||||
const DataFacade<mld::Algorithm> &facade,
|
||||
size_t max_candidates)
|
||||
const DataFacade<mld::Algorithm> &facade)
|
||||
{
|
||||
|
||||
const auto nodes_number = facade.GetNumberOfNodes();
|
||||
const auto border_nodes_number = facade.GetMaxBorderNodeID() + 1;
|
||||
engine_working_data.InitializeOrClearMapMatchingThreadLocalStorage(
|
||||
nodes_number, border_nodes_number, max_candidates);
|
||||
engine_working_data.InitializeOrClearMapMatchingThreadLocalStorage(nodes_number,
|
||||
border_nodes_number);
|
||||
}
|
||||
|
||||
#include <fstream>
|
||||
#include <iostream>
|
||||
|
||||
template <typename T> void saveVectorToFile(const std::vector<T> &data, const std::string &filename)
|
||||
{
|
||||
std::ofstream outFile(filename, std::ios::binary);
|
||||
if (!outFile)
|
||||
{
|
||||
std::cerr << "Error opening file for writing: " << filename << std::endl;
|
||||
return;
|
||||
}
|
||||
size_t size = data.size();
|
||||
outFile.write(reinterpret_cast<const char *>(&size), sizeof(size));
|
||||
outFile.write(reinterpret_cast<const char *>(data.data()), size * sizeof(T));
|
||||
outFile.close();
|
||||
if (!outFile.good())
|
||||
{
|
||||
std::cerr << "Error occurred at writing time!" << std::endl;
|
||||
}
|
||||
}
|
||||
|
||||
template <typename T> bool loadVectorFromFile(std::vector<T> &data, const std::string &filename)
|
||||
{
|
||||
std::ifstream inFile(filename, std::ios::binary);
|
||||
if (!inFile)
|
||||
{
|
||||
std::cerr << "Error opening file for reading: " << filename << std::endl;
|
||||
return false;
|
||||
}
|
||||
size_t size;
|
||||
inFile.read(reinterpret_cast<char *>(&size), sizeof(size));
|
||||
data.resize(size);
|
||||
inFile.read(reinterpret_cast<char *>(data.data()), size * sizeof(T));
|
||||
inFile.close();
|
||||
if (!inFile.good())
|
||||
{
|
||||
std::cerr << "Error occurred at reading time!" << std::endl;
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
template <typename T> void saveStructToFile(const T &data, const std::string &filename)
|
||||
{
|
||||
std::ofstream outFile(filename, std::ios::binary);
|
||||
if (!outFile)
|
||||
{
|
||||
std::cerr << "Error opening file for writing: " << filename << std::endl;
|
||||
return;
|
||||
}
|
||||
outFile.write(reinterpret_cast<const char *>(&data), sizeof(T));
|
||||
outFile.close();
|
||||
if (!outFile.good())
|
||||
{
|
||||
std::cerr << "Error occurred at writing time!" << std::endl;
|
||||
}
|
||||
}
|
||||
|
||||
template <typename T> bool loadStructFromFile(T &data, const std::string &filename)
|
||||
{
|
||||
std::ifstream inFile(filename, std::ios::binary);
|
||||
if (!inFile)
|
||||
{
|
||||
std::cerr << "Error opening file for reading: " << filename << std::endl;
|
||||
return false;
|
||||
}
|
||||
inFile.read(reinterpret_cast<char *>(&data), sizeof(T));
|
||||
inFile.close();
|
||||
if (!inFile.good())
|
||||
{
|
||||
std::cerr << "Error occurred at reading time!" << std::endl;
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
} // namespace
|
||||
|
||||
template <typename Algorithm>
|
||||
@@ -223,16 +144,9 @@ SubMatchingList mapMatching(SearchEngineData<Algorithm> &engine_working_data,
|
||||
return sub_matchings;
|
||||
}
|
||||
|
||||
size_t max_candidates = 0;
|
||||
for (const auto &candidates : candidates_list)
|
||||
{
|
||||
max_candidates = std::max(max_candidates, candidates.size());
|
||||
}
|
||||
|
||||
initializeHeap(engine_working_data, facade, max_candidates);
|
||||
initializeHeap(engine_working_data, facade);
|
||||
auto &forward_heap = *engine_working_data.map_matching_forward_heap_1;
|
||||
auto &reverse_heap = *engine_working_data.map_matching_reverse_heap_1;
|
||||
const auto &reverse_heaps = engine_working_data.map_matching_reverse_heaps;
|
||||
|
||||
std::size_t breakage_begin = map_matching::INVALID_STATE;
|
||||
std::vector<std::size_t> split_points;
|
||||
@@ -311,108 +225,6 @@ SubMatchingList mapMatching(SearchEngineData<Algorithm> &engine_working_data,
|
||||
continue;
|
||||
}
|
||||
|
||||
// PhantomNode source;
|
||||
// loadStructFromFile<PhantomNode>(source, "source.bin");
|
||||
std::vector<PhantomNode> target_phantom_nodes;
|
||||
// loadVectorFromFile(target_phantom_nodes, "target.bin");
|
||||
// target_phantom_nodes.erase(target_phantom_nodes.begin());
|
||||
// target_phantom_nodes.erase(target_phantom_nodes.begin());
|
||||
// target_phantom_nodes.erase(target_phantom_nodes.begin());
|
||||
// target_phantom_nodes.erase(target_phantom_nodes.begin());
|
||||
// target_phantom_nodes.pop_back();
|
||||
// target_phantom_nodes.pop_back();
|
||||
// target_phantom_nodes.erase(target_phantom_nodes.begin() + 1);
|
||||
|
||||
// target_phantom_nodes.push_back(target);
|
||||
for (const auto s_prime : util::irange<std::size_t>(0UL, current_viterbi.size()))
|
||||
{
|
||||
const double emission_pr = emission_log_probabilities[t][s_prime];
|
||||
double new_value = prev_viterbi[s] + emission_pr;
|
||||
if (current_viterbi[s_prime] > new_value)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
target_phantom_nodes.push_back(current_timestamps_list[s_prime].phantom_node);
|
||||
}
|
||||
|
||||
// TIMER_START(NEW_DIST);
|
||||
|
||||
#define MODE 1
|
||||
|
||||
#if MODE == 0
|
||||
auto new_distances =
|
||||
getNetworkDistances(engine_working_data,
|
||||
facade,
|
||||
forward_heap,
|
||||
reverse_heaps,
|
||||
prev_unbroken_timestamps_list[s].phantom_node,
|
||||
target_phantom_nodes,
|
||||
weight_upper_bound);
|
||||
std::vector<double> old_distances;
|
||||
|
||||
for (const auto &pn : target_phantom_nodes)
|
||||
{
|
||||
double network_distance =
|
||||
getNetworkDistance(engine_working_data,
|
||||
facade,
|
||||
forward_heap,
|
||||
reverse_heap,
|
||||
prev_unbroken_timestamps_list[s].phantom_node,
|
||||
pn,
|
||||
weight_upper_bound);
|
||||
old_distances.push_back(network_distance);
|
||||
}
|
||||
|
||||
for (size_t i = 0; i < old_distances.size(); ++i)
|
||||
{
|
||||
if (std::abs(old_distances[i] - new_distances[i]) > 0.01)
|
||||
{
|
||||
// saveStructToFile(prev_unbroken_timestamps_list[s].phantom_node,
|
||||
// "source.bin");
|
||||
// saveVectorToFile(target_phantom_nodes, "target.bin");
|
||||
std::cerr << "OOPS " << old_distances[i] << " " << new_distances[i]
|
||||
<< std::endl;
|
||||
// std::exit(1);
|
||||
}
|
||||
}
|
||||
|
||||
auto distances = old_distances;
|
||||
#elif MODE == 1
|
||||
(void)reverse_heap;
|
||||
auto distances =
|
||||
getNetworkDistances(engine_working_data,
|
||||
facade,
|
||||
forward_heap,
|
||||
reverse_heaps,
|
||||
prev_unbroken_timestamps_list[s].phantom_node,
|
||||
target_phantom_nodes,
|
||||
weight_upper_bound);
|
||||
// TIMER_STOP(NEW_DIST);
|
||||
#else
|
||||
// TIMER_START(OLD_DIST);
|
||||
(void)reverse_heaps;
|
||||
std::vector<double> distances;
|
||||
|
||||
for (const auto &pn : target_phantom_nodes)
|
||||
{
|
||||
double network_distance =
|
||||
getNetworkDistance(engine_working_data,
|
||||
facade,
|
||||
forward_heap,
|
||||
reverse_heap,
|
||||
prev_unbroken_timestamps_list[s].phantom_node,
|
||||
pn,
|
||||
weight_upper_bound);
|
||||
distances.push_back(network_distance);
|
||||
}
|
||||
#endif
|
||||
// TIMER_STOP(OLD_DIST);
|
||||
|
||||
// std::cerr << "Old: " << TIMER_MSEC(OLD_DIST) << " New: " << TIMER_MSEC(NEW_DIST)
|
||||
// << std::endl;
|
||||
|
||||
|
||||
size_t distance_index = 0;
|
||||
for (const auto s_prime : util::irange<std::size_t>(0UL, current_viterbi.size()))
|
||||
{
|
||||
const double emission_pr = emission_log_probabilities[t][s_prime];
|
||||
@@ -422,16 +234,14 @@ SubMatchingList mapMatching(SearchEngineData<Algorithm> &engine_working_data,
|
||||
continue;
|
||||
}
|
||||
|
||||
double network_distance = distances[distance_index];
|
||||
++distance_index;
|
||||
// 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);
|
||||
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);
|
||||
|
||||
// get distance diff between loc1/2 and locs/s_prime
|
||||
const auto d_t = std::abs(network_distance - haversine_distance);
|
||||
|
||||
@@ -15,8 +15,6 @@ thread_local SearchEngineData<CH>::SearchEngineHeapPtr
|
||||
SearchEngineData<CH>::map_matching_forward_heap_1;
|
||||
thread_local SearchEngineData<CH>::SearchEngineHeapPtr
|
||||
SearchEngineData<CH>::map_matching_reverse_heap_1;
|
||||
thread_local std::vector<typename SearchEngineData<CH>::SearchEngineHeapPtr>
|
||||
SearchEngineData<CH>::map_matching_reverse_heaps;
|
||||
|
||||
thread_local SearchEngineData<CH>::ManyToManyHeapPtr SearchEngineData<CH>::many_to_many_heap;
|
||||
|
||||
@@ -125,11 +123,9 @@ thread_local SearchEngineData<MLD>::MapMatchingHeapPtr
|
||||
thread_local SearchEngineData<MLD>::MapMatchingHeapPtr
|
||||
SearchEngineData<MLD>::map_matching_reverse_heap_1;
|
||||
thread_local SearchEngineData<MLD>::ManyToManyHeapPtr SearchEngineData<MLD>::many_to_many_heap;
|
||||
thread_local std::vector<typename SearchEngineData<MLD>::MapMatchingHeapPtr>
|
||||
SearchEngineData<MLD>::map_matching_reverse_heaps;
|
||||
|
||||
void SearchEngineData<MLD>::InitializeOrClearMapMatchingThreadLocalStorage(
|
||||
unsigned number_of_nodes, unsigned number_of_boundary_nodes, size_t max_candidates)
|
||||
unsigned number_of_nodes, unsigned number_of_boundary_nodes)
|
||||
{
|
||||
if (map_matching_forward_heap_1.get())
|
||||
{
|
||||
@@ -150,16 +146,6 @@ void SearchEngineData<MLD>::InitializeOrClearMapMatchingThreadLocalStorage(
|
||||
map_matching_reverse_heap_1.reset(
|
||||
new MapMatchingQueryHeap(number_of_nodes, number_of_boundary_nodes));
|
||||
}
|
||||
|
||||
if (max_candidates > map_matching_reverse_heaps.size())
|
||||
{
|
||||
size_t to_add = max_candidates - map_matching_reverse_heaps.size();
|
||||
for (unsigned i = 0; i < to_add; ++i)
|
||||
{
|
||||
map_matching_reverse_heaps.emplace_back(
|
||||
new MapMatchingQueryHeap(number_of_nodes, number_of_boundary_nodes));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void SearchEngineData<MLD>::InitializeOrClearFirstThreadLocalStorage(
|
||||
|
||||
@@ -0,0 +1,175 @@
|
||||
|
||||
#include "util/d_ary_heap.hpp"
|
||||
#include <boost/test/unit_test.hpp>
|
||||
|
||||
using namespace osrm::util;
|
||||
|
||||
BOOST_AUTO_TEST_SUITE(d_ary_heap_test)
|
||||
|
||||
BOOST_AUTO_TEST_CASE(test_empty_heap)
|
||||
{
|
||||
DAryHeap<int, 2> heap;
|
||||
BOOST_CHECK(heap.empty());
|
||||
BOOST_CHECK_EQUAL(heap.size(), 0);
|
||||
heap.emplace(10, [](int &, size_t) {});
|
||||
BOOST_CHECK(!heap.empty());
|
||||
BOOST_CHECK_EQUAL(heap.size(), 1);
|
||||
}
|
||||
|
||||
BOOST_AUTO_TEST_CASE(test_emplace_and_top)
|
||||
{
|
||||
DAryHeap<int, 2> heap;
|
||||
heap.emplace(10, [](int &, size_t) {});
|
||||
heap.emplace(5, [](int &, size_t) {});
|
||||
heap.emplace(8, [](int &, size_t) {});
|
||||
|
||||
BOOST_CHECK_EQUAL(heap.top(), 5);
|
||||
BOOST_CHECK_EQUAL(heap.size(), 3);
|
||||
}
|
||||
|
||||
BOOST_AUTO_TEST_CASE(test_pop)
|
||||
{
|
||||
DAryHeap<int, 2> heap;
|
||||
heap.emplace(10, [](int &, size_t) {});
|
||||
heap.emplace(5, [](int &, size_t) {});
|
||||
heap.emplace(8, [](int &, size_t) {});
|
||||
|
||||
heap.pop([](int &, size_t) {});
|
||||
BOOST_CHECK_EQUAL(heap.top(), 8);
|
||||
BOOST_CHECK_EQUAL(heap.size(), 2);
|
||||
|
||||
heap.pop([](int &, size_t) {});
|
||||
BOOST_CHECK_EQUAL(heap.top(), 10);
|
||||
BOOST_CHECK_EQUAL(heap.size(), 1);
|
||||
}
|
||||
|
||||
BOOST_AUTO_TEST_CASE(test_decrease)
|
||||
{
|
||||
struct HeapData
|
||||
{
|
||||
int key;
|
||||
int data;
|
||||
|
||||
bool operator<(const HeapData &other) const { return key < other.key; }
|
||||
};
|
||||
DAryHeap<HeapData, 2> heap;
|
||||
size_t handle = DAryHeap<HeapData, 2>::INVALID_HANDLE;
|
||||
|
||||
auto reorder_handler = [&](const HeapData &value, size_t new_handle)
|
||||
{
|
||||
if (value.data == 42)
|
||||
{
|
||||
handle = new_handle;
|
||||
}
|
||||
};
|
||||
|
||||
heap.emplace({10, 42}, reorder_handler);
|
||||
heap.emplace({5, 73}, reorder_handler);
|
||||
heap.emplace({8, 37}, reorder_handler);
|
||||
|
||||
heap.decrease(handle, {3, 42}, reorder_handler);
|
||||
BOOST_CHECK_EQUAL(heap.size(), 3);
|
||||
BOOST_CHECK_EQUAL(heap.top().key, 3);
|
||||
BOOST_CHECK_EQUAL(heap.top().data, 42);
|
||||
heap.pop(reorder_handler);
|
||||
BOOST_CHECK_EQUAL(heap.size(), 2);
|
||||
BOOST_CHECK_EQUAL(heap.top().key, 5);
|
||||
BOOST_CHECK_EQUAL(heap.top().data, 73);
|
||||
heap.pop(reorder_handler);
|
||||
BOOST_CHECK_EQUAL(heap.size(), 1);
|
||||
BOOST_CHECK_EQUAL(heap.top().key, 8);
|
||||
BOOST_CHECK_EQUAL(heap.top().data, 37);
|
||||
heap.pop(reorder_handler);
|
||||
BOOST_CHECK_EQUAL(heap.size(), 0);
|
||||
BOOST_CHECK(heap.empty());
|
||||
}
|
||||
|
||||
BOOST_AUTO_TEST_CASE(test_reorder_handler)
|
||||
{
|
||||
std::vector<int> reordered_values;
|
||||
std::vector<size_t> reordered_indices;
|
||||
auto reorder_handler = [&](int value, size_t index)
|
||||
{
|
||||
reordered_values.push_back(value);
|
||||
reordered_indices.push_back(index);
|
||||
};
|
||||
DAryHeap<int, 2> heap;
|
||||
std::vector<int> expected_reordered_values;
|
||||
std::vector<int> expected_reordered_indices;
|
||||
|
||||
heap.emplace(10, reorder_handler);
|
||||
|
||||
expected_reordered_values = {10};
|
||||
expected_reordered_indices = {0};
|
||||
BOOST_CHECK_EQUAL_COLLECTIONS(reordered_values.begin(),
|
||||
reordered_values.end(),
|
||||
expected_reordered_values.begin(),
|
||||
expected_reordered_values.end());
|
||||
BOOST_CHECK_EQUAL_COLLECTIONS(reordered_indices.begin(),
|
||||
reordered_indices.end(),
|
||||
expected_reordered_indices.begin(),
|
||||
expected_reordered_indices.end());
|
||||
|
||||
heap.emplace(5, reorder_handler);
|
||||
expected_reordered_values = {10, 10, 5};
|
||||
expected_reordered_indices = {0, 1, 0};
|
||||
BOOST_CHECK_EQUAL_COLLECTIONS(reordered_values.begin(),
|
||||
reordered_values.end(),
|
||||
expected_reordered_values.begin(),
|
||||
expected_reordered_values.end());
|
||||
BOOST_CHECK_EQUAL_COLLECTIONS(reordered_indices.begin(),
|
||||
reordered_indices.end(),
|
||||
expected_reordered_indices.begin(),
|
||||
expected_reordered_indices.end());
|
||||
|
||||
heap.emplace(8, reorder_handler);
|
||||
expected_reordered_values = {10, 10, 5, 8};
|
||||
expected_reordered_indices = {0, 1, 0, 2};
|
||||
BOOST_CHECK_EQUAL_COLLECTIONS(reordered_values.begin(),
|
||||
reordered_values.end(),
|
||||
expected_reordered_values.begin(),
|
||||
expected_reordered_values.end());
|
||||
BOOST_CHECK_EQUAL_COLLECTIONS(reordered_indices.begin(),
|
||||
reordered_indices.end(),
|
||||
expected_reordered_indices.begin(),
|
||||
expected_reordered_indices.end());
|
||||
|
||||
heap.pop(reorder_handler);
|
||||
expected_reordered_values = {10, 10, 5, 8, 8};
|
||||
expected_reordered_indices = {0, 1, 0, 2, 0};
|
||||
BOOST_CHECK_EQUAL_COLLECTIONS(reordered_values.begin(),
|
||||
reordered_values.end(),
|
||||
expected_reordered_values.begin(),
|
||||
expected_reordered_values.end());
|
||||
BOOST_CHECK_EQUAL_COLLECTIONS(reordered_indices.begin(),
|
||||
reordered_indices.end(),
|
||||
expected_reordered_indices.begin(),
|
||||
expected_reordered_indices.end());
|
||||
|
||||
heap.pop(reorder_handler);
|
||||
|
||||
expected_reordered_values = {10, 10, 5, 8, 8, 10};
|
||||
expected_reordered_indices = {0, 1, 0, 2, 0, 0};
|
||||
BOOST_CHECK_EQUAL_COLLECTIONS(reordered_values.begin(),
|
||||
reordered_values.end(),
|
||||
expected_reordered_values.begin(),
|
||||
expected_reordered_values.end());
|
||||
BOOST_CHECK_EQUAL_COLLECTIONS(reordered_indices.begin(),
|
||||
reordered_indices.end(),
|
||||
expected_reordered_indices.begin(),
|
||||
expected_reordered_indices.end());
|
||||
|
||||
heap.pop(reorder_handler);
|
||||
expected_reordered_values = {10, 10, 5, 8, 8, 10};
|
||||
expected_reordered_indices = {0, 1, 0, 2, 0, 0};
|
||||
BOOST_CHECK_EQUAL_COLLECTIONS(reordered_values.begin(),
|
||||
reordered_values.end(),
|
||||
expected_reordered_values.begin(),
|
||||
expected_reordered_values.end());
|
||||
BOOST_CHECK_EQUAL_COLLECTIONS(reordered_indices.begin(),
|
||||
reordered_indices.end(),
|
||||
expected_reordered_indices.begin(),
|
||||
expected_reordered_indices.end());
|
||||
}
|
||||
|
||||
BOOST_AUTO_TEST_SUITE_END()
|
||||
@@ -120,6 +120,28 @@ BOOST_FIXTURE_TEST_CASE_TEMPLATE(delete_all_test, T, storage_types, RandomDataFi
|
||||
BOOST_CHECK(heap.Empty());
|
||||
}
|
||||
|
||||
BOOST_FIXTURE_TEST_CASE_TEMPLATE(smoke_test, T, storage_types, RandomDataFixture<NUM_NODES>)
|
||||
{
|
||||
QueryHeap<TestNodeID, TestKey, TestWeight, TestData, T> heap(NUM_NODES);
|
||||
|
||||
for (unsigned idx : order)
|
||||
{
|
||||
heap.Insert(ids[idx], weights[idx], data[idx]);
|
||||
}
|
||||
|
||||
while (!heap.Empty())
|
||||
{
|
||||
auto old_weight = heap.MinKey();
|
||||
auto node = heap.GetHeapNodeIfWasInserted(heap.Min());
|
||||
BOOST_CHECK(old_weight == node->weight);
|
||||
BOOST_CHECK(node);
|
||||
node->weight = node->weight - 1;
|
||||
heap.DecreaseKey(*node);
|
||||
BOOST_CHECK(heap.MinKey() == node->weight);
|
||||
heap.DeleteMin();
|
||||
}
|
||||
}
|
||||
|
||||
BOOST_FIXTURE_TEST_CASE_TEMPLATE(decrease_key_test, T, storage_types, RandomDataFixture<10>)
|
||||
{
|
||||
QueryHeap<TestNodeID, TestKey, TestWeight, TestData, T> heap(10);
|
||||
|
||||
Reference in New Issue
Block a user