add unit tests for the different components of the parttion tool
This commit is contained in:
committed by
Patrick Niklaus
parent
e316dad1cb
commit
b789da45bd
@@ -56,7 +56,7 @@ using BisectionInputEdge = GraphConstructionWrapper<BisectionEdge>;
|
||||
using BisectionGraph = RemappableGraph<BisectionGraphNode, BisectionEdge>;
|
||||
|
||||
// Factory method to construct the bisection graph form a set of coordinates and Input Edges (need
|
||||
// to contain source and target)
|
||||
// to contain source and target). Edges needs to be labeled from zero
|
||||
inline BisectionGraph makeBisectionGraph(const std::vector<util::Coordinate> &coordinates,
|
||||
const std::vector<BisectionInputEdge> &edges)
|
||||
{
|
||||
|
||||
@@ -32,8 +32,13 @@ class DinicMaxFlow
|
||||
using SourceSinkNodes = std::unordered_set<NodeID>;
|
||||
|
||||
MinCut operator()(const GraphView &view,
|
||||
const SourceSinkNodes &sink_nodes,
|
||||
const SourceSinkNodes &source_nodes) const;
|
||||
const SourceSinkNodes &source_nodes,
|
||||
const SourceSinkNodes &sink_nodes) const;
|
||||
|
||||
// validates the inpiut parameters to the flow algorithm (e.g. not intersecting)
|
||||
bool Validate(const GraphView &view,
|
||||
const SourceSinkNodes &source_nodes,
|
||||
const SourceSinkNodes &sink_nodes) const;
|
||||
|
||||
private:
|
||||
// the level of each node in the graph (==hops in BFS from source)
|
||||
|
||||
@@ -2,7 +2,6 @@
|
||||
#define OSRM_PARTITION_GRAPHVIEW_HPP_
|
||||
|
||||
#include "partition/bisection_graph.hpp"
|
||||
#include "partition/recursive_bisection_state.hpp"
|
||||
|
||||
#include <boost/iterator/filter_iterator.hpp>
|
||||
#include <boost/iterator/iterator_facade.hpp>
|
||||
@@ -41,6 +40,7 @@ class GraphView
|
||||
// Iteration over all nodes (direct access into the node)
|
||||
ConstNodeIterator Begin() const;
|
||||
ConstNodeIterator End() const;
|
||||
auto Nodes() const { return boost::make_iterator_range(begin, end); }
|
||||
|
||||
// Re-Construct the ID of a node from a reference
|
||||
NodeID GetID(const NodeT &node) const;
|
||||
@@ -50,6 +50,7 @@ class GraphView
|
||||
const EdgeT &Edge(const EdgeID eid) const;
|
||||
|
||||
// Access into all Edges
|
||||
auto Edges(const NodeT &node) const { return bisection_graph.Edges(node); }
|
||||
auto Edges(const NodeID nid) const { return bisection_graph.Edges(*(begin + nid)); }
|
||||
auto BeginEdges(const NodeID nid) const { return bisection_graph.BeginEdges(*(begin + nid)); }
|
||||
auto EndEdges(const NodeID nid) const { return bisection_graph.EndEdges(*(begin + nid)); }
|
||||
|
||||
@@ -47,6 +47,7 @@ struct PartitionConfig
|
||||
double balance;
|
||||
double boundary_factor;
|
||||
std::size_t num_optimizing_cuts;
|
||||
std::size_t small_component_size;
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
@@ -123,11 +123,16 @@ template <typename NodeEntryT, typename EdgeEntryT> class RemappableGraph
|
||||
auto Nodes() { return boost::make_iterator_range(nodes.begin(), nodes.end()); }
|
||||
auto Nodes() const { return boost::make_iterator_range(nodes.begin(), nodes.end()); }
|
||||
|
||||
NodeID GetID(const NodeT &node)
|
||||
NodeID GetID(const NodeT &node) const
|
||||
{
|
||||
BOOST_ASSERT(&node >= &nodes[0] && &node <= &nodes.back());
|
||||
return (&node - &nodes[0]);
|
||||
}
|
||||
EdgeID GetID(const EdgeT &edge) const
|
||||
{
|
||||
BOOST_ASSERT(&edge >= &edges[0] && &edge <= &edges.back());
|
||||
return (&edge - &edges[0]);
|
||||
}
|
||||
|
||||
NodeIterator Begin() { return nodes.begin(); }
|
||||
NodeIterator End() { return nodes.end(); }
|
||||
|
||||
@@ -16,21 +16,18 @@ namespace partition
|
||||
class RecursiveBisection
|
||||
{
|
||||
public:
|
||||
RecursiveBisection(std::size_t maximum_cell_size,
|
||||
double balance,
|
||||
double boundary_factor,
|
||||
std::size_t num_optimizing_cuts,
|
||||
BisectionGraph &bisection_graph);
|
||||
RecursiveBisection(BisectionGraph &bisection_graph,
|
||||
const std::size_t maximum_cell_size,
|
||||
const double balance,
|
||||
const double boundary_factor,
|
||||
const std::size_t num_optimizing_cuts,
|
||||
const std::size_t small_component_size);
|
||||
|
||||
const std::vector<RecursiveBisectionState::BisectionID> &BisectionIDs() const;
|
||||
|
||||
private:
|
||||
BisectionGraph &bisection_graph;
|
||||
RecursiveBisectionState internal_state;
|
||||
|
||||
// on larger graphs, SCCs give perfect cuts (think Amerika vs Europe)
|
||||
// This function performs an initial pre-partitioning using these sccs.
|
||||
std::vector<GraphView> FakeFirstPartitionWithSCC(const std::size_t small_component_size);
|
||||
};
|
||||
|
||||
} // namespace partition
|
||||
|
||||
@@ -6,6 +6,7 @@
|
||||
#include <vector>
|
||||
|
||||
#include "partition/bisection_graph.hpp"
|
||||
#include "partition/graph_view.hpp"
|
||||
#include "util/typedefs.hpp"
|
||||
|
||||
namespace osrm
|
||||
@@ -13,51 +14,8 @@ namespace osrm
|
||||
namespace partition
|
||||
{
|
||||
|
||||
// The recursive state describes the relation between our global graph and the recursive state in a
|
||||
// recursive bisection.
|
||||
//
|
||||
// We describe the state with the use of two arrays:
|
||||
//
|
||||
// The id-arrays keeps nodes in order, based on their partitioning. Initially, it contains all nodes
|
||||
// in sorted order:
|
||||
//
|
||||
// ids: [0,1,2,3,4,5,6,7,8,9]
|
||||
//
|
||||
// When partitioned (for this example we use even : odd), the arrays is re-ordered to group all
|
||||
// elements within a single cell of the partition:
|
||||
//
|
||||
// ids: [0,2,4,6,8,1,3,5,7,9]
|
||||
//
|
||||
// This can be performed recursively by interpreting the arrays [0,2,4,6,8] and [1,3,5,7,9] as new
|
||||
// input.
|
||||
//
|
||||
// The partitioning array describes all results of the partitioning in form of `left` or `right`.
|
||||
// It is a sequence of bits for every id that describes if it is moved to the `front` or `back`
|
||||
// during the split of the ID array. In the example, we would get the result
|
||||
//
|
||||
// bisection-ids: [0,1,0,1,0,1,0,1,0,1]
|
||||
//
|
||||
// Further partitioning [0,2,4,6,8] into [0,4,8], [2,6] and [1,3,5,7,9] into [1,3,9] and [5,7]
|
||||
// the result would be:
|
||||
//
|
||||
// bisection-ids: [00,10,01,10,00,11,01,11,00,10]
|
||||
|
||||
/* Written out in a recursive tree form:
|
||||
|
||||
ids: [0,1,2,3,4,5,6,7,8,9]
|
||||
mask: [0,1,0,1,0,1,0,1,0,1]
|
||||
/ \
|
||||
ids: [0,2,4,6,8] [1,3,5,7,9]
|
||||
mask: [0,1,0,1,0] [0,0,1,1,0]
|
||||
/ \ / \
|
||||
ids: [0,4,8] [2,6] [1,3,9] [5,7]
|
||||
|
||||
The bisection ids then trace the path (left: 0, right: 1) through the tree:
|
||||
|
||||
ids: [0, 1, 2, 3, 4, 5, 6, 7, 8, 9 ]
|
||||
path: [00, 10, 01, 10, 00, 11, 01, 11, 00, 10]
|
||||
|
||||
*/
|
||||
// Keeps track of the bisection ids, modifies the graph accordingly, splitting it into a left/right
|
||||
// section with consecutively labelled nodes. Requires a GraphView to look at.
|
||||
class RecursiveBisectionState
|
||||
{
|
||||
public:
|
||||
@@ -77,6 +35,11 @@ class RecursiveBisectionState
|
||||
const std::size_t depth,
|
||||
const std::vector<bool> &partition);
|
||||
|
||||
// perform an initial pre-partitioning into small components
|
||||
// on larger graphs, SCCs give perfect cuts (think Amerika vs Europe)
|
||||
// This function performs an initial pre-partitioning using these sccs.
|
||||
std::vector<GraphView> PrePartitionWithSCC(const std::size_t small_component_size);
|
||||
|
||||
const std::vector<BisectionID> &BisectionIDs() const;
|
||||
|
||||
private:
|
||||
|
||||
@@ -0,0 +1,19 @@
|
||||
#ifndef OSRM_PARTITION_RECURSIVE_BISECTION_STATS_HPP_
|
||||
#define OSRM_PARTITION_RECURSIVE_BISECTION_STATS_HPP_
|
||||
|
||||
#include "partition/bisection_graph.hpp"
|
||||
#include "partition/recursive_bisection_state.hpp"
|
||||
|
||||
#include <vector>
|
||||
|
||||
namespace osrm
|
||||
{
|
||||
namespace partition
|
||||
{
|
||||
// generates some statistics on a recursive bisection to describe its quality/parameters
|
||||
void printBisectionStats(std::vector<RecursiveBisectionState::BisectionID> const &bisection_ids,
|
||||
const BisectionGraph &graph);
|
||||
} // namespace partition
|
||||
} // namespace osrm
|
||||
|
||||
#endif // OSRM_PARTITION_RECURSIVE_BISECTION_STATS_HPP_
|
||||
@@ -85,7 +85,7 @@ template <typename NodeT, typename EdgeT, bool UseSharedMemory = false> class Fl
|
||||
{
|
||||
static_assert(traits::HasFirstEdgeMember<NodeT>::value,
|
||||
"Model for compatible Node type requires .first_edge member attribute");
|
||||
static_assert(traits::HasTargetMember<EdgeT>(),
|
||||
static_assert(traits::HasTargetMember<EdgeT>::value,
|
||||
"Model for compatible Node type requires .target member attribute");
|
||||
|
||||
public:
|
||||
|
||||
Reference in New Issue
Block a user