【问题标题】:Shuffling a large network using Python使用 Python 对大型网络进行洗牌
【发布时间】:2015-10-09 02:27:00
【问题描述】:

我有一个大型网络要分析。例如:

import networkx as nx
import random

BA = nx.random_graphs.barabasi_albert_graph(1000000, 3)
nx.info(BA)

我必须在保持度数分布不变的同时对边缘进行洗牌。基本思想由Maslov介绍。因此,我和我的同事编写了一个 shuffleNetwork 函数,我们在其中对网络对象 G 工作了 num 次。边缘是一个列表对象。

问题是这个函数对于大型网络来说运行太慢了。我尝试使用 setdict 而不是 list 作为边缘对象(set 和 dict 是哈希表)。但是,由于我们还需要删除和添加元素,时间复杂度变得更大。

您对进一步优化此功能有什么建议吗?

def shuffleNetwork(G,Num):
    edges=G.edges()
    l=range(len(edges))
    for n in range(Num):
        i,j = random.sample(l, 2)
        a,b=edges[i]
        c,d=edges[j]
        if a != d and c!= b:
            if not (a,d) in edges or (d, a) in edges or (c,b) in edges or (b, c) in edges:
                edges[i]=(a,d)
                edges[j]=(c,b)
    K=nx.from_edgelist(edges)
    return K



import timeit
start = timeit.default_timer()
#Your statements here
gr = shuffleNetwork(BA, 1000)
stop = timeit.default_timer()
print stop - start 

【问题讨论】:

  • 我再次查看了您的代码。我认为较慢的部分是测试(a,d) in edges 等。执行if not G.has_edge(a,d) 会更快。然后,与其检查(a,d) 是否在您的边列表中(需要检查您的边列表中的每条边),它直接转到a 并检查d 是否是邻居。这是 O(1)(几乎)与 O(len(edgelist))。我怀疑通过此更改,您的代码将与 double_edge_swap 相当。

标签: python list hash networkx shuffle


【解决方案1】:

你应该考虑使用nx.double_edge_swap

文档是here。它看起来完全符合您的要求,但修改了图表。

我不确定它是否会解决速度问题,但它确实避免了生成列表,所以我认为它会比你所拥有的做得更好。

您可以使用nx.double_edge_swap(G,nswap=number) 调用它

【讨论】:

  • 这正是我需要的,虽然我仍然不知道它是如何神奇地做到的。非常感谢。
  • 选中源:networkx.github.io/documentation/latest/_modules/networkx/…它使用nx.utils生成累积分布,然后从中选择恰当。这使它可以根据其边数按比例选择一个节点,然后选择该节点的一条边,因此它对边进行均匀采样,但不必生成边列表。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-03-20
  • 2017-10-14
  • 2011-09-02
  • 1970-01-01
  • 1970-01-01
  • 2019-09-20
相关资源
最近更新 更多