Make InertialFlow a function
This commit is contained in:
parent
54c35710f6
commit
e20cbf673f
@ -4,42 +4,15 @@
|
|||||||
#include "partition/dinic_max_flow.hpp"
|
#include "partition/dinic_max_flow.hpp"
|
||||||
#include "partition/graph_view.hpp"
|
#include "partition/graph_view.hpp"
|
||||||
|
|
||||||
#include <unordered_set>
|
|
||||||
#include <vector>
|
|
||||||
|
|
||||||
namespace osrm
|
namespace osrm
|
||||||
{
|
{
|
||||||
namespace partition
|
namespace partition
|
||||||
{
|
{
|
||||||
|
|
||||||
class InertialFlow
|
DinicMaxFlow::MinCut computeInertialFlowCut(const GraphView &view,
|
||||||
{
|
const std::size_t num_slopes,
|
||||||
public:
|
const double balance,
|
||||||
InertialFlow(const GraphView &view);
|
const double source_sink_rate);
|
||||||
|
|
||||||
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<NodeID> sources;
|
|
||||||
std::unordered_set<NodeID> 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;
|
|
||||||
};
|
|
||||||
|
|
||||||
} // namespace partition
|
} // namespace partition
|
||||||
} // namespace osrm
|
} // namespace osrm
|
||||||
|
@ -9,7 +9,9 @@
|
|||||||
#include <mutex>
|
#include <mutex>
|
||||||
#include <set>
|
#include <set>
|
||||||
#include <tuple>
|
#include <tuple>
|
||||||
|
#include <unordered_set>
|
||||||
#include <utility>
|
#include <utility>
|
||||||
|
#include <vector>
|
||||||
|
|
||||||
#include <tbb/blocked_range.h>
|
#include <tbb/blocked_range.h>
|
||||||
#include <tbb/parallel_for.h>
|
#include <tbb/parallel_for.h>
|
||||||
@ -18,18 +20,19 @@ namespace osrm
|
|||||||
{
|
{
|
||||||
namespace partition
|
namespace partition
|
||||||
{
|
{
|
||||||
|
namespace
|
||||||
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)
|
|
||||||
{
|
{
|
||||||
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<NodeID> sources;
|
||||||
|
std::unordered_set<NodeID> sinks;
|
||||||
|
};
|
||||||
|
|
||||||
InertialFlow::SpatialOrder InertialFlow::MakeSpatialOrder(const double ratio,
|
// Creates a spatial order of n * sources "first" and n * sink "last" node ids.
|
||||||
const double slope) const
|
// The slope determines the spatial order for sorting node coordinates.
|
||||||
|
SpatialOrder makeSpatialOrder(const GraphView &view, const double ratio, const double slope)
|
||||||
{
|
{
|
||||||
struct NodeWithCoordinate
|
struct NodeWithCoordinate
|
||||||
{
|
{
|
||||||
@ -70,7 +73,7 @@ InertialFlow::SpatialOrder InertialFlow::MakeSpatialOrder(const double ratio,
|
|||||||
|
|
||||||
reorderFirstLast(embedding, n, spatially);
|
reorderFirstLast(embedding, n, spatially);
|
||||||
|
|
||||||
InertialFlow::SpatialOrder order;
|
SpatialOrder order;
|
||||||
|
|
||||||
order.sources.reserve(n);
|
order.sources.reserve(n);
|
||||||
order.sinks.reserve(n);
|
order.sinks.reserve(n);
|
||||||
@ -84,13 +87,14 @@ InertialFlow::SpatialOrder InertialFlow::MakeSpatialOrder(const double ratio,
|
|||||||
return order;
|
return order;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Makes n cuts with different spatial orders and returns the best.
|
||||||
DinicMaxFlow::MinCut
|
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;
|
DinicMaxFlow::MinCut best;
|
||||||
best.num_edges = -1;
|
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 perfect_balance = view.NumberOfNodes() / 2;
|
||||||
const auto allowed_balance = balance * perfect_balance;
|
const auto allowed_balance = balance * perfect_balance;
|
||||||
const auto bigger_side =
|
const auto bigger_side =
|
||||||
@ -108,18 +112,18 @@ InertialFlow::BestMinCut(const std::size_t n, const double ratio, const double b
|
|||||||
|
|
||||||
tbb::blocked_range<std::size_t> range{0, n, 1};
|
tbb::blocked_range<std::size_t> 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 =
|
const std::int64_t difference =
|
||||||
static_cast<std::int64_t>(view.NumberOfNodes()) / 2 - num_nodes_source;
|
static_cast<std::int64_t>(view.NumberOfNodes()) / 2 - num_nodes_source;
|
||||||
return std::abs(difference);
|
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)
|
for (auto round = chunk.begin(), end = chunk.end(); round != end; ++round)
|
||||||
{
|
{
|
||||||
const auto slope = -1. + round * (2. / n);
|
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 = DinicMaxFlow()(view, order.sources, order.sinks);
|
||||||
auto cut_balance = get_balance(cut.num_nodes_source);
|
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;
|
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 partition
|
||||||
} // namespace osrm
|
} // namespace osrm
|
||||||
|
@ -70,10 +70,10 @@ RecursiveBisection::RecursiveBisection(BisectionGraph &bisection_graph_,
|
|||||||
|
|
||||||
// Bisect graph into two parts. Get partition point and recurse left and right in parallel.
|
// 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) {
|
tbb::parallel_do(begin(forest), end(forest), [&](const TreeNode &node, Feeder &feeder) {
|
||||||
InertialFlow flow{node.graph};
|
const auto cut =
|
||||||
const auto partition = flow.ComputePartition(num_optimizing_cuts, balance, boundary_factor);
|
computeInertialFlowCut(node.graph, num_optimizing_cuts, balance, boundary_factor);
|
||||||
const auto center = internal_state.ApplyBisection(
|
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 terminal = [&](const auto &node) {
|
||||||
const auto maximum_depth = sizeof(BisectionID) * CHAR_BIT;
|
const auto maximum_depth = sizeof(BisectionID) * CHAR_BIT;
|
||||||
|
Loading…
Reference in New Issue
Block a user