并行介数#

使用 Python 标准库的 multiprocessing 模块并行实现介数中心性的示例。

betweenness centrality 函数接受一组节点,并计算这些节点对整个网络的介数中心性的贡献。在这里,我们将网络划分为节点块,并计算它们对整个网络介数中心性的贡献。

注意:下面的示例输出显示非并行实现更快。这是我们 CI/CD 流水线在单核上运行的局限性。

根据您的设置,您可能会看到加速效果。

plot parallel betweenness
Computing betweenness centrality for:
Graph with 1000 nodes and 2991 edges
        Parallel version
                Time: 0.8885 seconds
                Betweenness centrality for node 0: 0.07416
        Non-Parallel version
                Time: 1.9108 seconds
                Betweenness centrality for node 0: 0.07416

Computing betweenness centrality for:
Graph with 1000 nodes and 4969 edges
        Parallel version
                Time: 1.1523 seconds
                Betweenness centrality for node 0: 0.00301
        Non-Parallel version
                Time: 2.4428 seconds
                Betweenness centrality for node 0: 0.00301

Computing betweenness centrality for:
Graph with 1000 nodes and 2000 edges
        Parallel version
                Time: 0.9824 seconds
                Betweenness centrality for node 0: 0.00490
        Non-Parallel version
                Time: 1.8211 seconds
                Betweenness centrality for node 0: 0.00490

from multiprocessing import Pool
import time
import itertools

import matplotlib.pyplot as plt
import networkx as nx


def chunks(l, n):
    """Divide a list of nodes `l` in `n` chunks"""
    l_c = iter(l)
    while 1:
        x = tuple(itertools.islice(l_c, n))
        if not x:
            return
        yield x


def betweenness_centrality_parallel(G, processes=None):
    """Parallel betweenness centrality  function"""
    p = Pool(processes=processes)
    node_divisor = len(p._pool) * 4
    node_chunks = list(chunks(G.nodes(), G.order() // node_divisor))
    num_chunks = len(node_chunks)
    bt_sc = p.starmap(
        nx.betweenness_centrality_subset,
        zip(
            [G] * num_chunks,
            node_chunks,
            [list(G)] * num_chunks,
            [True] * num_chunks,
            [None] * num_chunks,
        ),
    )

    # Reduce the partial solutions
    bt_c = bt_sc[0]
    for bt in bt_sc[1:]:
        for n in bt:
            bt_c[n] += bt[n]
    return bt_c


G_ba = nx.barabasi_albert_graph(1000, 3)
G_er = nx.gnp_random_graph(1000, 0.01)
G_ws = nx.connected_watts_strogatz_graph(1000, 4, 0.1)
for G in [G_ba, G_er, G_ws]:
    print("")
    print("Computing betweenness centrality for:")
    print(G)
    print("\tParallel version")
    start = time.time()
    bt = betweenness_centrality_parallel(G)
    print(f"\t\tTime: {(time.time() - start):.4F} seconds")
    print(f"\t\tBetweenness centrality for node 0: {bt[0]:.5f}")
    print("\tNon-Parallel version")
    start = time.time()
    bt = nx.betweenness_centrality(G)
    print(f"\t\tTime: {(time.time() - start):.4F} seconds")
    print(f"\t\tBetweenness centrality for node 0: {bt[0]:.5f}")
print("")

nx.draw(G_ba, node_size=100)
plt.show()

脚本总运行时间: (0 分 14.288 秒)

由 Sphinx-Gallery 生成的画廊