Loads the edge based graph edges and constructs a dynamic graph from it
This commit is contained in:
parent
e0665856b0
commit
3e409bea26
203
include/partition/edge_based_graph_reader.hpp
Normal file
203
include/partition/edge_based_graph_reader.hpp
Normal file
@ -0,0 +1,203 @@
|
|||||||
|
#ifndef OSRM_EDGE_BASED_GRAPH_READER_HPP
|
||||||
|
#define OSRM_EDGE_BASED_GRAPH_READER_HPP
|
||||||
|
|
||||||
|
#include "storage/io.hpp"
|
||||||
|
#include "util/coordinate.hpp"
|
||||||
|
#include "util/dynamic_graph.hpp"
|
||||||
|
#include "util/typedefs.hpp"
|
||||||
|
|
||||||
|
#include <cstdint>
|
||||||
|
|
||||||
|
#include <algorithm>
|
||||||
|
#include <iterator>
|
||||||
|
#include <memory>
|
||||||
|
#include <vector>
|
||||||
|
|
||||||
|
namespace osrm
|
||||||
|
{
|
||||||
|
namespace partition
|
||||||
|
{
|
||||||
|
|
||||||
|
struct EdgeBasedGraphEdgeData
|
||||||
|
{
|
||||||
|
NodeID edge_id : 31;
|
||||||
|
// Artificial edge used to fixup partitioning, see #3205.
|
||||||
|
// These artificial edges have invalid weight / duration.
|
||||||
|
std::uint32_t is_boundary_arc : 1;
|
||||||
|
EdgeWeight weight;
|
||||||
|
EdgeWeight duration : 30;
|
||||||
|
std::uint32_t forward : 1;
|
||||||
|
std::uint32_t backward : 1;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct EdgeBasedGraph : util::DynamicGraph<EdgeBasedGraphEdgeData>
|
||||||
|
{
|
||||||
|
using Base = util::DynamicGraph<EdgeBasedGraphEdgeData>;
|
||||||
|
using Base::Base;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct EdgeBasedGraphEdge : EdgeBasedGraph::InputEdge
|
||||||
|
{
|
||||||
|
using Base = EdgeBasedGraph::InputEdge;
|
||||||
|
using Base::Base;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct EdgeBasedGraphReader
|
||||||
|
{
|
||||||
|
EdgeBasedGraphReader(storage::io::FileReader &reader)
|
||||||
|
{
|
||||||
|
// Reads: | Fingerprint | #e | max_eid | edges |
|
||||||
|
// - uint64: number of edges
|
||||||
|
// - EdgeID: max edge id
|
||||||
|
// - extractor::EdgeBasedEdge edges
|
||||||
|
//
|
||||||
|
// Gets written in Extractor::WriteEdgeBasedGraph
|
||||||
|
|
||||||
|
const auto num_edges = reader.ReadElementCount64();
|
||||||
|
const auto max_edge_id = reader.ReadOne<EdgeID>();
|
||||||
|
|
||||||
|
num_nodes = max_edge_id + 1;
|
||||||
|
|
||||||
|
edges.resize(num_edges);
|
||||||
|
reader.ReadInto(edges);
|
||||||
|
}
|
||||||
|
|
||||||
|
// FIXME: wrapped in unique_ptr since dynamic_graph is not move-able
|
||||||
|
|
||||||
|
std::unique_ptr<EdgeBasedGraph> BuildEdgeBasedGraph()
|
||||||
|
{
|
||||||
|
// FIXME: The following is a rough adaption from:
|
||||||
|
// - adaptToContractorInput
|
||||||
|
// - GraphContractor::GraphContractor
|
||||||
|
// and should really be abstracted over.
|
||||||
|
|
||||||
|
auto directed = SplitBidirectionalEdges(edges);
|
||||||
|
auto tidied = PrepareEdgesForUsageInGraph(directed);
|
||||||
|
|
||||||
|
return std::make_unique<EdgeBasedGraph>(num_nodes, tidied);
|
||||||
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
// Bidirectional (s,t) to (s,t) and (t,s)
|
||||||
|
static std::vector<extractor::EdgeBasedEdge>
|
||||||
|
SplitBidirectionalEdges(std::vector<extractor::EdgeBasedEdge> edges)
|
||||||
|
{
|
||||||
|
std::vector<extractor::EdgeBasedEdge> directed;
|
||||||
|
directed.reserve(edges.size() * 2);
|
||||||
|
|
||||||
|
for (const auto &edge : edges)
|
||||||
|
{
|
||||||
|
directed.emplace_back(edge.source,
|
||||||
|
edge.target,
|
||||||
|
edge.edge_id,
|
||||||
|
std::max(edge.weight, 1),
|
||||||
|
edge.duration,
|
||||||
|
edge.forward,
|
||||||
|
edge.backward);
|
||||||
|
|
||||||
|
directed.emplace_back(edge.target,
|
||||||
|
edge.source,
|
||||||
|
edge.edge_id,
|
||||||
|
std::max(edge.weight, 1),
|
||||||
|
edge.duration,
|
||||||
|
edge.backward,
|
||||||
|
edge.forward);
|
||||||
|
}
|
||||||
|
|
||||||
|
std::swap(directed, edges);
|
||||||
|
|
||||||
|
return directed;
|
||||||
|
}
|
||||||
|
|
||||||
|
static std::vector<EdgeBasedGraphEdge>
|
||||||
|
PrepareEdgesForUsageInGraph(std::vector<extractor::EdgeBasedEdge> edges)
|
||||||
|
{
|
||||||
|
std::sort(begin(edges), end(edges));
|
||||||
|
|
||||||
|
std::vector<EdgeBasedGraphEdge> graph_edges;
|
||||||
|
graph_edges.reserve(edges.size());
|
||||||
|
|
||||||
|
for (NodeID i = 0; i < edges.size();)
|
||||||
|
{
|
||||||
|
const NodeID source = edges[i].source;
|
||||||
|
const NodeID target = edges[i].target;
|
||||||
|
|
||||||
|
// remove eigenloops
|
||||||
|
if (source == target)
|
||||||
|
{
|
||||||
|
++i;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
EdgeBasedGraphEdge forward_edge;
|
||||||
|
EdgeBasedGraphEdge reverse_edge;
|
||||||
|
forward_edge.source = reverse_edge.source = source;
|
||||||
|
forward_edge.target = reverse_edge.target = target;
|
||||||
|
forward_edge.data.edge_id = reverse_edge.data.edge_id = edges[i].edge_id;
|
||||||
|
forward_edge.data.is_boundary_arc = reverse_edge.data.is_boundary_arc = false;
|
||||||
|
forward_edge.data.weight = reverse_edge.data.weight = INVALID_EDGE_WEIGHT;
|
||||||
|
forward_edge.data.duration = reverse_edge.data.duration = MAXIMAL_EDGE_DURATION;
|
||||||
|
forward_edge.data.forward = reverse_edge.data.backward = true;
|
||||||
|
forward_edge.data.backward = reverse_edge.data.forward = false;
|
||||||
|
|
||||||
|
|
||||||
|
// remove parallel edges
|
||||||
|
while (i < edges.size() && edges[i].source == source && edges[i].target == target)
|
||||||
|
{
|
||||||
|
if (edges[i].forward)
|
||||||
|
{
|
||||||
|
forward_edge.data.weight = std::min(edges[i].weight, forward_edge.data.weight);
|
||||||
|
forward_edge.data.duration =
|
||||||
|
std::min(edges[i].duration, forward_edge.data.duration);
|
||||||
|
}
|
||||||
|
if (edges[i].backward)
|
||||||
|
{
|
||||||
|
reverse_edge.data.weight = std::min(edges[i].weight, reverse_edge.data.weight);
|
||||||
|
reverse_edge.data.duration =
|
||||||
|
std::min(edges[i].duration, reverse_edge.data.duration);
|
||||||
|
}
|
||||||
|
++i;
|
||||||
|
}
|
||||||
|
// merge edges (s,t) and (t,s) into bidirectional edge
|
||||||
|
if (forward_edge.data.weight == reverse_edge.data.weight)
|
||||||
|
{
|
||||||
|
if ((int)forward_edge.data.weight != INVALID_EDGE_WEIGHT)
|
||||||
|
{
|
||||||
|
forward_edge.data.backward = true;
|
||||||
|
graph_edges.push_back(forward_edge);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{ // insert seperate edges
|
||||||
|
if (((int)forward_edge.data.weight) != INVALID_EDGE_WEIGHT)
|
||||||
|
{
|
||||||
|
graph_edges.push_back(forward_edge);
|
||||||
|
}
|
||||||
|
if ((int)reverse_edge.data.weight != INVALID_EDGE_WEIGHT)
|
||||||
|
{
|
||||||
|
graph_edges.push_back(reverse_edge);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return graph_edges;
|
||||||
|
}
|
||||||
|
|
||||||
|
std::vector<extractor::EdgeBasedEdge> edges;
|
||||||
|
std::size_t num_nodes;
|
||||||
|
};
|
||||||
|
|
||||||
|
inline std::unique_ptr<EdgeBasedGraph> LoadEdgeBasedGraph(const std::string &path)
|
||||||
|
{
|
||||||
|
const auto fingerprint = storage::io::FileReader::VerifyFingerprint;
|
||||||
|
storage::io::FileReader reader(path, fingerprint);
|
||||||
|
|
||||||
|
EdgeBasedGraphReader builder{reader};
|
||||||
|
|
||||||
|
return builder.BuildEdgeBasedGraph();
|
||||||
|
}
|
||||||
|
|
||||||
|
} // ns partition
|
||||||
|
} // ns osrm
|
||||||
|
|
||||||
|
#endif
|
@ -105,8 +105,6 @@ template <typename EdgeDataT> class DynamicGraph
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
~DynamicGraph() {}
|
|
||||||
|
|
||||||
unsigned GetNumberOfNodes() const { return number_of_nodes; }
|
unsigned GetNumberOfNodes() const { return number_of_nodes; }
|
||||||
|
|
||||||
unsigned GetNumberOfEdges() const { return number_of_edges; }
|
unsigned GetNumberOfEdges() const { return number_of_edges; }
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
#ifndef STATIC_GRAPH_TRAITS_HPP
|
#ifndef OSRM_GRAPH_TRAITS_HPP
|
||||||
#define STATIC_GRAPH_TRAITS_HPP
|
#define OSRM_GRAPH_TRAITS_HPP
|
||||||
|
|
||||||
#include <type_traits>
|
#include <type_traits>
|
||||||
|
|
||||||
@ -31,14 +31,14 @@ struct HasTargetMember<T, decltype((void)(sizeof(std::declval<T>().target) > 0))
|
|||||||
{
|
{
|
||||||
};
|
};
|
||||||
|
|
||||||
// Static Graph requires edges to have a .target and .data member attribute
|
// Our graphs require edges to have a .target and .data member attribute
|
||||||
template <typename Edge>
|
template <typename Edge>
|
||||||
struct HasDataAndTargetMember
|
struct HasDataAndTargetMember
|
||||||
: std::integral_constant<bool, HasDataMember<Edge>::value && HasTargetMember<Edge>::value>
|
: std::integral_constant<bool, HasDataMember<Edge>::value && HasTargetMember<Edge>::value>
|
||||||
{
|
{
|
||||||
};
|
};
|
||||||
|
|
||||||
// Static Graph requires nodes to have a .first_edge member attribute
|
// Our graphs require nodes to have a .first_edge member attribute
|
||||||
template <typename T, typename = void> struct HasFirstEdgeMember : std::false_type
|
template <typename T, typename = void> struct HasFirstEdgeMember : std::false_type
|
||||||
{
|
{
|
||||||
};
|
};
|
@ -1,10 +1,10 @@
|
|||||||
#ifndef STATIC_GRAPH_HPP
|
#ifndef STATIC_GRAPH_HPP
|
||||||
#define STATIC_GRAPH_HPP
|
#define STATIC_GRAPH_HPP
|
||||||
|
|
||||||
|
#include "util/graph_traits.hpp"
|
||||||
#include "util/integer_range.hpp"
|
#include "util/integer_range.hpp"
|
||||||
#include "util/percent.hpp"
|
#include "util/percent.hpp"
|
||||||
#include "util/shared_memory_vector_wrapper.hpp"
|
#include "util/shared_memory_vector_wrapper.hpp"
|
||||||
#include "util/static_graph_traits.hpp"
|
|
||||||
#include "util/typedefs.hpp"
|
#include "util/typedefs.hpp"
|
||||||
|
|
||||||
#include <boost/assert.hpp>
|
#include <boost/assert.hpp>
|
||||||
|
@ -2,12 +2,14 @@
|
|||||||
#include "partition/annotated_partition.hpp"
|
#include "partition/annotated_partition.hpp"
|
||||||
#include "partition/bisection_graph.hpp"
|
#include "partition/bisection_graph.hpp"
|
||||||
#include "partition/compressed_node_based_graph_reader.hpp"
|
#include "partition/compressed_node_based_graph_reader.hpp"
|
||||||
|
#include "partition/edge_based_graph_reader.hpp"
|
||||||
#include "partition/node_based_graph_to_edge_based_graph_mapping_reader.hpp"
|
#include "partition/node_based_graph_to_edge_based_graph_mapping_reader.hpp"
|
||||||
#include "partition/recursive_bisection.hpp"
|
#include "partition/recursive_bisection.hpp"
|
||||||
|
|
||||||
#include "util/coordinate.hpp"
|
#include "util/coordinate.hpp"
|
||||||
#include "util/geojson_debug_logger.hpp"
|
#include "util/geojson_debug_logger.hpp"
|
||||||
#include "util/geojson_debug_policies.hpp"
|
#include "util/geojson_debug_policies.hpp"
|
||||||
|
#include "util/integer_range.hpp"
|
||||||
#include "util/json_container.hpp"
|
#include "util/json_container.hpp"
|
||||||
#include "util/log.hpp"
|
#include "util/log.hpp"
|
||||||
|
|
||||||
@ -136,9 +138,30 @@ int Partitioner::Run(const PartitionConfig &config)
|
|||||||
recursive_bisection.BisectionIDs());
|
recursive_bisection.BisectionIDs());
|
||||||
|
|
||||||
auto mapping = LoadNodeBasedGraphToEdgeBasedGraphMapping(config.nbg_ebg_mapping_path.string());
|
auto mapping = LoadNodeBasedGraphToEdgeBasedGraphMapping(config.nbg_ebg_mapping_path.string());
|
||||||
|
|
||||||
util::Log() << "Loaded node based graph to edge based graph mapping";
|
util::Log() << "Loaded node based graph to edge based graph mapping";
|
||||||
|
|
||||||
|
auto edge_based_graph = LoadEdgeBasedGraph(config.edge_based_graph_path.string());
|
||||||
|
util::Log() << "Loaded edge based graph for mapping partition ids: "
|
||||||
|
<< edge_based_graph->GetNumberOfEdges() << " edges, "
|
||||||
|
<< edge_based_graph->GetNumberOfNodes() << " nodes";
|
||||||
|
|
||||||
|
for (const auto node_id : util::irange(0u, edge_based_graph->GetNumberOfNodes()))
|
||||||
|
{
|
||||||
|
const auto node_based_nodes = mapping.Lookup(node_id);
|
||||||
|
|
||||||
|
const auto u = node_based_nodes.u;
|
||||||
|
const auto v = node_based_nodes.v;
|
||||||
|
|
||||||
|
auto partition_id = [](auto) {
|
||||||
|
return 0; /*dummy*/
|
||||||
|
};
|
||||||
|
|
||||||
|
if (partition_id(u) != partition_id(v))
|
||||||
|
{
|
||||||
|
// TODO: resolve border nodes u, v
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user