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
{
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
@ -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,
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,
SearchEngineData::QueryHeap &forward_heap,
SearchEngineData::QueryHeap &reverse_heap,
NodeID &middle_node_id,
std::int32_t &upper_bound,
std::int32_t min_edge_offset,
const bool forward_direction,
const bool stalling,
EdgeWeight &upper_bound,
EdgeWeight min_edge_offset,
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>
EdgeWeight

View File

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

View File

@ -81,9 +81,6 @@ extractRoute(const datafacade::ContiguousInternalMemoryDataFacade<AlgorithmT> &f
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.

View File

@ -15,7 +15,7 @@ namespace engine
namespace routing_algorithms
{
using QueryHeap = SearchEngineData::ManyToManyQueryHeap;
using ManyToManyQueryHeap = SearchEngineData::ManyToManyQueryHeap;
namespace
{
@ -29,21 +29,21 @@ struct NodeBucket
{
}
};
// FIXME This should be replaced by an std::unordered_multimap, though this needs benchmarking
using SearchSpaceWithBuckets = std::unordered_map<NodeID, std::vector<NodeBucket>>;
template <bool forward_direction>
template <bool DIRECTION>
void relaxOutgoingEdges(const datafacade::ContiguousInternalMemoryDataFacade<algorithm::CH> &facade,
const NodeID node,
const EdgeWeight weight,
const EdgeWeight duration,
QueryHeap &query_heap)
ManyToManyQueryHeap &query_heap)
{
for (auto edge : facade.GetAdjacentEdgeRange(node))
{
const auto &data = facade.GetEdgeData(edge);
const bool direction_flag = (forward_direction ? data.forward : data.backward);
if (direction_flag)
if (DIRECTION == FORWARD_DIRECTION ? data.forward : data.backward)
{
const NodeID to = facade.GetTarget(edge);
const EdgeWeight edge_weight = data.weight;
@ -69,38 +69,10 @@ void relaxOutgoingEdges(const datafacade::ContiguousInternalMemoryDataFacade<alg
}
}
// Stalling
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,
void forwardRoutingStep(const datafacade::ContiguousInternalMemoryDataFacade<algorithm::CH> &facade,
const unsigned row_idx,
const unsigned number_of_targets,
QueryHeap &query_heap,
ManyToManyQueryHeap &query_heap,
const SearchSpaceWithBuckets &search_space_with_buckets,
std::vector<EdgeWeight> &weights_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;
}
relaxOutgoingEdges<true>(facade, node, source_weight, source_duration, query_heap);
relaxOutgoingEdges<FORWARD_DIRECTION>(facade, node, source_weight, source_duration, query_heap);
}
void backwardRoutingStep(
const datafacade::ContiguousInternalMemoryDataFacade<algorithm::CH> &facade,
const unsigned column_idx,
QueryHeap &query_heap,
ManyToManyQueryHeap &query_heap,
SearchSpaceWithBuckets &search_space_with_buckets)
{
const NodeID node = query_heap.DeleteMin();
@ -166,12 +139,12 @@ void backwardRoutingStep(
// store settled nodes in search space bucket
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;
}
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
while (!query_heap.Empty())
{
ForwardRoutingStep(facade,
forwardRoutingStep(facade,
row_idx,
number_of_targets,
query_heap,

View File

@ -7,125 +7,6 @@ namespace engine
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
* route.
@ -207,34 +88,29 @@ void search(const datafacade::ContiguousInternalMemoryDataFacade<algorithm::CH>
BOOST_ASSERT(reverse_heap.MinKey() >= 0);
// run two-Target Dijkstra routing step.
const constexpr bool STALLING_ENABLED = true;
while (0 < (forward_heap.Size() + reverse_heap.Size()))
{
if (!forward_heap.Empty())
{
routingStep(facade,
forward_heap,
reverse_heap,
middle,
weight,
min_edge_offset,
true,
STALLING_ENABLED,
force_loop_forward,
force_loop_reverse);
routingStep<FORWARD_DIRECTION>(facade,
forward_heap,
reverse_heap,
middle,
weight,
min_edge_offset,
force_loop_forward,
force_loop_reverse);
}
if (!reverse_heap.Empty())
{
routingStep(facade,
reverse_heap,
forward_heap,
middle,
weight,
min_edge_offset,
false,
STALLING_ENABLED,
force_loop_reverse,
force_loop_forward);
routingStep<REVERSE_DIRECTION>(facade,
reverse_heap,
forward_heap,
middle,
weight,
min_edge_offset,
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
BOOST_ASSERT(reverse_heap.MinKey() >= 0);
const constexpr bool STALLING_ENABLED = true;
// run two-Target Dijkstra routing step.
while (0 < (forward_heap.Size() + reverse_heap.Size()))
{
@ -307,14 +182,12 @@ void search(const datafacade::ContiguousInternalMemoryDataFacade<algorithm::Core
}
else
{
routingStep(facade,
routingStep<FORWARD_DIRECTION>(facade,
forward_heap,
reverse_heap,
middle,
weight,
min_edge_offset,
true,
STALLING_ENABLED,
force_loop_forward,
force_loop_reverse);
}
@ -329,14 +202,12 @@ void search(const datafacade::ContiguousInternalMemoryDataFacade<algorithm::Core
}
else
{
routingStep(facade,
routingStep<REVERSE_DIRECTION>(facade,
reverse_heap,
forward_heap,
middle,
weight,
min_edge_offset,
false,
STALLING_ENABLED,
force_loop_reverse,
force_loop_forward);
}
@ -378,29 +249,24 @@ void search(const datafacade::ContiguousInternalMemoryDataFacade<algorithm::Core
BOOST_ASSERT(min_core_edge_offset <= 0);
// 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() &&
weight > (forward_core_heap.MinKey() + reverse_core_heap.MinKey()))
{
routingStep(facade,
routingStep<FORWARD_DIRECTION, DISABLE_STALLING>(facade,
forward_core_heap,
reverse_core_heap,
middle,
weight,
min_core_edge_offset,
true,
STALLING_DISABLED,
force_loop_forward,
force_loop_reverse);
routingStep(facade,
routingStep<REVERSE_DIRECTION, DISABLE_STALLING>(facade,
reverse_core_heap,
forward_core_heap,
middle,
weight,
min_core_edge_offset,
false,
STALLING_DISABLED,
force_loop_reverse,
force_loop_forward);
}
@ -571,9 +437,6 @@ getNetworkDistance(const datafacade::ContiguousInternalMemoryDataFacade<algorith
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;
std::vector<NodeID> packed_path;
search(facade,
@ -635,9 +498,6 @@ getNetworkDistance(const datafacade::ContiguousInternalMemoryDataFacade<algorith
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;
std::vector<NodeID> packed_path;
search(facade,