Refactor contractor to pass in graph directly

This commit is contained in:
Patrick Niklaus
2017-08-18 22:31:04 +00:00
committed by Patrick Niklaus
parent acb7916996
commit 26c909b64b
5 changed files with 123 additions and 129 deletions
+21 -22
View File
@@ -95,10 +95,9 @@ class GraphContractor
};
public:
GraphContractor(int nodes, std::vector<ContractorEdge> input_edge_list);
GraphContractor(ContractorGraph graph);
GraphContractor(int nodes,
std::vector<ContractorEdge> edges,
GraphContractor(ContractorGraph graph,
std::vector<float> node_levels_,
std::vector<EdgeWeight> node_weights_);
@@ -119,18 +118,18 @@ class GraphContractor
util::UnbufferedLog log;
log << "Getting edges of minimized graph ";
util::Percent p(log, contractor_graph->GetNumberOfNodes());
const NodeID number_of_nodes = contractor_graph->GetNumberOfNodes();
if (contractor_graph->GetNumberOfNodes())
util::Percent p(log, graph.GetNumberOfNodes());
const NodeID number_of_nodes = graph.GetNumberOfNodes();
if (graph.GetNumberOfNodes())
{
Edge new_edge;
for (const auto node : util::irange(0u, number_of_nodes))
{
p.PrintStatus(node);
for (auto edge : contractor_graph->GetAdjacentEdgeRange(node))
for (auto edge : graph.GetAdjacentEdgeRange(node))
{
const NodeID target = contractor_graph->GetTarget(edge);
const ContractorGraph::EdgeData &data = contractor_graph->GetEdgeData(edge);
const NodeID target = graph.GetTarget(edge);
const ContractorGraph::EdgeData &data = graph.GetEdgeData(edge);
if (!orig_node_id_from_new_node_id_map.empty())
{
new_edge.source = orig_node_id_from_new_node_id_map[node];
@@ -163,7 +162,7 @@ class GraphContractor
}
}
}
contractor_graph.reset();
graph = ContractorGraph{};
orig_node_id_from_new_node_id_map.clear();
orig_node_id_from_new_node_id_map.shrink_to_fit();
@@ -198,10 +197,10 @@ class GraphContractor
constexpr bool REVERSE_DIRECTION_ENABLED = true;
constexpr bool REVERSE_DIRECTION_DISABLED = false;
for (auto in_edge : contractor_graph->GetAdjacentEdgeRange(node))
for (auto in_edge : graph.GetAdjacentEdgeRange(node))
{
const ContractorEdgeData &in_data = contractor_graph->GetEdgeData(in_edge);
const NodeID source = contractor_graph->GetTarget(in_edge);
const ContractorEdgeData &in_data = graph.GetEdgeData(in_edge);
const NodeID source = graph.GetTarget(in_edge);
if (source == node)
continue;
@@ -221,14 +220,14 @@ class GraphContractor
EdgeWeight max_weight = 0;
unsigned number_of_targets = 0;
for (auto out_edge : contractor_graph->GetAdjacentEdgeRange(node))
for (auto out_edge : graph.GetAdjacentEdgeRange(node))
{
const ContractorEdgeData &out_data = contractor_graph->GetEdgeData(out_edge);
const ContractorEdgeData &out_data = graph.GetEdgeData(out_edge);
if (!out_data.forward)
{
continue;
}
const NodeID target = contractor_graph->GetTarget(out_edge);
const NodeID target = graph.GetTarget(out_edge);
if (node == target)
{
continue;
@@ -298,22 +297,22 @@ class GraphContractor
SIMULATION_SEARCH_SPACE_SIZE,
max_weight,
node,
*contractor_graph);
graph);
}
else
{
const int constexpr FULL_SEARCH_SPACE_SIZE = 2000;
dijkstra.Run(
number_of_targets, FULL_SEARCH_SPACE_SIZE, max_weight, node, *contractor_graph);
number_of_targets, FULL_SEARCH_SPACE_SIZE, max_weight, node, graph);
}
for (auto out_edge : contractor_graph->GetAdjacentEdgeRange(node))
for (auto out_edge : graph.GetAdjacentEdgeRange(node))
{
const ContractorEdgeData &out_data = contractor_graph->GetEdgeData(out_edge);
const ContractorEdgeData &out_data = graph.GetEdgeData(out_edge);
if (!out_data.forward)
{
continue;
}
const NodeID target = contractor_graph->GetTarget(out_edge);
const NodeID target = graph.GetTarget(out_edge);
if (target == node)
continue;
@@ -408,7 +407,7 @@ class GraphContractor
// This bias function takes up 22 assembly instructions in total on X86
bool Bias(const NodeID a, const NodeID b) const;
std::shared_ptr<ContractorGraph> contractor_graph;
ContractorGraph graph;
ExternalVector<QueryEdge> external_edge_list;
std::vector<NodeID> orig_node_id_from_new_node_id_map;
std::vector<float> node_levels;
@@ -4,6 +4,8 @@
#include "contractor/contractor_graph.hpp"
#include "util/log.hpp"
#include <tbb/parallel_sort.h>
#include <vector>
namespace osrm
@@ -13,15 +15,14 @@ namespace contractor
// Make sure to move in the input edge list!
template <typename InputEdgeContainer>
std::vector<ContractorEdge> adaptToContractorInput(InputEdgeContainer input_edge_list)
ContractorGraph toContractorGraph(NodeID number_of_nodes, InputEdgeContainer input_edge_list)
{
std::vector<ContractorEdge> edges;
edges.reserve(input_edge_list.size() * 2);
for (const auto &input_edge : input_edge_list)
{
if (input_edge.data.weight == INVALID_EDGE_WEIGHT)
continue;
BOOST_ASSERT(input_edge.data.weight < INVALID_EDGE_WEIGHT);
#ifndef NDEBUG
const unsigned int constexpr DAY_IN_DECI_SECONDS = 24 * 60 * 60 * 10;
@@ -52,10 +53,74 @@ std::vector<ContractorEdge> adaptToContractorInput(InputEdgeContainer input_edge
false,
input_edge.data.backward ? true : false,
input_edge.data.forward ? true : false);
};
tbb::parallel_sort(edges.begin(), edges.end());
NodeID edge = 0;
for (NodeID i = 0; i < edges.size();)
{
const NodeID source = edges[i].source;
const NodeID target = edges[i].target;
const NodeID id = edges[i].data.id;
// remove eigenloops
if (source == target)
{
++i;
continue;
}
ContractorEdge forward_edge;
ContractorEdge reverse_edge;
forward_edge.source = reverse_edge.source = source;
forward_edge.target = reverse_edge.target = target;
forward_edge.data.forward = reverse_edge.data.backward = true;
forward_edge.data.backward = reverse_edge.data.forward = false;
forward_edge.data.shortcut = reverse_edge.data.shortcut = false;
forward_edge.data.id = reverse_edge.data.id = id;
forward_edge.data.originalEdges = reverse_edge.data.originalEdges = 1;
forward_edge.data.weight = reverse_edge.data.weight = INVALID_EDGE_WEIGHT;
forward_edge.data.duration = reverse_edge.data.duration = MAXIMAL_EDGE_DURATION;
// remove parallel edges
while (i < edges.size() && edges[i].source == source && edges[i].target == target)
{
if (edges[i].data.forward)
{
forward_edge.data.weight = std::min(edges[i].data.weight, forward_edge.data.weight);
forward_edge.data.duration =
std::min(edges[i].data.duration, forward_edge.data.duration);
}
if (edges[i].data.backward)
{
reverse_edge.data.weight = std::min(edges[i].data.weight, reverse_edge.data.weight);
reverse_edge.data.duration =
std::min(edges[i].data.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;
edges[edge++] = forward_edge;
}
}
else
{ // insert seperate edges
if (((int)forward_edge.data.weight) != INVALID_EDGE_WEIGHT)
{
edges[edge++] = forward_edge;
}
if ((int)reverse_edge.data.weight != INVALID_EDGE_WEIGHT)
{
edges[edge++] = reverse_edge;
}
}
}
// FIXME not sure if we need this
edges.shrink_to_fit();
return edges;
util::Log() << "merged " << edges.size() - edge << " edges out of " << edges.size();
edges.resize(edge);
return ContractorGraph{number_of_nodes, edges};
}
} // namespace contractor
+2
View File
@@ -66,6 +66,8 @@ template <typename EdgeDataT> class DynamicGraph
}
};
DynamicGraph() : DynamicGraph(0) {}
// Constructs an empty graph with a given number of nodes.
explicit DynamicGraph(NodeIterator nodes) : number_of_nodes(nodes), number_of_edges(0)
{