Skip to content

Commit

Permalink
allow selection of balanced cuts
Browse files Browse the repository at this point in the history
  • Loading branch information
Moritz Kobitzsch committed Feb 8, 2017
1 parent 3cbdb68 commit 1c0bc9d
Show file tree
Hide file tree
Showing 4 changed files with 45 additions and 18 deletions.
9 changes: 7 additions & 2 deletions include/partition/annotated_partition.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -65,18 +65,23 @@ class AnnotatedPartition
std::size_t max_border_arcs_per_cell;

std::size_t total_memory_cells;
std::vector<std::size_t> cell_sizes;

std::ostream &print(std::ostream &os) const
{
os << "[level]\n"
<< "\t#border nodes: " << border_nodes << " #border arcs: " << border_arcs
<< " #cells: " << number_of_cells << " #contained nodes: " << contained_nodes << "\n"
<< "\tborder nodes: max: " << max_border_nodes_per_cell
<< "avg : " << static_cast<double>(border_nodes) / number_of_cells
<< " avg : " << static_cast<double>(border_nodes) / number_of_cells
<< " border arcs: max: " << max_border_arcs_per_cell << " "
<< " avg: " << static_cast<double>(border_arcs) / number_of_cells << "\n"
<< "\tmemory consumption: " << total_memory_cells / (1024.0 * 1024.0) << " MB."
<< std::endl;
<< "\n";
os << "\tcell sizes:";
for( auto s : cell_sizes )
os << " " << s;
os << std::endl;
return os;
}
};
Expand Down
2 changes: 1 addition & 1 deletion include/partition/inertial_flow.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,7 @@ class InertialFlow
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) const;
DinicMaxFlow::MinCut BestMinCut(std::size_t n, double ratio, double balance) const;

// The subgraph to partition into two parts.
const GraphView &view;
Expand Down
19 changes: 14 additions & 5 deletions src/partition/annotated_partition.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -157,12 +157,12 @@ void AnnotatedPartition::PrintBisection(const std::vector<SizedID> &implicit_tre
{
const auto prefix = id_queue.front();
id_queue.pop();
if (level == 0 || hasChildren(implicit_tree, prefix, level-1))
if (level == 0 || hasChildren(implicit_tree, prefix, level - 1))
{
current_level.push_back(
std::pair<BisectionID, std::uint32_t>(leftChild(prefix, level), level+1));
std::pair<BisectionID, std::uint32_t>(leftChild(prefix, level), level + 1));
current_level.push_back(
std::pair<BisectionID, std::uint32_t>(rightChild(prefix, level), level+1));
std::pair<BisectionID, std::uint32_t>(rightChild(prefix, level), level + 1));
}
add_child(leftChild(prefix, level), level);
add_child(rightChild(prefix, level), level);
Expand Down Expand Up @@ -195,6 +195,7 @@ void AnnotatedPartition::SearchLevels(double balance,
stats.print(std::cout);
};

std::size_t max_size = 0.5 * graph.NumberOfNodes();
while (!current_level.empty())
{
std::size_t total_size = 0;
Expand All @@ -219,7 +220,7 @@ void AnnotatedPartition::SearchLevels(double balance,
}
}

std::size_t max_size = balance * (total_size / static_cast<double>(count));
// std::size_t max_size = balance * (total_size / static_cast<double>(count));

current_level.clear();

Expand Down Expand Up @@ -249,6 +250,7 @@ void AnnotatedPartition::SearchLevels(double balance,
id_queue.pop();
}
print_level();
max_size *= 0.5;
}
}

Expand Down Expand Up @@ -310,13 +312,20 @@ AnnotatedPartition::AnalyseLevel(const BisectionGraph &graph,
const auto memory =
4 * std::accumulate(border_arcs.begin(), border_nodes.end(), std::size_t(0), squarded_size);

std::vector<std::size_t> cell_sizes_vec;
cell_sizes_vec.resize(cell_sizes.size());
std::transform(cell_sizes.begin(), cell_sizes.end(), cell_sizes_vec.begin(), [](const auto &pair) {
return pair.second;
});

return {border_nodes_total,
border_arcs_total,
contained_nodes,
border_nodes.size(),
max_nodes,
max_arcs,
memory};
memory,
std::move(cell_sizes_vec)};
}

std::vector<std::uint32_t> AnnotatedPartition::ComputeCellIDs(
Expand Down
33 changes: 23 additions & 10 deletions src/partition/inertial_flow.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -25,9 +25,7 @@ DinicMaxFlow::MinCut InertialFlow::ComputePartition(const std::size_t num_slopes
const double balance,
const double source_sink_rate)
{
auto cut = BestMinCut(num_slopes, source_sink_rate);

return cut;
return BestMinCut(num_slopes, source_sink_rate, balance);
}

InertialFlow::SpatialOrder InertialFlow::MakeSpatialOrder(const double ratio,
Expand Down Expand Up @@ -86,23 +84,36 @@ InertialFlow::SpatialOrder InertialFlow::MakeSpatialOrder(const double ratio,
return order;
}

DinicMaxFlow::MinCut InertialFlow::BestMinCut(const std::size_t n, const double ratio) const
DinicMaxFlow::MinCut
InertialFlow::BestMinCut(const std::size_t n, const double ratio, const double balance) const
{
DinicMaxFlow::MinCut best;
best.num_edges = -1;

const auto get_balance = [this](const auto num_nodes_source) {
double ratio = static_cast<double>(view.NumberOfNodes() - num_nodes_source) /
static_cast<double>(num_nodes_source);
return std::abs(ratio - 1.0);
const auto get_balance = [this, balance](const auto num_nodes_source) {
const auto perfect_balance = view.NumberOfNodes() / 2;
const auto allowed_balance = balance * perfect_balance;
const auto bigger_side =
std::max(num_nodes_source, view.NumberOfNodes() - num_nodes_source);

if (bigger_side > allowed_balance)
return bigger_side / static_cast<double>(allowed_balance);
else
return 0.0;
};

auto best_balance = 10000; // get_balance(best.num_nodes_source);
auto best_balance = 1;

std::mutex lock;

tbb::blocked_range<std::size_t> range{0, n, 1};

const auto balance_delta = [this](const auto num_nodes_source) {
const std::int64_t difference =
static_cast<std::int64_t>(view.NumberOfNodes()) / 2 - num_nodes_source;
return std::abs(difference);
};

tbb::parallel_for(range, [&, this](const auto &chunk) {
for (auto round = chunk.begin(), end = chunk.end(); round != end; ++round)
{
Expand All @@ -116,7 +127,9 @@ DinicMaxFlow::MinCut InertialFlow::BestMinCut(const std::size_t n, const double
std::lock_guard<std::mutex> guard{lock};

// Swap to keep the destruction of the old object outside of critical section.
if (std::tie(cut.num_edges, cut_balance) < std::tie(best.num_edges, best_balance))
if (cut.num_edges * cut_balance < best.num_edges * best_balance ||
(cut.num_edges == best.num_edges &&
balance_delta(cut.num_nodes_source) < balance_delta(best.num_nodes_source)))
{
best_balance = cut_balance;
std::swap(best, cut);
Expand Down

0 comments on commit 1c0bc9d

Please sign in to comment.