如何在Python中高效地创建随机动态图?
TL;DR:生成静态网络列表的速度是将这些静态网络合并为单个动态网络的速度的十倍。为什么会这样? 接下来,我尝试使用NetworkX和DyNetx生成一个随机动态图 在处理中等规模的网络(大约1000个节点和1000个时间戳)时会出现问题—内存崩溃。同样在较小的规模上(大约100个节点和300个时间戳),该过程非常缓慢。我相信我已经发现了障碍,但我不确定如何应对 以下是生成随机时间网络的简单代码示例:如何在Python中高效地创建随机动态图?,python,performance,networkx,Python,Performance,Networkx,TL;DR:生成静态网络列表的速度是将这些静态网络合并为单个动态网络的速度的十倍。为什么会这样? 接下来,我尝试使用NetworkX和DyNetx生成一个随机动态图 在处理中等规模的网络(大约1000个节点和1000个时间戳)时会出现问题—内存崩溃。同样在较小的规模上(大约100个节点和300个时间戳),该过程非常缓慢。我相信我已经发现了障碍,但我不确定如何应对 以下是生成随机时间网络的简单代码示例: 将dynetx导入为dnx 将networkx导入为nx 进口itertools 从随机导入随
将dynetx导入为dnx
将networkx导入为nx
进口itertools
从随机导入随机
def动态随机图(n,步数,上升率,种子=42):
#创建静态图列表
快照列表=列表()
对于范围内的t(0步):
G_t=nx.Graph()
边=itertools.组合(范围(n),2)
G_t.从(范围(n))添加节点
对于边中的e:
如果随机()
G_t.添加_边(*e)
快照列表。附加(G\U t)
#将静态图合并为动态图
动态图=dnx.DynGraph()
对于t,枚举中的图形(快照列表):
动态图。添加交互(图。边(数据=False),t=t)
返回动态图
如果我们运行以下命令:
%timeit dynamic_random_graph(300, 100, 0.5) # Memory was crahsed on larger networks.
>> 1 loop, best of 5: 15.1 s per loop
相反,如果我们在不合并网络的情况下运行代码,我们将获得显著更好的结果:
%timeit dynamic_random_graph_without_merge(300, 100, 0.5) # Ignore the merge part in the function
>> 1 loop, best of 5: 15.1 s per loop
如果在没有合并部分的情况下运行函数,我们可以在具有1000个节点的网络上工作,而不会出现内存崩溃
因此,我想看看,并试图找出add\u interactions\u from
方法的错误
这个函数很短很简单,但我很好奇为什么它需要这么多时间和内存,以及如何改进它。你的想法是什么?
这是: 我想最后的循环是所有问题的根源。
在
中添加交互
实现。只需考虑以下几点:
- 在没有合并阶段的情况下创建快照列表的成本比在动态图中合并快照列表的成本低,这是完全正常的:这通常是因为复制边的时间信息必须压缩为边的属性
- 您生成的随机图是密集的(50%的边都存在,这在大多数真实环境中是不现实的),这需要不断更新边的属性。通过减少边的数量,您将能够扩展到更大的网络。作为一个例子,考虑到ER模型,你模拟它足以P = 1 / N(其中n是图中节点的数量),以保证超临界政权(即,单个连接的组件);
- dynetx是对networkx的扩展,networkx的可扩展性不是特别强(在内存消耗和执行时间方面):当处理密集的、高度边缘化的图形时,这种限制比以往任何时候都更加明显
- 构建动态图的方式可能是最耗时的方式。您正在添加每对节点之间的交互,而没有利用对其有效持续时间的了解。如果交互(u,v)在t到t+k之间发生k次,则可以只插入一次这样的边,指定其消失时间,从而减少图形操纵操作
无论如何,我们欢迎对该库的每一项贡献:如果有人想研究它的可扩展性,我们将全力支持他 顺便说一句,networkx不是一个非常高效的软件包。我认为它是为非常小的图形设计的。您可能对neo4j或snap等替代软件包感兴趣。
def add_interactions_from(self, ebunch, t=None, e=None):
"""Add all the interaction in ebunch at time t.
Parameters
----------
ebunch : container of interaction
Each interaction given in the container will be added to the
graph. The interaction must be given as as 2-tuples (u,v) or
3-tuples (u,v,d) where d is a dictionary containing interaction
data.
t : appearance snapshot id, mandatory
e : vanishing snapshot id, optional
See Also
--------
add_edge : add a single interaction
Examples
--------
>>> import dynetx as dn
>>> G = dn.DynGraph()
>>> G.add_edges_from([(0,1),(1,2)], t=0)
"""
# set up attribute dict
if t is None:
raise nx.NetworkXError(
"The t argument must be a specified.")
# process ebunch
for ed in ebunch:
self.add_interaction(ed[0], ed[1], t, e)