生成具有幂律度分布的无标度网络

时间:2015-03-07 22:30:52

标签: python graph graph-algorithm networkx

我正在尝试生成一些无标度网络:

  • 具有相同指数的幂律之后的度分布
  • 完全相同的节点数。

我需要建立至少60对夫妻并为每个夫妻进行模拟。

为了做到这一点,我需要一种方法来生成具有上述属性的n个节点的网络。

现在,我可以使用NetworkX Python库,使用此代码生成具有指数分布的幂律分布的图形

import networkx as nx
import matplotlib.pyplot as plt

#create a graph with degrees following a power law distribution
s = nx.utils.powerlaw_sequence(100, 2.5) #100 nodes, power-law exponent 2.5
G = nx.expected_degree_graph(s, selfloops=False)

print(G.nodes())
print(G.edges())

#draw and show graph
pos = nx.spring_layout(G)
nx.draw_networkx(G, pos)
plt.show()

但是,这会生成一个包含许多孤立节点的图形,通常不只是一个连接的组件。

我可以丢弃孤立的节点,但是我的最终网络将拥有比我预期更少的节点,并且它可能不是单个网络。它可能是2个或更多单独的连接组件。

2 个答案:

答案 0 :(得分:2)

首先提出一个问题 - 您是否有理由不想要隔离节点或多个连接组件?原则上,一个真正的"随机"幂律图将有这些。

所以有一些评论:

1)如果你使用expected_degree_graph,你将很难消除孤立的节点。这是因为有许多节点的预期度大约为1(但实际度数来自泊松分布)。这意味着他们很可能拥有小于1的学位。为了证明自己,请打印s

2)另一种选择是使用配置模型图来建立网络。为此,我们从powerlaw序列中取数字并取整数部分。丢弃那些为0.然后使用nx.configuration_model创建图形。然后,您可以删除自循环和重复边。但是,您应该小心 - 高度节点可能有许多自循环或重复边。所以你需要小心,powerlaw的尾巴不会被削减得太快。这不能解决具有多个组件的问题。您通常会有一个非常大的组件和一些非常小的隔离组件。除非你有充分的理由抛弃这些,否则抛弃这样的情况会使你的样本产生偏差。

import networkx as nx
import matplotlib.pyplot as plt

#create a graph with degrees following a power law distribution

#I believe we can eliminate this loop to find s by using the call   
#nx.utils.create_degree_sequence(100,powerlaw_sequence) with 
#appropriate modification
while True:  
    s=[]
    while len(s)<100:
        nextval = int(nx.utils.powerlaw_sequence(1, 2.5)[0]) #100 nodes, power-law exponent 2.5
        if nextval!=0:
            s.append(nextval)
    if sum(s)%2 == 0:
        break
G = nx.configuration_model(s)
G=nx.Graph(G) # remove parallel edges
G.remove_edges_from(G.selfloop_edges())

#draw and show graph
pos = nx.spring_layout(G)
nx.draw_networkx(G, pos)
plt.savefig('test.pdf')

PS:我想出了networkx中expected_degree_graph实现的算法(不是模型,而是实现它的算法)。如果你有空的时间,请仔细阅读。很酷。

答案 1 :(得分:1)

当我遇到类似的问题时,我走出了鸡出路,简单地使用了BA发生器,其中添加了不同数量的链接,用于添加新节点,例如1,...,5。这保证了单个连接组件,没有平行边缘。

由于您需要固定幂律指数,我建议如下:通常,在级联故障中,研究了两种不同类型的拓扑。如果是这种情况,请生成一个&#34;无标度&#34;来自最大连通组件(LCC)的网络,如我的ipython notebook

所示
import networkx as nx
from networkx.utils import (powerlaw_sequence, create_degree_sequence)
sequence = create_degree_sequence(num, powerlaw_sequence, exponent=exp)
graph = nx.configuration_model(sequence, seed=seed)
loops = graph.selfloop_edges()
# remove parallel edges and self-loops
graph = nx.Graph(graph)
graph.remove_edges_from(loops)
# get largest connected component
# unfortunately, the iterator over the components is not guaranteed to be sorted by size
components = sorted(nx.connected_components(graph), key=len, reverse=True)
lcc = graph.subgraph(components[0])

并将节点数量生成ER图形作为连接拓扑,因为LCC中的节点数量比某个边缘概率更可靠。

正如您在链接度分布中所看到的,LCC的拓扑结构仍然是我所考虑的&#34;无标度&#34;。当您考虑几千个节点的网络时,只要您的两个连接的网络具有相同的数量,您的60个网络的节点数量就不会完全相同。

如果你想连接两个&#34;无标度&#34;网络,除了从两个LCC中较大的LCC中删除随机节点之外,我不知道如何做到这一点,直到你得到相同的数字。

告诉我们您是如何解决的。