WIP: add appropriate distances property where needed

This commit is contained in:
Kajari Ghosh 2018-09-19 19:52:05 -04:00
parent b86232d6bd
commit c3fc68c139
8 changed files with 115 additions and 31 deletions

View File

@ -22,6 +22,7 @@ class CellCustomizer
{ {
bool from_clique; bool from_clique;
EdgeDuration duration; EdgeDuration duration;
EdgeDistance distance;
}; };
public: public:
@ -60,7 +61,7 @@ class CellCustomizer
} }
} }
heap.Clear(); heap.Clear();
heap.Insert(source, 0, {false, 0}); heap.Insert(source, 0, {false, 0, 0});
// explore search space // explore search space
while (!heap.Empty() && !destinations_set.empty()) while (!heap.Empty() && !destinations_set.empty())
@ -68,8 +69,18 @@ class CellCustomizer
const NodeID node = heap.DeleteMin(); const NodeID node = heap.DeleteMin();
const EdgeWeight weight = heap.GetKey(node); const EdgeWeight weight = heap.GetKey(node);
const EdgeDuration duration = heap.GetData(node).duration; const EdgeDuration duration = heap.GetData(node).duration;
const EdgeDistance distance = heap.GetData(node).distance;
RelaxNode(graph, cells, allowed_nodes, metric, heap, level, node, weight, duration); RelaxNode(graph,
cells,
allowed_nodes,
metric,
heap,
level,
node,
weight,
duration,
distance);
destinations_set.erase(node); destinations_set.erase(node);
} }
@ -77,21 +88,27 @@ class CellCustomizer
// fill a map of destination nodes to placeholder pointers // fill a map of destination nodes to placeholder pointers
auto weights = cell.GetOutWeight(source); auto weights = cell.GetOutWeight(source);
auto durations = cell.GetOutDuration(source); auto durations = cell.GetOutDuration(source);
auto distances = cell.GetOutDistance(source);
for (auto &destination : destinations) for (auto &destination : destinations)
{ {
BOOST_ASSERT(!weights.empty()); BOOST_ASSERT(!weights.empty());
BOOST_ASSERT(!durations.empty()); BOOST_ASSERT(!durations.empty());
BOOST_ASSERT(!distances.empty());
const bool inserted = heap.WasInserted(destination); const bool inserted = heap.WasInserted(destination);
weights.front() = inserted ? heap.GetKey(destination) : INVALID_EDGE_WEIGHT; weights.front() = inserted ? heap.GetKey(destination) : INVALID_EDGE_WEIGHT;
durations.front() = durations.front() =
inserted ? heap.GetData(destination).duration : MAXIMAL_EDGE_DURATION; inserted ? heap.GetData(destination).duration : MAXIMAL_EDGE_DURATION;
distances.front() =
inserted ? heap.GetData(destination).distance : INVALID_EDGE_DISTANCE;
weights.advance_begin(1); weights.advance_begin(1);
durations.advance_begin(1); durations.advance_begin(1);
distances.advance_begin(1);
} }
BOOST_ASSERT(weights.empty()); BOOST_ASSERT(weights.empty());
BOOST_ASSERT(durations.empty()); BOOST_ASSERT(durations.empty());
BOOST_ASSERT(distances.empty());
} }
} }
@ -128,7 +145,8 @@ class CellCustomizer
LevelID level, LevelID level,
NodeID node, NodeID node,
EdgeWeight weight, EdgeWeight weight,
EdgeDuration duration) const EdgeDuration duration,
EdgeDistance distance) const
{ {
auto first_level = level == 1; auto first_level = level == 1;
BOOST_ASSERT(heap.WasInserted(node)); BOOST_ASSERT(heap.WasInserted(node));
@ -149,6 +167,7 @@ class CellCustomizer
auto subcell = cells.GetCell(metric, level - 1, subcell_id); auto subcell = cells.GetCell(metric, level - 1, subcell_id);
auto subcell_destination = subcell.GetDestinationNodes().begin(); auto subcell_destination = subcell.GetDestinationNodes().begin();
auto subcell_duration = subcell.GetOutDuration(node).begin(); auto subcell_duration = subcell.GetOutDuration(node).begin();
auto subcell_distance = subcell.GetOutDistance(node).begin();
for (auto subcell_weight : subcell.GetOutWeight(node)) for (auto subcell_weight : subcell.GetOutWeight(node))
{ {
if (subcell_weight != INVALID_EDGE_WEIGHT) if (subcell_weight != INVALID_EDGE_WEIGHT)
@ -161,20 +180,24 @@ class CellCustomizer
const EdgeWeight to_weight = weight + subcell_weight; const EdgeWeight to_weight = weight + subcell_weight;
const EdgeDuration to_duration = duration + *subcell_duration; const EdgeDuration to_duration = duration + *subcell_duration;
const EdgeDistance to_distance = distance + *subcell_distance;
if (!heap.WasInserted(to)) if (!heap.WasInserted(to))
{ {
heap.Insert(to, to_weight, {true, to_duration}); heap.Insert(to, to_weight, {true, to_duration, to_distance});
} }
else if (std::tie(to_weight, to_duration) < else if (std::tie(to_weight, to_duration, to_distance) <
std::tie(heap.GetKey(to), heap.GetData(to).duration)) std::tie(heap.GetKey(to),
heap.GetData(to).duration,
heap.GetData(to).distance))
{ {
heap.DecreaseKey(to, to_weight); heap.DecreaseKey(to, to_weight);
heap.GetData(to) = {true, to_duration}; heap.GetData(to) = {true, to_duration, to_distance};
} }
} }
++subcell_destination; ++subcell_destination;
++subcell_duration; ++subcell_duration;
++subcell_distance;
} }
} }
} }
@ -195,15 +218,18 @@ class CellCustomizer
{ {
const EdgeWeight to_weight = weight + data.weight; const EdgeWeight to_weight = weight + data.weight;
const EdgeDuration to_duration = duration + data.duration; const EdgeDuration to_duration = duration + data.duration;
const EdgeDistance to_distance = distance + data.distance;
if (!heap.WasInserted(to)) if (!heap.WasInserted(to))
{ {
heap.Insert(to, to_weight, {false, duration + data.duration}); heap.Insert(
to, to_weight, {false, duration + data.duration, distance + data.distance});
} }
else if (std::tie(to_weight, to_duration) < else if (std::tie(to_weight, to_duration, to_distance) <
std::tie(heap.GetKey(to), heap.GetData(to).duration)) std::tie(
heap.GetKey(to), heap.GetData(to).duration, heap.GetData(to).distance))
{ {
heap.DecreaseKey(to, to_weight); heap.DecreaseKey(to, to_weight);
heap.GetData(to) = {false, to_duration}; heap.GetData(to) = {false, to_duration, to_distance};
} }
} }
} }

View File

@ -20,6 +20,7 @@ template <storage::Ownership Ownership> struct CellMetricImpl
Vector<EdgeWeight> weights; Vector<EdgeWeight> weights;
Vector<EdgeDuration> durations; Vector<EdgeDuration> durations;
Vector<EdgeDistance> distances;
}; };
} }

View File

@ -83,11 +83,13 @@ class MultiLevelGraph : public partitioner::MultiLevelGraph<EdgeDataT, Ownership
Vector<EdgeOffset> node_to_edge_offset_, Vector<EdgeOffset> node_to_edge_offset_,
Vector<EdgeWeight> node_weights_, Vector<EdgeWeight> node_weights_,
Vector<EdgeDuration> node_durations_, Vector<EdgeDuration> node_durations_,
Vector<EdgeDistance> node_distances_,
Vector<bool> is_forward_edge_, Vector<bool> is_forward_edge_,
Vector<bool> is_backward_edge_) Vector<bool> is_backward_edge_)
: SuperT(std::move(node_array_), std::move(edge_array_), std::move(node_to_edge_offset_)), : SuperT(std::move(node_array_), std::move(edge_array_), std::move(node_to_edge_offset_)),
node_weights(std::move(node_weights_)), node_durations(std::move(node_durations_)), node_weights(std::move(node_weights_)), node_durations(std::move(node_durations_)),
is_forward_edge(is_forward_edge_), is_backward_edge(is_backward_edge_) node_distances(std::move(node_distances_)), is_forward_edge(is_forward_edge_),
is_backward_edge(is_backward_edge_)
{ {
} }
@ -95,6 +97,8 @@ class MultiLevelGraph : public partitioner::MultiLevelGraph<EdgeDataT, Ownership
EdgeWeight GetNodeDuration(NodeID node) const { return node_durations[node]; } EdgeWeight GetNodeDuration(NodeID node) const { return node_durations[node]; }
EdgeWeight GetNodeDistance(NodeID node) const { return node_distances[node]; }
bool IsForwardEdge(EdgeID edge) const { return is_forward_edge[edge]; } bool IsForwardEdge(EdgeID edge) const { return is_forward_edge[edge]; }
bool IsBackwardEdge(EdgeID edge) const { return is_backward_edge[edge]; } bool IsBackwardEdge(EdgeID edge) const { return is_backward_edge[edge]; }
@ -111,6 +115,7 @@ class MultiLevelGraph : public partitioner::MultiLevelGraph<EdgeDataT, Ownership
protected: protected:
Vector<EdgeWeight> node_weights; Vector<EdgeWeight> node_weights;
Vector<EdgeDuration> node_durations; Vector<EdgeDuration> node_durations;
Vector<EdgeDistance> node_distances;
Vector<bool> is_forward_edge; Vector<bool> is_forward_edge;
Vector<bool> is_backward_edge; Vector<bool> is_backward_edge;
}; };

View File

@ -78,6 +78,8 @@ template <> class AlgorithmDataFacade<MLD>
virtual EdgeWeight GetNodeDuration(const NodeID node) const = 0; // TODO: to be removed virtual EdgeWeight GetNodeDuration(const NodeID node) const = 0; // TODO: to be removed
virtual EdgeDistance GetNodeDistance(const NodeID node) const = 0;
virtual bool IsForwardEdge(EdgeID edge) const = 0; virtual bool IsForwardEdge(EdgeID edge) const = 0;
virtual bool IsBackwardEdge(EdgeID edge) const = 0; virtual bool IsBackwardEdge(EdgeID edge) const = 0;

View File

@ -697,6 +697,11 @@ template <> class ContiguousInternalMemoryAlgorithmDataFacade<MLD> : public Algo
return query_graph.GetNodeDuration(node); return query_graph.GetNodeDuration(node);
} }
EdgeDistance GetNodeDistance(const NodeID node) const override final
{
return query_graph.GetNodeDistance(node);
}
bool IsForwardEdge(const NodeID node) const override final bool IsForwardEdge(const NodeID node) const override final
{ {
return query_graph.IsForwardEdge(node); return query_graph.IsForwardEdge(node);

View File

@ -75,16 +75,19 @@ template <storage::Ownership Ownership> class CellStorageImpl
// Implementation of the cell view. We need a template parameter here // Implementation of the cell view. We need a template parameter here
// because we need to derive a read-only and read-write view from this. // because we need to derive a read-only and read-write view from this.
template <typename WeightValueT, typename DurationValueT> class CellImpl template <typename WeightValueT, typename DurationValueT, typename DistanceValueT>
class CellImpl
{ {
private: private:
using WeightPtrT = WeightValueT *; using WeightPtrT = WeightValueT *;
using DurationPtrT = DurationValueT *; using DurationPtrT = DurationValueT *;
using DistancePtrT = DistanceValueT *;
BoundarySize num_source_nodes; BoundarySize num_source_nodes;
BoundarySize num_destination_nodes; BoundarySize num_destination_nodes;
WeightPtrT const weights; WeightPtrT const weights;
DurationPtrT const durations; DurationPtrT const durations;
DistancePtrT const distances;
const NodeID *const source_boundary; const NodeID *const source_boundary;
const NodeID *const destination_boundary; const NodeID *const destination_boundary;
@ -165,6 +168,14 @@ template <storage::Ownership Ownership> class CellStorageImpl
auto GetInDuration(NodeID node) const { return GetInRange(durations, node); } auto GetInDuration(NodeID node) const { return GetInRange(durations, node); }
auto GetOutDistance(NodeID node) const
{
return GetOutRange(distances, node);
} // Might be symmetric and may be able to get away with simply having GetDistance and not
// have both GetInDistance and GetOutDistance
auto GetInDistance(NodeID node) const { return GetInRange(distances, node); }
auto GetSourceNodes() const auto GetSourceNodes() const
{ {
return boost::make_iterator_range(source_boundary, source_boundary + num_source_nodes); return boost::make_iterator_range(source_boundary, source_boundary + num_source_nodes);
@ -179,17 +190,20 @@ template <storage::Ownership Ownership> class CellStorageImpl
CellImpl(const CellData &data, CellImpl(const CellData &data,
WeightPtrT const all_weights, WeightPtrT const all_weights,
DurationPtrT const all_durations, DurationPtrT const all_durations,
DistancePtrT const all_distances,
const NodeID *const all_sources, const NodeID *const all_sources,
const NodeID *const all_destinations) const NodeID *const all_destinations)
: num_source_nodes{data.num_source_nodes}, : num_source_nodes{data.num_source_nodes},
num_destination_nodes{data.num_destination_nodes}, num_destination_nodes{data.num_destination_nodes},
weights{all_weights + data.value_offset}, weights{all_weights + data.value_offset},
durations{all_durations + data.value_offset}, durations{all_durations + data.value_offset},
distances{all_distances + data.value_offset},
source_boundary{all_sources + data.source_boundary_offset}, source_boundary{all_sources + data.source_boundary_offset},
destination_boundary{all_destinations + data.destination_boundary_offset} destination_boundary{all_destinations + data.destination_boundary_offset}
{ {
BOOST_ASSERT(all_weights != nullptr); BOOST_ASSERT(all_weights != nullptr);
BOOST_ASSERT(all_durations != nullptr); BOOST_ASSERT(all_durations != nullptr);
BOOST_ASSERT(all_durations != nullptr);
BOOST_ASSERT(num_source_nodes == 0 || all_sources != nullptr); BOOST_ASSERT(num_source_nodes == 0 || all_sources != nullptr);
BOOST_ASSERT(num_destination_nodes == 0 || all_destinations != nullptr); BOOST_ASSERT(num_destination_nodes == 0 || all_destinations != nullptr);
} }
@ -201,7 +215,8 @@ template <storage::Ownership Ownership> class CellStorageImpl
const NodeID *const all_destinations) const NodeID *const all_destinations)
: num_source_nodes{data.num_source_nodes}, : num_source_nodes{data.num_source_nodes},
num_destination_nodes{data.num_destination_nodes}, weights{nullptr}, num_destination_nodes{data.num_destination_nodes}, weights{nullptr},
durations{nullptr}, source_boundary{all_sources + data.source_boundary_offset}, durations{nullptr}, distances{nullptr},
source_boundary{all_sources + data.source_boundary_offset},
destination_boundary{all_destinations + data.destination_boundary_offset} destination_boundary{all_destinations + data.destination_boundary_offset}
{ {
BOOST_ASSERT(num_source_nodes == 0 || all_sources != nullptr); BOOST_ASSERT(num_source_nodes == 0 || all_sources != nullptr);
@ -212,8 +227,8 @@ template <storage::Ownership Ownership> class CellStorageImpl
std::size_t LevelIDToIndex(LevelID level) const { return level - 1; } std::size_t LevelIDToIndex(LevelID level) const { return level - 1; }
public: public:
using Cell = CellImpl<EdgeWeight, EdgeDuration>; using Cell = CellImpl<EdgeWeight, EdgeDuration, EdgeDistance>;
using ConstCell = CellImpl<const EdgeWeight, const EdgeDuration>; using ConstCell = CellImpl<const EdgeWeight, const EdgeDuration, const EdgeDistance>;
CellStorageImpl() {} CellStorageImpl() {}
@ -388,6 +403,7 @@ template <storage::Ownership Ownership> class CellStorageImpl
return ConstCell{cells[cell_index], return ConstCell{cells[cell_index],
metric.weights.data(), metric.weights.data(),
metric.durations.data(), metric.durations.data(),
metric.distances.data(),
source_boundary.empty() ? nullptr : source_boundary.data(), source_boundary.empty() ? nullptr : source_boundary.data(),
destination_boundary.empty() ? nullptr : destination_boundary.data()}; destination_boundary.empty() ? nullptr : destination_boundary.data()};
} }
@ -415,6 +431,7 @@ template <storage::Ownership Ownership> class CellStorageImpl
return Cell{cells[cell_index], return Cell{cells[cell_index],
metric.weights.data(), metric.weights.data(),
metric.durations.data(), metric.durations.data(),
metric.distances.data(),
source_boundary.data(), source_boundary.data(),
destination_boundary.data()}; destination_boundary.data()};
} }

View File

@ -294,11 +294,14 @@ inline auto make_filtered_cell_metric_view(const SharedDataIndex &index,
auto prefix = name + "/exclude/" + std::to_string(exclude_index); auto prefix = name + "/exclude/" + std::to_string(exclude_index);
auto weights_block_id = prefix + "/weights"; auto weights_block_id = prefix + "/weights";
auto durations_block_id = prefix + "/durations"; auto durations_block_id = prefix + "/durations";
auto distances_block_id = prefix + "/distances";
auto weights = make_vector_view<EdgeWeight>(index, weights_block_id); auto weights = make_vector_view<EdgeWeight>(index, weights_block_id);
auto durations = make_vector_view<EdgeDuration>(index, durations_block_id); auto durations = make_vector_view<EdgeDuration>(index, durations_block_id);
auto distances = make_vector_view<EdgeDistance>(index, distances_block_id);
return customizer::CellMetricView{std::move(weights), std::move(durations)}; return customizer::CellMetricView{
std::move(weights), std::move(durations), std::move(distances)};
} }
inline auto make_cell_metric_view(const SharedDataIndex &index, const std::string &name) inline auto make_cell_metric_view(const SharedDataIndex &index, const std::string &name)
@ -311,12 +314,14 @@ inline auto make_cell_metric_view(const SharedDataIndex &index, const std::strin
{ {
auto weights_block_id = prefix + "/weights"; auto weights_block_id = prefix + "/weights";
auto durations_block_id = prefix + "/durations"; auto durations_block_id = prefix + "/durations";
auto distances_block_id = prefix + "/distances";
auto weights = make_vector_view<EdgeWeight>(index, weights_block_id); auto weights = make_vector_view<EdgeWeight>(index, weights_block_id);
auto durations = make_vector_view<EdgeDuration>(index, durations_block_id); auto durations = make_vector_view<EdgeDuration>(index, durations_block_id);
auto distances = make_vector_view<EdgeDistance>(index, distances_block_id);
cell_metric_excludes.push_back( cell_metric_excludes.push_back(customizer::CellMetricView{
customizer::CellMetricView{std::move(weights), std::move(durations)}); std::move(weights), std::move(durations), std::move(distances)});
} }
return cell_metric_excludes; return cell_metric_excludes;
@ -332,6 +337,7 @@ inline auto make_multi_level_graph_view(const SharedDataIndex &index, const std:
index, name + "/node_to_edge_offset"); index, name + "/node_to_edge_offset");
auto node_weights = make_vector_view<EdgeWeight>(index, name + "/node_weights"); auto node_weights = make_vector_view<EdgeWeight>(index, name + "/node_weights");
auto node_durations = make_vector_view<EdgeDuration>(index, name + "/node_durations"); auto node_durations = make_vector_view<EdgeDuration>(index, name + "/node_durations");
auto node_distances = make_vector_view<EdgeDistance>(index, name + "/node_distances");
auto is_forward_edge = make_vector_view<bool>(index, name + "/is_forward_edge"); auto is_forward_edge = make_vector_view<bool>(index, name + "/is_forward_edge");
auto is_backward_edge = make_vector_view<bool>(index, name + "/is_backward_edge"); auto is_backward_edge = make_vector_view<bool>(index, name + "/is_backward_edge");
@ -340,6 +346,7 @@ inline auto make_multi_level_graph_view(const SharedDataIndex &index, const std:
std::move(node_to_offset), std::move(node_to_offset),
std::move(node_weights), std::move(node_weights),
std::move(node_durations), std::move(node_durations),
std::move(node_distances),
std::move(is_forward_edge), std::move(is_forward_edge),
std::move(is_backward_edge)); std::move(is_backward_edge));
} }

View File

@ -41,7 +41,7 @@ void relaxOutgoingEdges(const DataFacade<mld::Algorithm> &facade,
const NodeID node, const NodeID node,
const EdgeWeight weight, const EdgeWeight weight,
const EdgeDuration duration, const EdgeDuration duration,
const EdgeDistance /* distance TODO use this */, const EdgeDistance distance,
typename SearchEngineData<mld::Algorithm>::ManyToManyQueryHeap &query_heap, typename SearchEngineData<mld::Algorithm>::ManyToManyQueryHeap &query_heap,
Args... args) Args... args)
{ {
@ -66,65 +66,77 @@ void relaxOutgoingEdges(const DataFacade<mld::Algorithm> &facade,
{ // Shortcuts in forward direction { // Shortcuts in forward direction
auto destination = cell.GetDestinationNodes().begin(); auto destination = cell.GetDestinationNodes().begin();
auto shortcut_durations = cell.GetOutDuration(node); auto shortcut_durations = cell.GetOutDuration(node);
auto shortcut_distances = cell.GetOutDistance(node);
for (auto shortcut_weight : cell.GetOutWeight(node)) for (auto shortcut_weight : cell.GetOutWeight(node))
{ {
BOOST_ASSERT(destination != cell.GetDestinationNodes().end()); BOOST_ASSERT(destination != cell.GetDestinationNodes().end());
BOOST_ASSERT(!shortcut_durations.empty()); BOOST_ASSERT(!shortcut_durations.empty());
BOOST_ASSERT(!shortcut_distances.empty());
const NodeID to = *destination; const NodeID to = *destination;
if (shortcut_weight != INVALID_EDGE_WEIGHT && node != to) if (shortcut_weight != INVALID_EDGE_WEIGHT && node != to)
{ {
const auto to_weight = weight + shortcut_weight; const auto to_weight = weight + shortcut_weight;
const auto to_duration = duration + shortcut_durations.front(); const auto to_duration = duration + shortcut_durations.front();
const auto to_distance = distance + shortcut_distances.front();
if (!query_heap.WasInserted(to)) if (!query_heap.WasInserted(to))
{ {
query_heap.Insert(to, to_weight, {node, true, to_duration, 0}); query_heap.Insert(to, to_weight, {node, true, to_duration, to_distance});
} }
else if (std::tie(to_weight, to_duration, node) < else if (std::tie(to_weight, to_duration, to_distance, node) <
std::tie(query_heap.GetKey(to), std::tie(query_heap.GetKey(to),
query_heap.GetData(to).duration, query_heap.GetData(to).duration,
query_heap.GetData(to).distance,
query_heap.GetData(to).parent)) query_heap.GetData(to).parent))
{ {
query_heap.GetData(to) = {node, true, to_duration, 0}; query_heap.GetData(to) = {node, true, to_duration, to_distance};
query_heap.DecreaseKey(to, to_weight); query_heap.DecreaseKey(to, to_weight);
} }
} }
++destination; ++destination;
shortcut_durations.advance_begin(1); shortcut_durations.advance_begin(1);
shortcut_distances.advance_begin(1);
} }
BOOST_ASSERT(shortcut_durations.empty()); BOOST_ASSERT(shortcut_durations.empty());
BOOST_ASSERT(shortcut_distances.empty());
} }
else else
{ // Shortcuts in backward direction { // Shortcuts in backward direction
auto source = cell.GetSourceNodes().begin(); auto source = cell.GetSourceNodes().begin();
auto shortcut_durations = cell.GetInDuration(node); auto shortcut_durations = cell.GetInDuration(node);
auto shortcut_distances = cell.GetInDistance(node);
for (auto shortcut_weight : cell.GetInWeight(node)) for (auto shortcut_weight : cell.GetInWeight(node))
{ {
BOOST_ASSERT(source != cell.GetSourceNodes().end()); BOOST_ASSERT(source != cell.GetSourceNodes().end());
BOOST_ASSERT(!shortcut_durations.empty()); BOOST_ASSERT(!shortcut_durations.empty());
BOOST_ASSERT(!shortcut_distances.empty());
const NodeID to = *source; const NodeID to = *source;
if (shortcut_weight != INVALID_EDGE_WEIGHT && node != to) if (shortcut_weight != INVALID_EDGE_WEIGHT && node != to)
{ {
const auto to_weight = weight + shortcut_weight; const auto to_weight = weight + shortcut_weight;
const auto to_duration = duration + shortcut_durations.front(); const auto to_duration = duration + shortcut_durations.front();
const auto to_distance = distance + shortcut_distances.front();
if (!query_heap.WasInserted(to)) if (!query_heap.WasInserted(to))
{ {
query_heap.Insert(to, to_weight, {node, true, to_duration, 0}); query_heap.Insert(to, to_weight, {node, true, to_duration, to_distance});
} }
else if (std::tie(to_weight, to_duration, node) < else if (std::tie(to_weight, to_duration, node) <
std::tie(query_heap.GetKey(to), std::tie(query_heap.GetKey(to),
query_heap.GetData(to).duration, query_heap.GetData(to).duration,
query_heap.GetData(to).distance,
query_heap.GetData(to).parent)) query_heap.GetData(to).parent))
{ {
query_heap.GetData(to) = {node, true, to_duration, 0}; query_heap.GetData(to) = {node, true, to_duration, to_distance};
query_heap.DecreaseKey(to, to_weight); query_heap.DecreaseKey(to, to_weight);
} }
} }
++source; ++source;
shortcut_durations.advance_begin(1); shortcut_durations.advance_begin(1);
shortcut_distances.advance_begin(1);
} }
BOOST_ASSERT(shortcut_durations.empty()); BOOST_ASSERT(shortcut_durations.empty());
BOOST_ASSERT(shortcut_distances.empty());
} }
} }
@ -144,6 +156,7 @@ void relaxOutgoingEdges(const DataFacade<mld::Algorithm> &facade,
const auto node_id = DIRECTION == FORWARD_DIRECTION ? node : facade.GetTarget(edge); const auto node_id = DIRECTION == FORWARD_DIRECTION ? node : facade.GetTarget(edge);
const auto node_weight = facade.GetNodeWeight(node_id); const auto node_weight = facade.GetNodeWeight(node_id);
const auto node_duration = facade.GetNodeDuration(node_id); const auto node_duration = facade.GetNodeDuration(node_id);
const auto node_distance = facade.GetNodeDistance(node_id);
const auto turn_weight = node_weight + facade.GetWeightPenaltyForEdgeID(turn_id); const auto turn_weight = node_weight + facade.GetWeightPenaltyForEdgeID(turn_id);
const auto turn_duration = node_duration + facade.GetDurationPenaltyForEdgeID(turn_id); const auto turn_duration = node_duration + facade.GetDurationPenaltyForEdgeID(turn_id);
@ -154,15 +167,16 @@ void relaxOutgoingEdges(const DataFacade<mld::Algorithm> &facade,
// New Node discovered -> Add to Heap + Node Info Storage // New Node discovered -> Add to Heap + Node Info Storage
if (!query_heap.WasInserted(to)) if (!query_heap.WasInserted(to))
{ {
query_heap.Insert(to, to_weight, {node, false, to_duration, 0}); query_heap.Insert(to, to_weight, {node, false, to_duration, int(node_distance)});
} }
// Found a shorter Path -> Update weight and set new parent // Found a shorter Path -> Update weight and set new parent
else if (std::tie(to_weight, to_duration, node) < else if (std::tie(to_weight, to_duration, node_distance, node) <
std::tie(query_heap.GetKey(to), std::tie(query_heap.GetKey(to),
query_heap.GetData(to).duration, query_heap.GetData(to).duration,
query_heap.GetData(to).distance,
query_heap.GetData(to).parent)) query_heap.GetData(to).parent))
{ {
query_heap.GetData(to) = {node, false, to_duration, 0}; query_heap.GetData(to) = {node, false, to_duration, node_distance};
query_heap.DecreaseKey(to, to_weight); query_heap.DecreaseKey(to, to_weight);
} }
} }
@ -511,6 +525,7 @@ void forwardRoutingStep(const DataFacade<Algorithm> &facade,
const std::vector<NodeBucket> &search_space_with_buckets, const std::vector<NodeBucket> &search_space_with_buckets,
std::vector<EdgeWeight> &weights_table, std::vector<EdgeWeight> &weights_table,
std::vector<EdgeDuration> &durations_table, std::vector<EdgeDuration> &durations_table,
std::vector<EdgeDistance> &distances_table,
std::vector<NodeID> &middle_nodes_table, std::vector<NodeID> &middle_nodes_table,
const PhantomNode &phantom_node) const PhantomNode &phantom_node)
{ {
@ -530,6 +545,7 @@ void forwardRoutingStep(const DataFacade<Algorithm> &facade,
const auto column_idx = current_bucket.column_index; const auto column_idx = current_bucket.column_index;
const auto target_weight = current_bucket.weight; const auto target_weight = current_bucket.weight;
const auto target_duration = current_bucket.duration; const auto target_duration = current_bucket.duration;
const auto target_distance = current_bucket.distance;
// Get the value location in the results tables: // Get the value location in the results tables:
// * row-major direct (row_idx, column_idx) index for forward direction // * row-major direct (row_idx, column_idx) index for forward direction
@ -539,16 +555,20 @@ void forwardRoutingStep(const DataFacade<Algorithm> &facade,
: row_idx + column_idx * number_of_sources; : row_idx + column_idx * number_of_sources;
auto &current_weight = weights_table[location]; auto &current_weight = weights_table[location];
auto &current_duration = durations_table[location]; auto &current_duration = durations_table[location];
auto &current_distance = distances_table[location];
// Check if new weight is better // Check if new weight is better
auto new_weight = source_weight + target_weight; auto new_weight = source_weight + target_weight;
auto new_duration = source_duration + target_duration; auto new_duration = source_duration + target_duration;
auto new_distance = source_distance + target_distance;
if (new_weight >= 0 && if (new_weight >= 0 &&
std::tie(new_weight, new_duration) < std::tie(current_weight, current_duration)) std::tie(new_weight, new_duration, new_distance) <
std::tie(current_weight, current_duration, current_distance))
{ {
current_weight = new_weight; current_weight = new_weight;
current_duration = new_duration; current_duration = new_duration;
current_distance = new_distance;
middle_nodes_table[location] = node; middle_nodes_table[location] = node;
} }
} }
@ -573,7 +593,7 @@ void backwardRoutingStep(const DataFacade<Algorithm> &facade,
// Store settled nodes in search space bucket // Store settled nodes in search space bucket
search_space_with_buckets.emplace_back( search_space_with_buckets.emplace_back(
node, parent, from_clique_arc, column_idx, target_weight, target_duration); node, parent, from_clique_arc, column_idx, target_weight, target_duration, target_distance);
const auto &partition = facade.GetMultiLevelPartition(); const auto &partition = facade.GetMultiLevelPartition();
const auto maximal_level = partition.GetNumberOfLevels() - 1; const auto maximal_level = partition.GetNumberOfLevels() - 1;
@ -815,7 +835,7 @@ manyToManySearch(SearchEngineData<Algorithm> &engine_working_data,
std::vector<EdgeWeight> weights_table(number_of_entries, INVALID_EDGE_WEIGHT); std::vector<EdgeWeight> weights_table(number_of_entries, INVALID_EDGE_WEIGHT);
std::vector<EdgeDuration> durations_table(number_of_entries, MAXIMAL_EDGE_DURATION); std::vector<EdgeDuration> durations_table(number_of_entries, MAXIMAL_EDGE_DURATION);
std::vector<EdgeDistance> distances_table; std::vector<EdgeDistance> distances_table(number_of_entries, INVALID_EDGE_DISTANCE);
std::vector<NodeID> middle_nodes_table(number_of_entries, SPECIAL_NODEID); std::vector<NodeID> middle_nodes_table(number_of_entries, SPECIAL_NODEID);
std::vector<NodeBucket> search_space_with_buckets; std::vector<NodeBucket> search_space_with_buckets;
@ -874,6 +894,7 @@ manyToManySearch(SearchEngineData<Algorithm> &engine_working_data,
search_space_with_buckets, search_space_with_buckets,
weights_table, weights_table,
durations_table, durations_table,
distances_table,
middle_nodes_table, middle_nodes_table,
source_phantom); source_phantom);
} }