static void discharge(MatrixT const &C, MatrixT &F, MatrixT &excess, MatrixT &height, MatrixT &seen, graphblas::IndexType u) { graphblas::IndexType num_nodes, cols; C.get_shape(num_nodes, cols); while (excess.get_value_at(0, u) > 0) { if (seen.get_value_at(0, u) < num_nodes) { graphblas::IndexType v = seen.get_value_at(0, u); if (((C.get_value_at(u, v) - F.get_value_at(u, v)) > 0) && (height.get_value_at(0, u) > height.get_value_at(0, v))) { push(C, F, excess, u, v); } else { seen.set_value_at(0, u, seen.get_value_at(0, u) + 1); } } else { relabel(C, F, height, u); seen.set_value_at(0, u, 0); } } }
static void push(MatrixT const &C, MatrixT &F, MatrixT &excess, graphblas::IndexType u, graphblas::IndexType v) { using T = typename MatrixT::ScalarType; T a = excess.get_value_at(0, u); T b = C.get_value_at(u, v) - F.get_value_at(u, v); T send = std::min(a, b); F.set_value_at(u, v, F.get_value_at(u, v) + send); F.set_value_at(v, u, F.get_value_at(v, u) - send); excess.set_value_at(0, u, excess.get_value_at(0, u) - send); excess.set_value_at(0, v, excess.get_value_at(0, v) + send); }
void row_index_of(MatrixT &mat) { graphblas::IndexType rows, cols; mat.get_shape(rows, cols); for (IndexType i = 0; i < rows; ++i) { for (IndexType j = 0; j < cols; ++j) { auto mat_ij = mat.get_value_at(i, j); if (mat_ij != mat.get_zero()) { mat.set_value_at(i, j, i); } } } }
static void relabel(MatrixT const &C, MatrixT const &F, MatrixT &height, graphblas::IndexType u) { using T = typename MatrixT::ScalarType; graphblas::IndexType num_nodes, cols; C.get_shape(num_nodes, cols); T min_height = std::numeric_limits<T>::max(); for (graphblas::IndexType v = 0; v < num_nodes; ++v) { if ((C.get_value_at(u, v) - F.get_value_at(u, v)) > 0) { T a = height.get_value_at(0, v); min_height = std::min(min_height, a); height.set_value_at(0, u, min_height + 1); } } }