#include "partitioner/bisection_graph_view.hpp" #include "partitioner/dinic_max_flow.hpp" #include "partitioner/graph_generator.hpp" #include "partitioner/recursive_bisection_state.hpp" #include #include #include #include using namespace osrm::partitioner; using namespace osrm::util; BOOST_AUTO_TEST_SUITE(dinic_algorithm) BOOST_AUTO_TEST_CASE(horizontal_cut_between_two_grids) { // 40 entries of left/right edges const double step_size = 0.01; const int rows = 10; const int cols = 10; // build a small grid (10*10) and a (100 * 10) below (to make the different steps unique) auto graph = [&]() { std::vector grid_coordinates; std::vector grid_edges; const auto connect = [&grid_edges](const NodeID from, const NodeID to) { grid_edges.push_back({from, to, 1}); grid_edges.push_back({to, from, 1}); }; // 10 rows of large components, interrupted by small disconnected components const auto small_coordinates = makeGridCoordinates(rows, cols, step_size, 0, 0); grid_coordinates.insert( grid_coordinates.end(), small_coordinates.begin(), small_coordinates.end()); // connect the grid edges, starting with i * (rows * cols + 1) as first id (0,11,22...) const auto small_edges = makeGridEdges(rows, cols, 0); grid_edges.insert(grid_edges.end(), small_edges.begin(), small_edges.end()); const auto large_coordinates = makeGridCoordinates(10 * rows, cols, step_size, 0, rows * step_size); grid_coordinates.insert( grid_coordinates.end(), large_coordinates.begin(), large_coordinates.end()); const auto large_edges = makeGridEdges(10 * rows, cols, (rows * cols)); grid_edges.insert(grid_edges.end(), large_edges.begin(), large_edges.end()); connect(45, 1001); connect(55, 800); connect(65, 600); connect(75, 200); groupEdgesBySource(grid_edges.begin(), grid_edges.end()); return makeBisectionGraph(grid_coordinates, adaptToBisectionEdge(std::move(grid_edges))); }(); RecursiveBisectionState bisection_state(graph); BisectionGraphView view(graph); DinicMaxFlow::SourceSinkNodes sources, sinks; for (int i = 0; i < 10; ++i) { sources.insert(static_cast(i)); sinks.insert(static_cast(1000 + i)); } DinicMaxFlow flow; const auto cut = flow(view, sources, sinks); BOOST_CHECK(cut.num_edges == 4); } BOOST_AUTO_TEST_SUITE_END()