diff --git a/include/partition/inertial_flow.hpp b/include/partition/inertial_flow.hpp index a1f17aa16..ae8cf076e 100644 --- a/include/partition/inertial_flow.hpp +++ b/include/partition/inertial_flow.hpp @@ -4,42 +4,15 @@ #include "partition/dinic_max_flow.hpp" #include "partition/graph_view.hpp" -#include -#include - namespace osrm { namespace partition { -class InertialFlow -{ - public: - InertialFlow(const GraphView &view); - - DinicMaxFlow::MinCut ComputePartition(const std::size_t num_slopes, - const double balance, - const double source_sink_rate); - - private: - // Spatially ordered sources and sink ids. - // The node ids refer to nodes in the GraphView. - struct SpatialOrder - { - std::unordered_set sources; - std::unordered_set sinks; - }; - - // Creates a spatial order of n * sources "first" and n * sink "last" node ids. - // The slope determines the spatial order for sorting node coordinates. - SpatialOrder MakeSpatialOrder(double ratio, double slope) const; - - // Makes n cuts with different spatial orders and returns the best. - DinicMaxFlow::MinCut BestMinCut(std::size_t n, double ratio, double balance) const; - - // The subgraph to partition into two parts. - const GraphView &view; -}; +DinicMaxFlow::MinCut computeInertialFlowCut(const GraphView &view, + const std::size_t num_slopes, + const double balance, + const double source_sink_rate); } // namespace partition } // namespace osrm diff --git a/src/partition/inertial_flow.cpp b/src/partition/inertial_flow.cpp index 84411c9b3..0df110d53 100644 --- a/src/partition/inertial_flow.cpp +++ b/src/partition/inertial_flow.cpp @@ -9,7 +9,9 @@ #include #include #include +#include #include +#include #include #include @@ -18,18 +20,19 @@ namespace osrm { namespace partition { - -InertialFlow::InertialFlow(const GraphView &view_) : view(view_) {} - -DinicMaxFlow::MinCut InertialFlow::ComputePartition(const std::size_t num_slopes, - const double balance, - const double source_sink_rate) +namespace { - return BestMinCut(num_slopes, source_sink_rate, balance); -} +// Spatially ordered sources and sink ids. +// The node ids refer to nodes in the GraphView. +struct SpatialOrder +{ + std::unordered_set sources; + std::unordered_set sinks; +}; -InertialFlow::SpatialOrder InertialFlow::MakeSpatialOrder(const double ratio, - const double slope) const +// Creates a spatial order of n * sources "first" and n * sink "last" node ids. +// The slope determines the spatial order for sorting node coordinates. +SpatialOrder makeSpatialOrder(const GraphView &view, const double ratio, const double slope) { struct NodeWithCoordinate { @@ -70,7 +73,7 @@ InertialFlow::SpatialOrder InertialFlow::MakeSpatialOrder(const double ratio, reorderFirstLast(embedding, n, spatially); - InertialFlow::SpatialOrder order; + SpatialOrder order; order.sources.reserve(n); order.sinks.reserve(n); @@ -84,13 +87,14 @@ InertialFlow::SpatialOrder InertialFlow::MakeSpatialOrder(const double ratio, return order; } +// Makes n cuts with different spatial orders and returns the best. DinicMaxFlow::MinCut -InertialFlow::BestMinCut(const std::size_t n, const double ratio, const double balance) const +bestMinCut(const GraphView &view, const std::size_t n, const double ratio, const double balance) { DinicMaxFlow::MinCut best; best.num_edges = -1; - const auto get_balance = [this, balance](const auto num_nodes_source) { + const auto get_balance = [&view, balance](const auto num_nodes_source) { const auto perfect_balance = view.NumberOfNodes() / 2; const auto allowed_balance = balance * perfect_balance; const auto bigger_side = @@ -108,18 +112,18 @@ InertialFlow::BestMinCut(const std::size_t n, const double ratio, const double b tbb::blocked_range range{0, n, 1}; - const auto balance_delta = [this](const auto num_nodes_source) { + const auto balance_delta = [&view](const auto num_nodes_source) { const std::int64_t difference = static_cast(view.NumberOfNodes()) / 2 - num_nodes_source; return std::abs(difference); }; - tbb::parallel_for(range, [&, this](const auto &chunk) { + tbb::parallel_for(range, [&](const auto &chunk) { for (auto round = chunk.begin(), end = chunk.end(); round != end; ++round) { const auto slope = -1. + round * (2. / n); - auto order = this->MakeSpatialOrder(ratio, slope); + auto order = makeSpatialOrder(view, ratio, slope); auto cut = DinicMaxFlow()(view, order.sources, order.sinks); auto cut_balance = get_balance(cut.num_nodes_source); @@ -141,6 +145,15 @@ InertialFlow::BestMinCut(const std::size_t n, const double ratio, const double b return best; } +} + +DinicMaxFlow::MinCut computeInertialFlowCut(const GraphView &view, + const std::size_t num_slopes, + const double balance, + const double source_sink_rate) +{ + return bestMinCut(view, num_slopes, source_sink_rate, balance); +} } // namespace partition } // namespace osrm diff --git a/src/partition/recursive_bisection.cpp b/src/partition/recursive_bisection.cpp index f6507cd56..3698828b8 100644 --- a/src/partition/recursive_bisection.cpp +++ b/src/partition/recursive_bisection.cpp @@ -70,10 +70,10 @@ RecursiveBisection::RecursiveBisection(BisectionGraph &bisection_graph_, // Bisect graph into two parts. Get partition point and recurse left and right in parallel. tbb::parallel_do(begin(forest), end(forest), [&](const TreeNode &node, Feeder &feeder) { - InertialFlow flow{node.graph}; - const auto partition = flow.ComputePartition(num_optimizing_cuts, balance, boundary_factor); + const auto cut = + computeInertialFlowCut(node.graph, num_optimizing_cuts, balance, boundary_factor); const auto center = internal_state.ApplyBisection( - node.graph.Begin(), node.graph.End(), node.depth, partition.flags); + node.graph.Begin(), node.graph.End(), node.depth, cut.flags); const auto terminal = [&](const auto &node) { const auto maximum_depth = sizeof(BisectionID) * CHAR_BIT;