forked from cmuparlay/parlaylib
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathbetweenness_centrality.h
46 lines (39 loc) · 1.71 KB
/
betweenness_centrality.h
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
#include <atomic>
#include <optional>
#include <utility>
#include <parlay/primitives.h>
#include <parlay/sequence.h>
#include "BFS_ligra.h"
// **************************************************************
// Betweenness centrality
// A parallel version of the algorithm from:
// A Faster Algorithm for Betweenness Centrality
// Ulrik Brandes
// Journal of Mathematical Sociology, 2001
// This code just calculates from a single source.
// Can either be maped over all sources for exact BC, or mapped
// over a (random) sample of sources for approximate BC.
// **************************************************************
template <typename vertex, typename graph>
auto BC_single_source(vertex start, const graph &G, const graph >) {
// get all levels of the BFS on G
auto levels = BFS(start, G, GT);
// label vertices with level and initialize sigma
struct vtx {int level; float sigma; float delta;};
parlay::sequence<vtx> V(G.size(), vtx{-1, 0.0, 0.0});
V[start] = vtx{0, 1.0, 0.0};
for_each(parlay::iota(levels.size()), [&] (long i) {
for_each(levels[i], [&] (vertex v) {V[v].level = i;});});
// forward pass over the levels to calculate sigma
for (long i = 1; i < levels.size(); i++)
for_each(levels[i], [&] (vertex v) {
V[v].sigma = reduce(delayed::map(GT[v], [&] (vertex u) {
return (V[u].level == i-1) ? V[u].sigma : 0.0;}));});
// backward pass over the levels to calculate delta
for (long i = levels.size()-2; i > 0; i--) {
for_each(levels[i], [&] (vertex u) {
V[u].delta = V[u].sigma * reduce(delayed::map(G[u], [&] (vertex v) {
return (V[v].level == i+1) ? 1/V[v].sigma * (1 + V[v].delta) : 0.0;}));});
}
return map(V, [] (vtx& v) {return v.delta;});
}