Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Use node weights instead of edge weights in MLD algorithm #5049

Merged
merged 9 commits into from
Apr 28, 2018
3 changes: 2 additions & 1 deletion include/customizer/customizer_config.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,8 @@ struct CustomizationConfig final : storage::IOConfig
".osrm.partition",
".osrm.cells",
".osrm.ebg_nodes",
".osrm.properties"},
".osrm.properties",
".osrm.enw"},
{},
{".osrm.cell_metrics", ".osrm.mldgr"}),
requested_num_threads(0)
Expand Down
111 changes: 96 additions & 15 deletions include/customizer/edge_based_graph.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -16,28 +16,109 @@ namespace osrm
namespace customizer
{

using EdgeBasedGraphEdgeData = partitioner::EdgeBasedGraphEdgeData;

struct MultiLevelEdgeBasedGraph
: public partitioner::MultiLevelGraph<EdgeBasedGraphEdgeData, storage::Ownership::Container>
struct EdgeBasedGraphEdgeData
{
using Base =
partitioner::MultiLevelGraph<EdgeBasedGraphEdgeData, storage::Ownership::Container>;
using Base::Base;
NodeID turn_id; // ID of the edge based node (node based edge)
};

struct MultiLevelEdgeBasedGraphView
: public partitioner::MultiLevelGraph<EdgeBasedGraphEdgeData, storage::Ownership::View>
template <typename EdgeDataT, storage::Ownership Ownership> class MultiLevelGraph;

namespace serialization
{
using Base = partitioner::MultiLevelGraph<EdgeBasedGraphEdgeData, storage::Ownership::View>;
using Base::Base;
};
template <typename EdgeDataT, storage::Ownership Ownership>
void read(storage::tar::FileReader &reader,
const std::string &name,
MultiLevelGraph<EdgeDataT, Ownership> &graph);

template <typename EdgeDataT, storage::Ownership Ownership>
void write(storage::tar::FileWriter &writer,
const std::string &name,
const MultiLevelGraph<EdgeDataT, Ownership> &graph);
}

struct StaticEdgeBasedGraphEdge : MultiLevelEdgeBasedGraph::InputEdge
template <typename EdgeDataT, storage::Ownership Ownership>
class MultiLevelGraph : public partitioner::MultiLevelGraph<EdgeDataT, Ownership>
{
using Base = MultiLevelEdgeBasedGraph::InputEdge;
using Base::Base;
private:
using SuperT = partitioner::MultiLevelGraph<EdgeDataT, Ownership>;
using PartitionerGraphT = partitioner::MultiLevelGraph<partitioner::EdgeBasedGraphEdgeData,
storage::Ownership::Container>;
template <typename T> using Vector = util::ViewOrVector<T, Ownership>;

public:
using NodeArrayEntry = typename SuperT::NodeArrayEntry;
using EdgeArrayEntry = typename SuperT::EdgeArrayEntry;
using EdgeOffset = typename SuperT::EdgeOffset;

MultiLevelGraph() = default;
MultiLevelGraph(MultiLevelGraph &&) = default;
MultiLevelGraph(const MultiLevelGraph &) = default;
MultiLevelGraph &operator=(MultiLevelGraph &&) = default;
MultiLevelGraph &operator=(const MultiLevelGraph &) = default;

MultiLevelGraph(PartitionerGraphT &&graph,
Vector<EdgeWeight> node_weights_,
Vector<EdgeDuration> node_durations_)
: node_weights(std::move(node_weights_)), node_durations(std::move(node_durations_))
{
util::ViewOrVector<PartitionerGraphT::EdgeArrayEntry, storage::Ownership::Container>
original_edge_array;

std::tie(SuperT::node_array,
original_edge_array,
SuperT::node_to_edge_offset,
SuperT::connectivity_checksum) = std::move(graph).data();

SuperT::edge_array.reserve(original_edge_array.size());
for (const auto &edge : original_edge_array)
{
SuperT::edge_array.push_back({edge.target, {edge.data.turn_id}});
is_forward_edge.push_back(edge.data.forward);
is_backward_edge.push_back(edge.data.backward);
}
}

MultiLevelGraph(Vector<NodeArrayEntry> node_array_,
Vector<EdgeArrayEntry> edge_array_,
Vector<EdgeOffset> node_to_edge_offset_,
Vector<EdgeWeight> node_weights_,
Vector<EdgeDuration> node_durations_,
Vector<bool> is_forward_edge_,
Vector<bool> is_backward_edge_)
: 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_)),
is_forward_edge(is_forward_edge_), is_backward_edge(is_backward_edge_)
{
}

EdgeWeight GetNodeWeight(NodeID node) const { return node_weights[node]; }

EdgeWeight GetNodeDuration(NodeID node) const { return node_durations[node]; }

bool IsForwardEdge(EdgeID edge) const { return is_forward_edge[edge]; }

bool IsBackwardEdge(EdgeID edge) const { return is_backward_edge[edge]; }

friend void
serialization::read<EdgeDataT, Ownership>(storage::tar::FileReader &reader,
const std::string &name,
MultiLevelGraph<EdgeDataT, Ownership> &graph);
friend void
serialization::write<EdgeDataT, Ownership>(storage::tar::FileWriter &writer,
const std::string &name,
const MultiLevelGraph<EdgeDataT, Ownership> &graph);

protected:
Vector<EdgeWeight> node_weights;
Vector<EdgeDuration> node_durations;
Vector<bool> is_forward_edge;
Vector<bool> is_backward_edge;
};

using MultiLevelEdgeBasedGraph =
MultiLevelGraph<EdgeBasedGraphEdgeData, storage::Ownership::Container>;
using MultiLevelEdgeBasedGraphView =
MultiLevelGraph<EdgeBasedGraphEdgeData, storage::Ownership::View>;
}
}

Expand Down
33 changes: 33 additions & 0 deletions include/customizer/files.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -73,6 +73,39 @@ writeCellMetrics(const boost::filesystem::path &path,
}
}
}

// reads .osrm.mldgr file
template <typename MultiLevelGraphT>
inline void readGraph(const boost::filesystem::path &path,
MultiLevelGraphT &graph,
std::uint32_t &connectivity_checksum)
{
static_assert(std::is_same<customizer::MultiLevelEdgeBasedGraphView, MultiLevelGraphT>::value ||
std::is_same<customizer::MultiLevelEdgeBasedGraph, MultiLevelGraphT>::value,
"");

storage::tar::FileReader reader{path, storage::tar::FileReader::VerifyFingerprint};

reader.ReadInto("/mld/connectivity_checksum", connectivity_checksum);
serialization::read(reader, "/mld/multilevelgraph", graph);
}

// writes .osrm.mldgr file
template <typename MultiLevelGraphT>
inline void writeGraph(const boost::filesystem::path &path,
const MultiLevelGraphT &graph,
const std::uint32_t connectivity_checksum)
{
static_assert(std::is_same<customizer::MultiLevelEdgeBasedGraphView, MultiLevelGraphT>::value ||
std::is_same<customizer::MultiLevelEdgeBasedGraph, MultiLevelGraphT>::value,
"");

storage::tar::FileWriter writer{path, storage::tar::FileWriter::GenerateFingerprint};

writer.WriteElementCount64("/mld/connectivity_checksum", 1);
writer.WriteFrom("/mld/connectivity_checksum", connectivity_checksum);
serialization::write(writer, "/mld/multilevelgraph", graph);
}
}
}
}
Expand Down
30 changes: 30 additions & 0 deletions include/customizer/serialization.hpp
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
#ifndef OSRM_CUSTOMIZER_SERIALIZATION_HPP
#define OSRM_CUSTOMIZER_SERIALIZATION_HPP

#include "customizer/edge_based_graph.hpp"

#include "partitioner/cell_storage.hpp"

#include "storage/serialization.hpp"
Expand Down Expand Up @@ -31,6 +33,34 @@ inline void write(storage::tar::FileWriter &writer,
storage::serialization::write(writer, name + "/weights", metric.weights);
storage::serialization::write(writer, name + "/durations", metric.durations);
}

template <typename EdgeDataT, storage::Ownership Ownership>
inline void read(storage::tar::FileReader &reader,
const std::string &name,
MultiLevelGraph<EdgeDataT, Ownership> &graph)
{
storage::serialization::read(reader, name + "/node_array", graph.node_array);
storage::serialization::read(reader, name + "/node_weights", graph.node_weights);
storage::serialization::read(reader, name + "/node_durations", graph.node_durations);
storage::serialization::read(reader, name + "/edge_array", graph.edge_array);
storage::serialization::read(reader, name + "/is_forward_edge", graph.is_forward_edge);
storage::serialization::read(reader, name + "/is_backward_edge", graph.is_backward_edge);
storage::serialization::read(reader, name + "/node_to_edge_offset", graph.node_to_edge_offset);
}

template <typename EdgeDataT, storage::Ownership Ownership>
inline void write(storage::tar::FileWriter &writer,
const std::string &name,
const MultiLevelGraph<EdgeDataT, Ownership> &graph)
{
storage::serialization::write(writer, name + "/node_array", graph.node_array);
storage::serialization::write(writer, name + "/node_weights", graph.node_weights);
storage::serialization::write(writer, name + "/node_durations", graph.node_durations);
storage::serialization::write(writer, name + "/edge_array", graph.edge_array);
storage::serialization::write(writer, name + "/is_forward_edge", graph.is_forward_edge);
storage::serialization::write(writer, name + "/is_backward_edge", graph.is_backward_edge);
storage::serialization::write(writer, name + "/node_to_edge_offset", graph.node_to_edge_offset);
}
}
}
}
Expand Down
15 changes: 12 additions & 3 deletions include/engine/datafacade/algorithm_datafacade.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
#define OSRM_ENGINE_DATAFACADE_ALGORITHM_DATAFACADE_HPP

#include "contractor/query_edge.hpp"
#include "customizer/edge_based_graph.hpp"
#include "extractor/edge_based_edge.hpp"
#include "engine/algorithm.hpp"

Expand Down Expand Up @@ -59,7 +60,7 @@ template <> class AlgorithmDataFacade<CH>
template <> class AlgorithmDataFacade<MLD>
{
public:
using EdgeData = extractor::EdgeBasedEdge::EdgeData;
using EdgeData = customizer::EdgeBasedGraphEdgeData;
using EdgeRange = util::range<EdgeID>;

// search graph access
Expand All @@ -71,12 +72,20 @@ template <> class AlgorithmDataFacade<MLD>

virtual unsigned GetOutDegree(const NodeID n) const = 0;

virtual EdgeRange GetAdjacentEdgeRange(const NodeID node) const = 0;

virtual EdgeWeight GetNodeWeight(const NodeID node) const = 0;

virtual EdgeWeight GetNodeDuration(const NodeID node) const = 0; // TODO: to be removed

virtual bool IsForwardEdge(EdgeID edge) const = 0;

virtual bool IsBackwardEdge(EdgeID edge) const = 0;

virtual NodeID GetTarget(const EdgeID e) const = 0;

virtual const EdgeData &GetEdgeData(const EdgeID e) const = 0;

virtual EdgeRange GetAdjacentEdgeRange(const NodeID node) const = 0;

virtual const partitioner::MultiLevelPartitionView &GetMultiLevelPartition() const = 0;

virtual const partitioner::CellStorageView &GetCellStorage() const = 0;
Expand Down
34 changes: 27 additions & 7 deletions include/engine/datafacade/contiguous_internalmem_datafacade.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -282,13 +282,13 @@ class ContiguousInternalMemoryDataFacadeBase : public BaseDataFacade
return segment_data.GetReverseDatasources(id);
}

TurnPenalty GetWeightPenaltyForEdgeID(const unsigned id) const override final
TurnPenalty GetWeightPenaltyForEdgeID(const EdgeID id) const override final
{
BOOST_ASSERT(m_turn_weight_penalties.size() > id);
return m_turn_weight_penalties[id];
}

TurnPenalty GetDurationPenaltyForEdgeID(const unsigned id) const override final
TurnPenalty GetDurationPenaltyForEdgeID(const EdgeID id) const override final
{
BOOST_ASSERT(m_turn_duration_penalties.size() > id);
return m_turn_duration_penalties[id];
Expand Down Expand Up @@ -682,16 +682,36 @@ template <> class ContiguousInternalMemoryAlgorithmDataFacade<MLD> : public Algo
return query_graph.GetOutDegree(n);
}

NodeID GetTarget(const EdgeID e) const override final { return query_graph.GetTarget(e); }
EdgeRange GetAdjacentEdgeRange(const NodeID node) const override final
{
return query_graph.GetAdjacentEdgeRange(node);
}

const EdgeData &GetEdgeData(const EdgeID e) const override final
EdgeWeight GetNodeWeight(const NodeID node) const override final
{
return query_graph.GetEdgeData(e);
return query_graph.GetNodeWeight(node);
}

EdgeRange GetAdjacentEdgeRange(const NodeID node) const override final
EdgeDuration GetNodeDuration(const NodeID node) const override final
{
return query_graph.GetAdjacentEdgeRange(node);
return query_graph.GetNodeDuration(node);
}

bool IsForwardEdge(const NodeID node) const override final
{
return query_graph.IsForwardEdge(node);
}

bool IsBackwardEdge(const NodeID node) const override final
{
return query_graph.IsBackwardEdge(node);
}

NodeID GetTarget(const EdgeID e) const override final { return query_graph.GetTarget(e); }

const EdgeData &GetEdgeData(const EdgeID e) const override final
{
return query_graph.GetEdgeData(e);
}

EdgeRange GetBorderEdgeRange(const LevelID level, const NodeID node) const override final
Expand Down
4 changes: 2 additions & 2 deletions include/engine/datafacade/datafacade_base.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -86,9 +86,9 @@ class BaseDataFacade
virtual NodeForwardRange GetUncompressedForwardGeometry(const EdgeID id) const = 0;
virtual NodeReverseRange GetUncompressedReverseGeometry(const EdgeID id) const = 0;

virtual TurnPenalty GetWeightPenaltyForEdgeID(const unsigned id) const = 0;
virtual TurnPenalty GetWeightPenaltyForEdgeID(const EdgeID id) const = 0;

virtual TurnPenalty GetDurationPenaltyForEdgeID(const unsigned id) const = 0;
virtual TurnPenalty GetDurationPenaltyForEdgeID(const EdgeID id) const = 0;

// Gets the weight values for each segment in an uncompressed geometry.
// Should always be 1 shorter than GetUncompressedGeometry
Expand Down
13 changes: 10 additions & 3 deletions include/engine/routing_algorithms/routing_base_mld.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -206,15 +206,22 @@ void relaxOutgoingEdges(const DataFacade<Algorithm> &facade,
for (const auto edge : facade.GetBorderEdgeRange(level, node))
{
const auto &edge_data = facade.GetEdgeData(edge);
if (DIRECTION == FORWARD_DIRECTION ? edge_data.forward : edge_data.backward)

if ((DIRECTION == FORWARD_DIRECTION) ? facade.IsForwardEdge(edge)
: facade.IsBackwardEdge(edge))
{
const NodeID to = facade.GetTarget(edge);

if (!facade.ExcludeNode(to) &&
checkParentCellRestriction(partition.GetCell(level + 1, to), args...))
{
BOOST_ASSERT_MSG(edge_data.weight > 0, "edge_weight invalid");
const EdgeWeight to_weight = weight + edge_data.weight;
const auto node_weight =
facade.GetNodeWeight(DIRECTION == FORWARD_DIRECTION ? node : to);
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Good catch, didn't think about the reverse-case here. 👍

const auto turn_penalty = facade.GetWeightPenaltyForEdgeID(edge_data.turn_id);

// TODO: BOOST_ASSERT(edge_data.weight == node_weight + turn_penalty);

const EdgeWeight to_weight = weight + node_weight + turn_penalty;

if (!forward_heap.WasInserted(to))
{
Expand Down
2 changes: 2 additions & 0 deletions include/extractor/edge_based_graph_factory.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -91,6 +91,7 @@ class EdgeBasedGraphFactory
void GetEdgeBasedNodeSegments(std::vector<EdgeBasedNodeSegment> &nodes);
void GetStartPointMarkers(std::vector<bool> &node_is_startpoint);
void GetEdgeBasedNodeWeights(std::vector<EdgeWeight> &output_node_weights);
void GetEdgeBasedNodeDurations(std::vector<EdgeWeight> &output_node_durations);
std::uint32_t GetConnectivityChecksum() const;

std::uint64_t GetNumberOfEdgeBasedNodes() const;
Expand All @@ -117,6 +118,7 @@ class EdgeBasedGraphFactory
//! node weights that indicate the length of the segment (node based) represented by the
//! edge-based node
std::vector<EdgeWeight> m_edge_based_node_weights;
std::vector<EdgeDuration> m_edge_based_node_durations;

//! list of edge based nodes (compressed segments)
std::vector<EdgeBasedNodeSegment> m_edge_based_node_segments;
Expand Down
1 change: 1 addition & 0 deletions include/extractor/extractor.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -87,6 +87,7 @@ class Extractor
std::vector<EdgeBasedNodeSegment> &edge_based_node_segments,
std::vector<bool> &node_is_startpoint,
std::vector<EdgeWeight> &edge_based_node_weights,
std::vector<EdgeDuration> &edge_based_node_durations,
util::DeallocatingVector<EdgeBasedEdge> &edge_based_edge_list,
std::uint32_t &connectivity_checksum);

Expand Down
Loading