Refactor routeStep

This commit is contained in:
Patrick Niklaus 2017-02-25 13:31:04 +00:00 committed by Patrick Niklaus
parent 7da86b5984
commit 30ff0fa977
5 changed files with 234 additions and 294 deletions

View File

@ -33,6 +33,68 @@ namespace engine
namespace routing_algorithms namespace routing_algorithms
{ {
static constexpr bool FORWARD_DIRECTION = true;
static constexpr bool REVERSE_DIRECTION = false;
// Stalling
template <bool DIRECTION, typename HeapT>
bool stallAtNode(const datafacade::ContiguousInternalMemoryDataFacade<algorithm::CH> &facade,
const NodeID node,
const EdgeWeight weight,
HeapT &query_heap)
{
for (auto edge : facade.GetAdjacentEdgeRange(node))
{
const auto &data = facade.GetEdgeData(edge);
if (DIRECTION == REVERSE_DIRECTION ? data.forward : data.backward)
{
const NodeID to = facade.GetTarget(edge);
const EdgeWeight edge_weight = data.weight;
BOOST_ASSERT_MSG(edge_weight > 0, "edge_weight invalid");
if (query_heap.WasInserted(to))
{
if (query_heap.GetKey(to) + edge_weight < weight)
{
return true;
}
}
}
}
return false;
}
template <bool DIRECTION>
void relaxOutgoingEdges(const datafacade::ContiguousInternalMemoryDataFacade<algorithm::CH> &facade,
const NodeID node,
const EdgeWeight weight,
SearchEngineData::QueryHeap &heap)
{
for (const auto edge : facade.GetAdjacentEdgeRange(node))
{
const auto &data = facade.GetEdgeData(edge);
if (DIRECTION == FORWARD_DIRECTION ? data.forward : data.backward)
{
const NodeID to = facade.GetTarget(edge);
const EdgeWeight edge_weight = data.weight;
BOOST_ASSERT_MSG(edge_weight > 0, "edge_weight invalid");
const EdgeWeight to_weight = weight + edge_weight;
// New Node discovered -> Add to Heap + Node Info Storage
if (!heap.WasInserted(to))
{
heap.Insert(to, to_weight, node);
}
// Found a shorter Path -> Update weight
else if (to_weight < heap.GetKey(to))
{
// new parent
heap.GetData(to).parent = node;
heap.DecreaseKey(to, to_weight);
}
}
}
}
/* /*
min_edge_offset is needed in case we use multiple min_edge_offset is needed in case we use multiple
@ -63,16 +125,81 @@ using edges (y, a) with weight -100, (y, b) with weight 0 and,
Since we are dealing with a graph that contains _negative_ edges, Since we are dealing with a graph that contains _negative_ edges,
we need to add an offset to the termination criterion. we need to add an offset to the termination criterion.
*/ */
static constexpr bool ENABLE_STALLING = true;
static constexpr bool DISABLE_STALLING = false;
static constexpr bool DO_NOT_FORCE_LOOPS = false;
template<bool DIRECTION, bool STALLING=ENABLE_STALLING>
void routingStep(const datafacade::ContiguousInternalMemoryDataFacade<algorithm::CH> &facade, void routingStep(const datafacade::ContiguousInternalMemoryDataFacade<algorithm::CH> &facade,
SearchEngineData::QueryHeap &forward_heap, SearchEngineData::QueryHeap &forward_heap,
SearchEngineData::QueryHeap &reverse_heap, SearchEngineData::QueryHeap &reverse_heap,
NodeID &middle_node_id, NodeID &middle_node_id,
std::int32_t &upper_bound, EdgeWeight &upper_bound,
std::int32_t min_edge_offset, EdgeWeight min_edge_offset,
const bool forward_direction,
const bool stalling,
const bool force_loop_forward, const bool force_loop_forward,
const bool force_loop_reverse); const bool force_loop_reverse)
{
const NodeID node = forward_heap.DeleteMin();
const EdgeWeight weight = forward_heap.GetKey(node);
if (reverse_heap.WasInserted(node))
{
const EdgeWeight new_weight = reverse_heap.GetKey(node) + weight;
if (new_weight < upper_bound)
{
// 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) ||
// in this case we are looking at a bi-directional way where the source
// and target phantom are on the same edge based node
new_weight < 0)
{
// check whether there is a loop present at the node
for (const auto edge : facade.GetAdjacentEdgeRange(node))
{
const auto &data = facade.GetEdgeData(edge);
if (DIRECTION == FORWARD_DIRECTION ? data.forward : data.backward)
{
const NodeID to = facade.GetTarget(edge);
if (to == node)
{
const EdgeWeight edge_weight = data.weight;
const EdgeWeight loop_weight = new_weight + edge_weight;
if (loop_weight >= 0 && loop_weight < upper_bound)
{
middle_node_id = node;
upper_bound = loop_weight;
}
}
}
}
}
else
{
BOOST_ASSERT(new_weight >= 0);
middle_node_id = node;
upper_bound = new_weight;
}
}
}
// make sure we don't terminate too early if we initialize the weight
// for the nodes in the forward heap with the forward/reverse offset
BOOST_ASSERT(min_edge_offset <= 0);
if (weight + min_edge_offset > upper_bound)
{
forward_heap.DeleteAll();
return;
}
// Stalling
if (STALLING && stallAtNode<DIRECTION>(facade, node, weight, forward_heap))
{
return;
}
relaxOutgoingEdges<DIRECTION>(facade, node, weight, forward_heap);
}
template <bool UseDuration> template <bool UseDuration>
EdgeWeight EdgeWeight

View File

@ -47,7 +47,7 @@ struct RankedCandidateNode
}; };
// todo: reorder parameters // todo: reorder parameters
template <bool is_forward_directed> template <bool DIRECTION>
void alternativeRoutingStep( void alternativeRoutingStep(
const datafacade::ContiguousInternalMemoryDataFacade<algorithm::CH> &facade, const datafacade::ContiguousInternalMemoryDataFacade<algorithm::CH> &facade,
QueryHeap &heap1, QueryHeap &heap1,
@ -58,8 +58,8 @@ void alternativeRoutingStep(
std::vector<SearchSpaceEdge> &search_space, std::vector<SearchSpaceEdge> &search_space,
const EdgeWeight min_edge_offset) const EdgeWeight min_edge_offset)
{ {
QueryHeap &forward_heap = (is_forward_directed ? heap1 : heap2); QueryHeap &forward_heap = DIRECTION == FORWARD_DIRECTION ? heap1 : heap2;
QueryHeap &reverse_heap = (is_forward_directed ? heap2 : heap1); QueryHeap &reverse_heap = DIRECTION == FORWARD_DIRECTION ? heap2 : heap1;
const NodeID node = forward_heap.DeleteMin(); const NodeID node = forward_heap.DeleteMin();
const EdgeWeight weight = forward_heap.GetKey(node); const EdgeWeight weight = forward_heap.GetKey(node);
@ -104,8 +104,7 @@ void alternativeRoutingStep(
for (auto edge : facade.GetAdjacentEdgeRange(node)) for (auto edge : facade.GetAdjacentEdgeRange(node))
{ {
const auto &data = facade.GetEdgeData(edge); const auto &data = facade.GetEdgeData(edge);
const bool edge_is_forward_directed = (is_forward_directed ? data.forward : data.backward); if (DIRECTION == FORWARD_DIRECTION ? data.forward : data.backward)
if (edge_is_forward_directed)
{ {
const NodeID to = facade.GetTarget(edge); const NodeID to = facade.GetTarget(edge);
const EdgeWeight edge_weight = data.weight; const EdgeWeight edge_weight = data.weight;
@ -179,20 +178,16 @@ void computeLengthAndSharingOfViaPath(
int upper_bound_s_v_path_length = INVALID_EDGE_WEIGHT; int upper_bound_s_v_path_length = INVALID_EDGE_WEIGHT;
new_reverse_heap.Insert(via_node, 0, via_node); new_reverse_heap.Insert(via_node, 0, via_node);
// compute path <s,..,v> by reusing forward search from s // compute path <s,..,v> by reusing forward search from s
const bool constexpr STALLING_ENABLED = true;
const bool constexpr DO_NOT_FORCE_LOOPS = false;
while (!new_reverse_heap.Empty()) while (!new_reverse_heap.Empty())
{ {
routingStep(facade, routingStep<REVERSE_DIRECTION>(facade,
new_reverse_heap, new_reverse_heap,
existing_forward_heap, existing_forward_heap,
s_v_middle, s_v_middle,
upper_bound_s_v_path_length, upper_bound_s_v_path_length,
min_edge_offset, min_edge_offset,
false, DO_NOT_FORCE_LOOPS,
STALLING_ENABLED, DO_NOT_FORCE_LOOPS);
DO_NOT_FORCE_LOOPS,
DO_NOT_FORCE_LOOPS);
} }
// compute path <v,..,t> by reusing backward search from node t // compute path <v,..,t> by reusing backward search from node t
NodeID v_t_middle = SPECIAL_NODEID; NodeID v_t_middle = SPECIAL_NODEID;
@ -200,16 +195,14 @@ void computeLengthAndSharingOfViaPath(
new_forward_heap.Insert(via_node, 0, via_node); new_forward_heap.Insert(via_node, 0, via_node);
while (!new_forward_heap.Empty()) while (!new_forward_heap.Empty())
{ {
routingStep(facade, routingStep<FORWARD_DIRECTION>(facade,
new_forward_heap, new_forward_heap,
existing_reverse_heap, existing_reverse_heap,
v_t_middle, v_t_middle,
upper_bound_of_v_t_path_length, upper_bound_of_v_t_path_length,
min_edge_offset, min_edge_offset,
true, DO_NOT_FORCE_LOOPS,
STALLING_ENABLED, DO_NOT_FORCE_LOOPS);
DO_NOT_FORCE_LOOPS,
DO_NOT_FORCE_LOOPS);
} }
*real_length_of_via_path = upper_bound_s_v_path_length + upper_bound_of_v_t_path_length; *real_length_of_via_path = upper_bound_s_v_path_length + upper_bound_of_v_t_path_length;
@ -347,20 +340,16 @@ bool viaNodeCandidatePassesTTest(
int upper_bound_s_v_path_length = INVALID_EDGE_WEIGHT; int upper_bound_s_v_path_length = INVALID_EDGE_WEIGHT;
// compute path <s,..,v> by reusing forward search from s // compute path <s,..,v> by reusing forward search from s
new_reverse_heap.Insert(candidate.node, 0, candidate.node); new_reverse_heap.Insert(candidate.node, 0, candidate.node);
const bool constexpr STALLING_ENABLED = true;
const bool constexpr DO_NOT_FORCE_LOOPS = false;
while (new_reverse_heap.Size() > 0) while (new_reverse_heap.Size() > 0)
{ {
routingStep(facade, routingStep<REVERSE_DIRECTION>(facade,
new_reverse_heap, new_reverse_heap,
existing_forward_heap, existing_forward_heap,
*s_v_middle, *s_v_middle,
upper_bound_s_v_path_length, upper_bound_s_v_path_length,
min_edge_offset, min_edge_offset,
false, DO_NOT_FORCE_LOOPS,
STALLING_ENABLED, DO_NOT_FORCE_LOOPS);
DO_NOT_FORCE_LOOPS,
DO_NOT_FORCE_LOOPS);
} }
if (INVALID_EDGE_WEIGHT == upper_bound_s_v_path_length) if (INVALID_EDGE_WEIGHT == upper_bound_s_v_path_length)
@ -374,16 +363,14 @@ bool viaNodeCandidatePassesTTest(
new_forward_heap.Insert(candidate.node, 0, candidate.node); new_forward_heap.Insert(candidate.node, 0, candidate.node);
while (new_forward_heap.Size() > 0) while (new_forward_heap.Size() > 0)
{ {
routingStep(facade, routingStep<FORWARD_DIRECTION>(facade,
new_forward_heap, new_forward_heap,
existing_reverse_heap, existing_reverse_heap,
*v_t_middle, *v_t_middle,
upper_bound_of_v_t_path_length, upper_bound_of_v_t_path_length,
min_edge_offset, min_edge_offset,
true, DO_NOT_FORCE_LOOPS,
STALLING_ENABLED, DO_NOT_FORCE_LOOPS);
DO_NOT_FORCE_LOOPS,
DO_NOT_FORCE_LOOPS);
} }
if (INVALID_EDGE_WEIGHT == upper_bound_of_v_t_path_length) if (INVALID_EDGE_WEIGHT == upper_bound_of_v_t_path_length)
@ -549,29 +536,25 @@ bool viaNodeCandidatePassesTTest(
{ {
if (!forward_heap3.Empty()) if (!forward_heap3.Empty())
{ {
routingStep(facade, routingStep<FORWARD_DIRECTION>(facade,
forward_heap3, forward_heap3,
reverse_heap3, reverse_heap3,
middle, middle,
upper_bound, upper_bound,
min_edge_offset, min_edge_offset,
true, DO_NOT_FORCE_LOOPS,
STALLING_ENABLED, DO_NOT_FORCE_LOOPS);
DO_NOT_FORCE_LOOPS,
DO_NOT_FORCE_LOOPS);
} }
if (!reverse_heap3.Empty()) if (!reverse_heap3.Empty())
{ {
routingStep(facade, routingStep<REVERSE_DIRECTION>(facade,
reverse_heap3, reverse_heap3,
forward_heap3, forward_heap3,
middle, middle,
upper_bound, upper_bound,
min_edge_offset, min_edge_offset,
false, DO_NOT_FORCE_LOOPS,
STALLING_ENABLED, DO_NOT_FORCE_LOOPS);
DO_NOT_FORCE_LOOPS,
DO_NOT_FORCE_LOOPS);
} }
} }
return (upper_bound <= t_test_path_length); return (upper_bound <= t_test_path_length);
@ -644,25 +627,25 @@ alternativePathSearch(SearchEngineData &engine_working_data,
{ {
if (0 < forward_heap1.Size()) if (0 < forward_heap1.Size())
{ {
alternativeRoutingStep<true>(facade, alternativeRoutingStep<FORWARD_DIRECTION>(facade,
forward_heap1, forward_heap1,
reverse_heap1, reverse_heap1,
&middle_node, &middle_node,
&upper_bound_to_shortest_path_weight, &upper_bound_to_shortest_path_weight,
via_node_candidate_list, via_node_candidate_list,
forward_search_space, forward_search_space,
min_edge_offset); min_edge_offset);
} }
if (0 < reverse_heap1.Size()) if (0 < reverse_heap1.Size())
{ {
alternativeRoutingStep<false>(facade, alternativeRoutingStep<REVERSE_DIRECTION>(facade,
forward_heap1, forward_heap1,
reverse_heap1, reverse_heap1,
&middle_node, &middle_node,
&upper_bound_to_shortest_path_weight, &upper_bound_to_shortest_path_weight,
via_node_candidate_list, via_node_candidate_list,
reverse_search_space, reverse_search_space,
min_edge_offset); min_edge_offset);
} }
} }

View File

@ -81,9 +81,6 @@ extractRoute(const datafacade::ContiguousInternalMemoryDataFacade<AlgorithmT> &f
return raw_route_data; return raw_route_data;
} }
// prevents forcing of loops, since offsets are set correctly
static const bool constexpr DO_NOT_FORCE_LOOPS = false;
} }
/// This is a striped down version of the general shortest path algorithm. /// This is a striped down version of the general shortest path algorithm.

View File

@ -15,7 +15,7 @@ namespace engine
namespace routing_algorithms namespace routing_algorithms
{ {
using QueryHeap = SearchEngineData::ManyToManyQueryHeap; using ManyToManyQueryHeap = SearchEngineData::ManyToManyQueryHeap;
namespace namespace
{ {
@ -29,21 +29,21 @@ struct NodeBucket
{ {
} }
}; };
// FIXME This should be replaced by an std::unordered_multimap, though this needs benchmarking // FIXME This should be replaced by an std::unordered_multimap, though this needs benchmarking
using SearchSpaceWithBuckets = std::unordered_map<NodeID, std::vector<NodeBucket>>; using SearchSpaceWithBuckets = std::unordered_map<NodeID, std::vector<NodeBucket>>;
template <bool forward_direction> template <bool DIRECTION>
void relaxOutgoingEdges(const datafacade::ContiguousInternalMemoryDataFacade<algorithm::CH> &facade, void relaxOutgoingEdges(const datafacade::ContiguousInternalMemoryDataFacade<algorithm::CH> &facade,
const NodeID node, const NodeID node,
const EdgeWeight weight, const EdgeWeight weight,
const EdgeWeight duration, const EdgeWeight duration,
QueryHeap &query_heap) ManyToManyQueryHeap &query_heap)
{ {
for (auto edge : facade.GetAdjacentEdgeRange(node)) for (auto edge : facade.GetAdjacentEdgeRange(node))
{ {
const auto &data = facade.GetEdgeData(edge); const auto &data = facade.GetEdgeData(edge);
const bool direction_flag = (forward_direction ? data.forward : data.backward); if (DIRECTION == FORWARD_DIRECTION ? data.forward : data.backward)
if (direction_flag)
{ {
const NodeID to = facade.GetTarget(edge); const NodeID to = facade.GetTarget(edge);
const EdgeWeight edge_weight = data.weight; const EdgeWeight edge_weight = data.weight;
@ -69,38 +69,10 @@ void relaxOutgoingEdges(const datafacade::ContiguousInternalMemoryDataFacade<alg
} }
} }
// Stalling void forwardRoutingStep(const datafacade::ContiguousInternalMemoryDataFacade<algorithm::CH> &facade,
template <bool forward_direction>
bool stallAtNode(const datafacade::ContiguousInternalMemoryDataFacade<algorithm::CH> &facade,
const NodeID node,
const EdgeWeight weight,
QueryHeap &query_heap)
{
for (auto edge : facade.GetAdjacentEdgeRange(node))
{
const auto &data = facade.GetEdgeData(edge);
const bool reverse_flag = ((!forward_direction) ? data.forward : data.backward);
if (reverse_flag)
{
const NodeID to = facade.GetTarget(edge);
const EdgeWeight edge_weight = data.weight;
BOOST_ASSERT_MSG(edge_weight > 0, "edge_weight invalid");
if (query_heap.WasInserted(to))
{
if (query_heap.GetKey(to) + edge_weight < weight)
{
return true;
}
}
}
}
return false;
}
void ForwardRoutingStep(const datafacade::ContiguousInternalMemoryDataFacade<algorithm::CH> &facade,
const unsigned row_idx, const unsigned row_idx,
const unsigned number_of_targets, const unsigned number_of_targets,
QueryHeap &query_heap, ManyToManyQueryHeap &query_heap,
const SearchSpaceWithBuckets &search_space_with_buckets, const SearchSpaceWithBuckets &search_space_with_buckets,
std::vector<EdgeWeight> &weights_table, std::vector<EdgeWeight> &weights_table,
std::vector<EdgeWeight> &durations_table) std::vector<EdgeWeight> &durations_table)
@ -146,17 +118,18 @@ void ForwardRoutingStep(const datafacade::ContiguousInternalMemoryDataFacade<alg
} }
} }
} }
if (stallAtNode<true>(facade, node, source_weight, query_heap)) if (stallAtNode<FORWARD_DIRECTION>(facade, node, source_weight, query_heap))
{ {
return; return;
} }
relaxOutgoingEdges<true>(facade, node, source_weight, source_duration, query_heap);
relaxOutgoingEdges<FORWARD_DIRECTION>(facade, node, source_weight, source_duration, query_heap);
} }
void backwardRoutingStep( void backwardRoutingStep(
const datafacade::ContiguousInternalMemoryDataFacade<algorithm::CH> &facade, const datafacade::ContiguousInternalMemoryDataFacade<algorithm::CH> &facade,
const unsigned column_idx, const unsigned column_idx,
QueryHeap &query_heap, ManyToManyQueryHeap &query_heap,
SearchSpaceWithBuckets &search_space_with_buckets) SearchSpaceWithBuckets &search_space_with_buckets)
{ {
const NodeID node = query_heap.DeleteMin(); const NodeID node = query_heap.DeleteMin();
@ -166,12 +139,12 @@ void backwardRoutingStep(
// store settled nodes in search space bucket // store settled nodes in search space bucket
search_space_with_buckets[node].emplace_back(column_idx, target_weight, target_duration); search_space_with_buckets[node].emplace_back(column_idx, target_weight, target_duration);
if (stallAtNode<false>(facade, node, target_weight, query_heap)) if (stallAtNode<REVERSE_DIRECTION>(facade, node, target_weight, query_heap))
{ {
return; return;
} }
relaxOutgoingEdges<false>(facade, node, target_weight, target_duration, query_heap); relaxOutgoingEdges<REVERSE_DIRECTION>(facade, node, target_weight, target_duration, query_heap);
} }
} }
@ -245,7 +218,7 @@ manyToManySearch(SearchEngineData &engine_working_data,
// explore search space // explore search space
while (!query_heap.Empty()) while (!query_heap.Empty())
{ {
ForwardRoutingStep(facade, forwardRoutingStep(facade,
row_idx, row_idx,
number_of_targets, number_of_targets,
query_heap, query_heap,

View File

@ -7,125 +7,6 @@ namespace engine
namespace routing_algorithms namespace routing_algorithms
{ {
void routingStep(const datafacade::ContiguousInternalMemoryDataFacade<algorithm::CH> &facade,
SearchEngineData::QueryHeap &forward_heap,
SearchEngineData::QueryHeap &reverse_heap,
NodeID &middle_node_id,
EdgeWeight &upper_bound,
EdgeWeight min_edge_offset,
const bool forward_direction,
const bool stalling,
const bool force_loop_forward,
const bool force_loop_reverse)
{
const NodeID node = forward_heap.DeleteMin();
const EdgeWeight weight = forward_heap.GetKey(node);
if (reverse_heap.WasInserted(node))
{
const EdgeWeight new_weight = reverse_heap.GetKey(node) + weight;
if (new_weight < upper_bound)
{
// 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) ||
// in this case we are looking at a bi-directional way where the source
// and target phantom are on the same edge based node
new_weight < 0)
{
// check whether there is a loop present at the node
for (const auto edge : facade.GetAdjacentEdgeRange(node))
{
const auto &data = facade.GetEdgeData(edge);
bool forward_directionFlag = (forward_direction ? data.forward : data.backward);
if (forward_directionFlag)
{
const NodeID to = facade.GetTarget(edge);
if (to == node)
{
const EdgeWeight edge_weight = data.weight;
const EdgeWeight loop_weight = new_weight + edge_weight;
if (loop_weight >= 0 && loop_weight < upper_bound)
{
middle_node_id = node;
upper_bound = loop_weight;
}
}
}
}
}
else
{
BOOST_ASSERT(new_weight >= 0);
middle_node_id = node;
upper_bound = new_weight;
}
}
}
// make sure we don't terminate too early if we initialize the weight
// for the nodes in the forward heap with the forward/reverse offset
BOOST_ASSERT(min_edge_offset <= 0);
if (weight + min_edge_offset > upper_bound)
{
forward_heap.DeleteAll();
return;
}
// Stalling
if (stalling)
{
for (const auto edge : facade.GetAdjacentEdgeRange(node))
{
const auto &data = facade.GetEdgeData(edge);
const bool reverse_flag = ((!forward_direction) ? data.forward : data.backward);
if (reverse_flag)
{
const NodeID to = facade.GetTarget(edge);
const EdgeWeight edge_weight = data.weight;
BOOST_ASSERT_MSG(edge_weight > 0, "edge_weight invalid");
if (forward_heap.WasInserted(to))
{
if (forward_heap.GetKey(to) + edge_weight < weight)
{
return;
}
}
}
}
}
for (const auto edge : facade.GetAdjacentEdgeRange(node))
{
const auto &data = facade.GetEdgeData(edge);
bool forward_directionFlag = (forward_direction ? data.forward : data.backward);
if (forward_directionFlag)
{
const NodeID to = facade.GetTarget(edge);
const EdgeWeight edge_weight = data.weight;
BOOST_ASSERT_MSG(edge_weight > 0, "edge_weight invalid");
const EdgeWeight to_weight = weight + edge_weight;
// New Node discovered -> Add to Heap + Node Info Storage
if (!forward_heap.WasInserted(to))
{
forward_heap.Insert(to, to_weight, node);
}
// Found a shorter Path -> Update weight
else if (to_weight < forward_heap.GetKey(to))
{
// new parent
forward_heap.GetData(to).parent = node;
forward_heap.DecreaseKey(to, to_weight);
}
}
}
}
/** /**
* Unpacks a single edge (NodeID->NodeID) from the CH graph down to it's original non-shortcut * Unpacks a single edge (NodeID->NodeID) from the CH graph down to it's original non-shortcut
* route. * route.
@ -207,34 +88,29 @@ void search(const datafacade::ContiguousInternalMemoryDataFacade<algorithm::CH>
BOOST_ASSERT(reverse_heap.MinKey() >= 0); BOOST_ASSERT(reverse_heap.MinKey() >= 0);
// run two-Target Dijkstra routing step. // run two-Target Dijkstra routing step.
const constexpr bool STALLING_ENABLED = true;
while (0 < (forward_heap.Size() + reverse_heap.Size())) while (0 < (forward_heap.Size() + reverse_heap.Size()))
{ {
if (!forward_heap.Empty()) if (!forward_heap.Empty())
{ {
routingStep(facade, routingStep<FORWARD_DIRECTION>(facade,
forward_heap, forward_heap,
reverse_heap, reverse_heap,
middle, middle,
weight, weight,
min_edge_offset, min_edge_offset,
true, force_loop_forward,
STALLING_ENABLED, force_loop_reverse);
force_loop_forward,
force_loop_reverse);
} }
if (!reverse_heap.Empty()) if (!reverse_heap.Empty())
{ {
routingStep(facade, routingStep<REVERSE_DIRECTION>(facade,
reverse_heap, reverse_heap,
forward_heap, forward_heap,
middle, middle,
weight, weight,
min_edge_offset, min_edge_offset,
false, force_loop_reverse,
STALLING_ENABLED, force_loop_forward);
force_loop_reverse,
force_loop_forward);
} }
} }
@ -293,7 +169,6 @@ void search(const datafacade::ContiguousInternalMemoryDataFacade<algorithm::Core
// we only every insert negative offsets for nodes in the forward heap // we only every insert negative offsets for nodes in the forward heap
BOOST_ASSERT(reverse_heap.MinKey() >= 0); BOOST_ASSERT(reverse_heap.MinKey() >= 0);
const constexpr bool STALLING_ENABLED = true;
// run two-Target Dijkstra routing step. // run two-Target Dijkstra routing step.
while (0 < (forward_heap.Size() + reverse_heap.Size())) while (0 < (forward_heap.Size() + reverse_heap.Size()))
{ {
@ -307,14 +182,12 @@ void search(const datafacade::ContiguousInternalMemoryDataFacade<algorithm::Core
} }
else else
{ {
routingStep(facade, routingStep<FORWARD_DIRECTION>(facade,
forward_heap, forward_heap,
reverse_heap, reverse_heap,
middle, middle,
weight, weight,
min_edge_offset, min_edge_offset,
true,
STALLING_ENABLED,
force_loop_forward, force_loop_forward,
force_loop_reverse); force_loop_reverse);
} }
@ -329,14 +202,12 @@ void search(const datafacade::ContiguousInternalMemoryDataFacade<algorithm::Core
} }
else else
{ {
routingStep(facade, routingStep<REVERSE_DIRECTION>(facade,
reverse_heap, reverse_heap,
forward_heap, forward_heap,
middle, middle,
weight, weight,
min_edge_offset, min_edge_offset,
false,
STALLING_ENABLED,
force_loop_reverse, force_loop_reverse,
force_loop_forward); force_loop_forward);
} }
@ -378,29 +249,24 @@ void search(const datafacade::ContiguousInternalMemoryDataFacade<algorithm::Core
BOOST_ASSERT(min_core_edge_offset <= 0); BOOST_ASSERT(min_core_edge_offset <= 0);
// run two-target Dijkstra routing step on core with termination criterion // run two-target Dijkstra routing step on core with termination criterion
const constexpr bool STALLING_DISABLED = false;
while (0 < forward_core_heap.Size() && 0 < reverse_core_heap.Size() && while (0 < forward_core_heap.Size() && 0 < reverse_core_heap.Size() &&
weight > (forward_core_heap.MinKey() + reverse_core_heap.MinKey())) weight > (forward_core_heap.MinKey() + reverse_core_heap.MinKey()))
{ {
routingStep(facade, routingStep<FORWARD_DIRECTION, DISABLE_STALLING>(facade,
forward_core_heap, forward_core_heap,
reverse_core_heap, reverse_core_heap,
middle, middle,
weight, weight,
min_core_edge_offset, min_core_edge_offset,
true,
STALLING_DISABLED,
force_loop_forward, force_loop_forward,
force_loop_reverse); force_loop_reverse);
routingStep(facade, routingStep<REVERSE_DIRECTION, DISABLE_STALLING>(facade,
reverse_core_heap, reverse_core_heap,
forward_core_heap, forward_core_heap,
middle, middle,
weight, weight,
min_core_edge_offset, min_core_edge_offset,
false,
STALLING_DISABLED,
force_loop_reverse, force_loop_reverse,
force_loop_forward); force_loop_forward);
} }
@ -571,9 +437,6 @@ getNetworkDistance(const datafacade::ContiguousInternalMemoryDataFacade<algorith
target_phantom.reverse_segment_id.id); target_phantom.reverse_segment_id.id);
} }
const bool constexpr DO_NOT_FORCE_LOOPS =
false; // prevents forcing of loops, since offsets are set correctly
EdgeWeight weight = INVALID_EDGE_WEIGHT; EdgeWeight weight = INVALID_EDGE_WEIGHT;
std::vector<NodeID> packed_path; std::vector<NodeID> packed_path;
search(facade, search(facade,
@ -635,9 +498,6 @@ getNetworkDistance(const datafacade::ContiguousInternalMemoryDataFacade<algorith
target_phantom.reverse_segment_id.id); target_phantom.reverse_segment_id.id);
} }
const bool constexpr DO_NOT_FORCE_LOOPS =
false; // prevents forcing of loops, since offsets are set correctly
EdgeWeight weight = INVALID_EDGE_WEIGHT; EdgeWeight weight = INVALID_EDGE_WEIGHT;
std::vector<NodeID> packed_path; std::vector<NodeID> packed_path;
search(facade, search(facade,