21 const auto node_count = boost::num_vertices(g);
22 std::vector<double> centrality_by_index(
static_cast<std::size_t
>(node_count), 0.0);
23 if (node_count == 0) {
26 for (
auto [v, vend] = boost::vertices(g); v != vend; ++v) {
27 centrality_by_index[get_vertex_index(*v)] = 0.0;
29 if (node_count <= 1) {
30 return build_node_indexed_result<double>([&](VertexDesc v) {
31 return centrality_by_index[get_vertex_index(v)];
34 const double scale = 1.0 /
static_cast<double>(node_count - 1);
35 for (
auto [v, vend] = boost::vertices(g); v != vend; ++v) {
37 if constexpr (Directed) {
38 degree =
static_cast<double>(boost::in_degree(*v, g) + boost::out_degree(*v, g));
40 degree =
static_cast<double>(boost::degree(*v, g));
42 centrality_by_index[get_vertex_index(*v)] = degree * scale;
44 return build_node_indexed_result<double>([&](VertexDesc v) {
45 return centrality_by_index[get_vertex_index(v)];
52 std::size_t max_iterations
54 const auto node_count = boost::num_vertices(g);
55 if (node_count == 0) {
59 const double n =
static_cast<double>(node_count);
60 const double damping = 0.85;
61 std::vector<double> rank(
static_cast<std::size_t
>(node_count), 1.0 / n);
62 std::vector<double> next(
static_cast<std::size_t
>(node_count), 0.0);
64 for (std::size_t iteration = 0; iteration < max_iterations; ++iteration) {
65 const double base = (1.0 - damping) / n;
66 std::fill(next.begin(), next.end(), base);
68 double dangling_sum = 0.0;
69 for (
auto [u, uend] = boost::vertices(g); u != uend; ++u) {
70 const auto out = boost::out_degree(*u, g);
71 const auto index = get_vertex_index(*u);
73 dangling_sum += rank[index];
77 const double share = damping * rank[index] /
static_cast<double>(out);
78 for (
auto [adj, adj_end] = boost::adjacent_vertices(*u, g); adj != adj_end; ++adj) {
79 next[get_vertex_index(*adj)] += share;
83 if (dangling_sum > 0.0) {
84 const double dangling_share = damping * dangling_sum / n;
85 for (
double& value : next) {
86 value += dangling_share;
91 for (std::size_t i = 0; i < rank.size(); ++i) {
92 delta += std::abs(next[i] - rank[i]);
96 if (delta < tolerance) {
101 return build_node_indexed_result<double>([&](VertexDesc v) {
102 return rank[get_vertex_index(v)];
134 const auto node_count = boost::num_vertices(g);
135 if (node_count == 0) {
139 const std::size_t n =
static_cast<std::size_t
>(node_count);
140 std::vector<double> bc(n, 0.0);
144 for (
auto [s_it, s_end] = boost::vertices(g); s_it != s_end; ++s_it) {
145 const VertexDesc s = *s_it;
146 const std::size_t s_idx = get_vertex_index(s);
149 std::vector<std::size_t> stack;
153 std::vector<std::vector<std::size_t>> pred(n);
156 std::vector<double> sigma(n, 0.0);
160 std::vector<int> dist(n, -1);
163 std::queue<VertexDesc> bfs_queue;
166 while (!bfs_queue.empty()) {
167 const VertexDesc v = bfs_queue.front();
169 const std::size_t v_idx = get_vertex_index(v);
170 stack.push_back(v_idx);
172 for (
auto [w_it, w_end] = boost::adjacent_vertices(v, g); w_it != w_end; ++w_it) {
173 const std::size_t w_idx = get_vertex_index(*w_it);
175 if (dist[w_idx] < 0) {
176 bfs_queue.push(*w_it);
177 dist[w_idx] = dist[v_idx] + 1;
179 if (dist[w_idx] == dist[v_idx] + 1) {
180 sigma[w_idx] += sigma[v_idx];
181 pred[w_idx].push_back(v_idx);
187 std::vector<double> delta(n, 0.0);
188 while (!stack.empty()) {
189 const std::size_t w_idx = stack.back();
191 for (
const std::size_t v_idx : pred[w_idx]) {
192 if (sigma[w_idx] > 0.0) {
193 delta[v_idx] += (sigma[v_idx] / sigma[w_idx]) * (1.0 + delta[w_idx]);
196 if (w_idx != s_idx) {
197 bc[w_idx] += delta[w_idx];
204 if (node_count > 2) {
205 const double denom =
static_cast<double>(node_count - 1) *
static_cast<double>(node_count - 2);
206 const double scale = Directed ? 1.0 / denom : 2.0 / denom;
207 for (
double& v : bc) v *= scale;
210 return build_node_indexed_result<double>([&](VertexDesc v) {
211 return bc[get_vertex_index(v)];
auto degree_centrality(const GraphWrapper &G)
Deprecated free-function alias for G.degree_centrality().
Definition centrality.hpp:128
auto betweenness_centrality(const GraphWrapper &G)
Deprecated free-function alias for G.betweenness_centrality().
Definition centrality.hpp:224
auto pagerank(const GraphWrapper &G)
Deprecated free-function alias for G.pagerank().
Definition centrality.hpp:115
auto pagerank(double tolerance=1e-6, std::size_t max_iterations=100) const
Computes PageRank scores for every node.
Definition centrality.hpp:50