Split MLD many-to-many method
This commit is contained in:
parent
454487dd41
commit
2715e5758b
@ -11,7 +11,7 @@ module.exports = function () {
|
||||
var waypoints = [],
|
||||
columnHeaders = tableRows[0].slice(1),
|
||||
rowHeaders = tableRows.map((h) => h[0]).slice(1),
|
||||
symmetric = columnHeaders.every((ele, i) => ele === rowHeaders[i]);
|
||||
symmetric = columnHeaders.length == rowHeaders.length && columnHeaders.every((ele, i) => ele === rowHeaders[i]);
|
||||
|
||||
if (symmetric) {
|
||||
columnHeaders.forEach((nodeName) => {
|
||||
|
@ -41,6 +41,17 @@ Feature: Basic Distance Matrix
|
||||
| c | 30 | 20 | 0 | 30 |
|
||||
| d | 60 | 50 | 30 | 0 |
|
||||
|
||||
When I request a travel time matrix I should get
|
||||
| | a | b | c | d |
|
||||
| a | 0 | 10 | 30 | 60 |
|
||||
|
||||
When I request a travel time matrix I should get
|
||||
| | a |
|
||||
| a | 0 |
|
||||
| b | 10 |
|
||||
| c | 30 |
|
||||
| d | 60 |
|
||||
|
||||
Scenario: Testbot - Travel time matrix with fuzzy match
|
||||
Given the node map
|
||||
"""
|
||||
@ -132,6 +143,13 @@ Feature: Basic Distance Matrix
|
||||
| | a | b | e | f |
|
||||
| a | 0 | 10 | 20 | 30 |
|
||||
|
||||
When I request a travel time matrix I should get
|
||||
| | a |
|
||||
| a | 0 |
|
||||
| b | 10 |
|
||||
| e | 20 |
|
||||
| f | 30 |
|
||||
|
||||
Scenario: Testbot - Travel time 3x2 matrix
|
||||
Given the node map
|
||||
"""
|
||||
|
@ -30,7 +30,7 @@ class RoutingAlgorithmsInterface
|
||||
virtual InternalRouteResult
|
||||
DirectShortestPathSearch(const PhantomNodes &phantom_node_pair) const = 0;
|
||||
|
||||
virtual std::vector<EdgeWeight>
|
||||
virtual std::vector<EdgeDuration>
|
||||
ManyToManySearch(const std::vector<PhantomNode> &phantom_nodes,
|
||||
const std::vector<std::size_t> &source_indices,
|
||||
const std::vector<std::size_t> &target_indices) const = 0;
|
||||
@ -81,7 +81,7 @@ template <typename Algorithm> class RoutingAlgorithms final : public RoutingAlgo
|
||||
InternalRouteResult
|
||||
DirectShortestPathSearch(const PhantomNodes &phantom_nodes) const final override;
|
||||
|
||||
std::vector<EdgeWeight>
|
||||
std::vector<EdgeDuration>
|
||||
ManyToManySearch(const std::vector<PhantomNode> &phantom_nodes,
|
||||
const std::vector<std::size_t> &source_indices,
|
||||
const std::vector<std::size_t> &target_indices) const final override;
|
||||
@ -166,16 +166,6 @@ RoutingAlgorithms<Algorithm>::DirectShortestPathSearch(const PhantomNodes &phant
|
||||
return routing_algorithms::directShortestPathSearch(heaps, *facade, phantom_nodes);
|
||||
}
|
||||
|
||||
template <typename Algorithm>
|
||||
std::vector<EdgeWeight>
|
||||
RoutingAlgorithms<Algorithm>::ManyToManySearch(const std::vector<PhantomNode> &phantom_nodes,
|
||||
const std::vector<std::size_t> &source_indices,
|
||||
const std::vector<std::size_t> &target_indices) const
|
||||
{
|
||||
return routing_algorithms::manyToManySearch(
|
||||
heaps, *facade, phantom_nodes, source_indices, target_indices);
|
||||
}
|
||||
|
||||
template <typename Algorithm>
|
||||
inline routing_algorithms::SubMatchingList RoutingAlgorithms<Algorithm>::MapMatching(
|
||||
const routing_algorithms::CandidateLists &candidates_list,
|
||||
@ -211,7 +201,7 @@ InternalManyRoutesResult inline RoutingAlgorithms<
|
||||
}
|
||||
|
||||
template <>
|
||||
inline std::vector<EdgeWeight>
|
||||
inline std::vector<EdgeDuration>
|
||||
RoutingAlgorithms<routing_algorithms::corech::Algorithm>::ManyToManySearch(
|
||||
const std::vector<PhantomNode> &,
|
||||
const std::vector<std::size_t> &,
|
||||
|
@ -17,11 +17,23 @@ namespace routing_algorithms
|
||||
{
|
||||
|
||||
template <typename Algorithm>
|
||||
std::vector<EdgeWeight> manyToManySearch(SearchEngineData<Algorithm> &engine_working_data,
|
||||
const DataFacade<Algorithm> &facade,
|
||||
const std::vector<PhantomNode> &phantom_nodes,
|
||||
std::vector<std::size_t> source_indices,
|
||||
std::vector<std::size_t> target_indices);
|
||||
std::vector<EdgeDuration> manyToManySearch(SearchEngineData<Algorithm> &engine_working_data,
|
||||
const DataFacade<Algorithm> &facade,
|
||||
const std::vector<PhantomNode> &phantom_nodes,
|
||||
std::vector<std::size_t> source_indices,
|
||||
std::vector<std::size_t> target_indices);
|
||||
|
||||
namespace mld
|
||||
{
|
||||
|
||||
template <bool DIRECTION>
|
||||
std::vector<EdgeDuration> oneToManySearch(SearchEngineData<Algorithm> &engine_working_data,
|
||||
const DataFacade<Algorithm> &facade,
|
||||
const std::vector<PhantomNode> &phantom_nodes,
|
||||
std::size_t phantom_index,
|
||||
std::vector<std::size_t> phantom_indices);
|
||||
|
||||
} // mld
|
||||
|
||||
} // namespace routing_algorithms
|
||||
} // namespace engine
|
||||
|
56
src/engine/routing_algorithms.cpp
Normal file
56
src/engine/routing_algorithms.cpp
Normal file
@ -0,0 +1,56 @@
|
||||
#include "engine/routing_algorithms.hpp"
|
||||
|
||||
namespace osrm
|
||||
{
|
||||
namespace engine
|
||||
{
|
||||
|
||||
template <typename Algorithm>
|
||||
std::vector<EdgeDuration>
|
||||
RoutingAlgorithms<Algorithm>::ManyToManySearch(const std::vector<PhantomNode> &phantom_nodes,
|
||||
const std::vector<std::size_t> &source_indices,
|
||||
const std::vector<std::size_t> &target_indices) const
|
||||
{
|
||||
return routing_algorithms::manyToManySearch(
|
||||
heaps, *facade, phantom_nodes, source_indices, target_indices);
|
||||
}
|
||||
|
||||
template std::vector<EdgeDuration>
|
||||
RoutingAlgorithms<routing_algorithms::ch::Algorithm>::ManyToManySearch(
|
||||
const std::vector<PhantomNode> &phantom_nodes,
|
||||
const std::vector<std::size_t> &source_indices,
|
||||
const std::vector<std::size_t> &target_indices) const;
|
||||
|
||||
template std::vector<EdgeDuration>
|
||||
RoutingAlgorithms<routing_algorithms::corech::Algorithm>::ManyToManySearch(
|
||||
const std::vector<PhantomNode> &phantom_nodes,
|
||||
const std::vector<std::size_t> &source_indices,
|
||||
const std::vector<std::size_t> &target_indices) const;
|
||||
|
||||
// One-to-many and many-to-one can be handled with MLD separately from many-to-many search.
|
||||
// One-to-many (many-to-one) search is a unidirectional forward (backward) Dijkstra search
|
||||
// with the candidate node level min(GetQueryLevel(phantom_node, phantom_nodes, node)
|
||||
template <>
|
||||
std::vector<EdgeDuration> RoutingAlgorithms<routing_algorithms::mld::Algorithm>::ManyToManySearch(
|
||||
const std::vector<PhantomNode> &phantom_nodes,
|
||||
const std::vector<std::size_t> &source_indices,
|
||||
const std::vector<std::size_t> &target_indices) const
|
||||
{
|
||||
if (source_indices.size() == 1)
|
||||
{ // TODO: check if target_indices.size() == 1 and do a bi-directional search
|
||||
return routing_algorithms::mld::oneToManySearch<routing_algorithms::FORWARD_DIRECTION>(
|
||||
heaps, *facade, phantom_nodes, source_indices.front(), target_indices);
|
||||
}
|
||||
|
||||
if (target_indices.size() == 1)
|
||||
{
|
||||
return routing_algorithms::mld::oneToManySearch<routing_algorithms::REVERSE_DIRECTION>(
|
||||
heaps, *facade, phantom_nodes, target_indices.front(), source_indices);
|
||||
}
|
||||
|
||||
return routing_algorithms::manyToManySearch(
|
||||
heaps, *facade, phantom_nodes, source_indices, target_indices);
|
||||
}
|
||||
|
||||
} // namespace engine
|
||||
} // namespace osrm
|
@ -322,11 +322,11 @@ void backwardRoutingStep(const DataFacade<Algorithm> &facade,
|
||||
}
|
||||
|
||||
template <typename Algorithm>
|
||||
std::vector<EdgeWeight> manyToManySearch(SearchEngineData<Algorithm> &engine_working_data,
|
||||
const DataFacade<Algorithm> &facade,
|
||||
const std::vector<PhantomNode> &phantom_nodes,
|
||||
std::vector<std::size_t> source_indices,
|
||||
std::vector<std::size_t> target_indices)
|
||||
std::vector<EdgeDuration> manyToManySearch(SearchEngineData<Algorithm> &engine_working_data,
|
||||
const DataFacade<Algorithm> &facade,
|
||||
const std::vector<PhantomNode> &phantom_nodes,
|
||||
std::vector<std::size_t> source_indices,
|
||||
std::vector<std::size_t> target_indices)
|
||||
{
|
||||
if (source_indices.empty())
|
||||
{
|
||||
@ -415,20 +415,57 @@ std::vector<EdgeWeight> manyToManySearch(SearchEngineData<Algorithm> &engine_wor
|
||||
return durations_table;
|
||||
}
|
||||
|
||||
template std::vector<EdgeWeight>
|
||||
template std::vector<EdgeDuration>
|
||||
manyToManySearch(SearchEngineData<ch::Algorithm> &engine_working_data,
|
||||
const DataFacade<ch::Algorithm> &facade,
|
||||
const std::vector<PhantomNode> &phantom_nodes,
|
||||
std::vector<std::size_t> source_indices,
|
||||
std::vector<std::size_t> target_indices);
|
||||
|
||||
template std::vector<EdgeWeight>
|
||||
template std::vector<EdgeDuration>
|
||||
manyToManySearch(SearchEngineData<mld::Algorithm> &engine_working_data,
|
||||
const DataFacade<mld::Algorithm> &facade,
|
||||
const std::vector<PhantomNode> &phantom_nodes,
|
||||
std::vector<std::size_t> source_indices,
|
||||
std::vector<std::size_t> target_indices);
|
||||
|
||||
namespace mld
|
||||
{
|
||||
|
||||
template <bool DIRECTION>
|
||||
std::vector<EdgeDuration> oneToManySearch(SearchEngineData<Algorithm> &engine_working_data,
|
||||
const DataFacade<Algorithm> &facade,
|
||||
const std::vector<PhantomNode> &phantom_nodes,
|
||||
std::size_t phantom_index,
|
||||
std::vector<std::size_t> phantom_indices)
|
||||
{
|
||||
if (phantom_indices.empty())
|
||||
{
|
||||
phantom_indices.resize(phantom_nodes.size());
|
||||
std::iota(phantom_indices.begin(), phantom_indices.end(), 0);
|
||||
}
|
||||
|
||||
std::vector<EdgeWeight> weights(phantom_nodes.size(), INVALID_EDGE_WEIGHT);
|
||||
std::vector<EdgeDuration> durations(phantom_nodes.size(), MAXIMAL_EDGE_DURATION);
|
||||
|
||||
return durations;
|
||||
}
|
||||
|
||||
template std::vector<EdgeDuration>
|
||||
oneToManySearch<FORWARD_DIRECTION>(SearchEngineData<Algorithm> &engine_working_data,
|
||||
const DataFacade<Algorithm> &facade,
|
||||
const std::vector<PhantomNode> &phantom_nodes,
|
||||
std::size_t phantom_index,
|
||||
std::vector<std::size_t> phantom_indices);
|
||||
|
||||
template std::vector<EdgeDuration>
|
||||
oneToManySearch<REVERSE_DIRECTION>(SearchEngineData<Algorithm> &engine_working_data,
|
||||
const DataFacade<Algorithm> &facade,
|
||||
const std::vector<PhantomNode> &phantom_nodes,
|
||||
std::size_t phantom_index,
|
||||
std::vector<std::size_t> phantom_indices);
|
||||
} // mld
|
||||
|
||||
} // namespace routing_algorithms
|
||||
} // namespace engine
|
||||
} // namespace osrm
|
||||
|
Loading…
Reference in New Issue
Block a user