关于python:生成具有一定程度分布的图?

Generating a graph with certain degree distribution?

我正在尝试生成一个具有小世界性质(显示幂定律分布)的随机图。我刚开始使用networkx包,发现它提供了多种随机图生成方法。有人可以告诉我是否可以生成一个图形,其中给定节点的度遵循伽马分布(在R中或使用python \\ networkx软件包)?


如果要使用配置模型,则应在NetworkX中使用以下方法:

1
2
3
4
import random
import networkx as nx
z=[int(random.gammavariate(alpha=9.0,beta=2.0)) for i in range(100)]
G=nx.configuration_model(z)

您可能需要根据伽马分布中的参数调整序列z的平均值。另外z不需要是图形的(您将获得多图),但是它确实需要一个偶数和,因此您可能必须尝试一些随机序列(或加1)...

有关configuration_model的NetworkX文档注释给出了另一个示例,参考以及如何删除平行边和自循环:

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
Notes
-----
As described by Newman [1]_.

A non-graphical degree sequence (not realizable by some simple
graph) is allowed since this function returns graphs with self
loops and parallel edges.  An exception is raised if the degree
sequence does not have an even sum.

This configuration model construction process can lead to
duplicate edges and loops.  You can remove the self-loops and
parallel edges (see below) which will likely result in a graph
that doesn't have the exact degree sequence specified.  This
"finite-size effect" decreases as the size of the graph increases.

References
----------
.. [1] M.E.J. Newman,"The structure and function
       of complex networks", SIAM REVIEW 45-2, pp 167-256, 2003.

Examples
--------
>>> from networkx.utils import powerlaw_sequence
>>> z=nx.create_degree_sequence(100,powerlaw_sequence)
>>> G=nx.configuration_model(z)

To remove parallel edges:

>>> G=nx.Graph(G)

To remove self loops:

>>> G.remove_edges_from(G.selfloop_edges())

这里的示例类似于http://networkx.lanl.gov/examples/drawing/degree_histogram.html上的示例,该示例绘制的图形包括最大连接组件的图形布局:

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
#!/usr/bin/env python
import random
import matplotlib.pyplot as plt
import networkx as nx

def seq(n):
    return [random.gammavariate(alpha=2.0,beta=1.0) for i in range(100)]    
z=nx.create_degree_sequence(100,seq)
nx.is_valid_degree_sequence(z)
G=nx.configuration_model(z)  # configuration model

degree_sequence=sorted(nx.degree(G).values(),reverse=True) # degree sequence
print"Degree sequence", degree_sequence
dmax=max(degree_sequence)

plt.hist(degree_sequence,bins=dmax)
plt.title("Degree histogram")
plt.ylabel("count")
plt.xlabel("degree")

# draw graph in inset
plt.axes([0.45,0.45,0.45,0.45])
Gcc=nx.connected_component_subgraphs(G)[0]
pos=nx.spring_layout(Gcc)
plt.axis('off')
nx.draw_networkx_nodes(Gcc,pos,node_size=20)
nx.draw_networkx_edges(Gcc,pos,alpha=0.4)

plt.savefig("degree_histogram.png")
plt.show()


前一段时间我是在基本的Python中执行此操作的... IIRC,我使用了以下方法。从内存来看,这可能并不完全准确,但是希望它值得:

  • 选择图中的节点数N和密度(可能的边上的现有边)D。这表示边数E。
  • 对于每个节点,通过首先选择一个随机正数x并找到P(x)来分配其度,其中P是您的pdf。节点的度数为(P(x)* E / 2)-1。
  • 随机选择一个节点,然后将其连接到另一个随机节点。如果任一节点已实现其分配的程度,则从进一步选择中将其消除。重复E次。
  • 通常这不会创建连接图。


    我知道这已经很晚了,但是您可以使用mathematica来做同样的事情,尽管更加简单。

    RandomGraph [DegreeGraphDistribution [{3,3,3,3,3,3,3,3}],4]

    这将生成4个随机图,每个节点具有指定的度数。


    包括上述内容,networkx提供了4种算法来接收度分布作为输入:

    • configuration_model:用@eric解释
    • Expected_degree_graph:根据每个节点的期望程度使用概率方法。它不会给您确切的度数,而是一个近似值。
    • havel_hakimi_graph:该节点首先尝试连接度最高的节点
    • random_degree_sequence_graph:据我所知,这类似于@JonC建议的内容;它具有trials参数,因为不能保证找到合适的配置。

    完整列表(包括有向图算法的某些版本)在这里。

    我还发现了几篇论文:

    • 给定任意度数序列的简单图的有效且精确的采样
    • 生成指定度随机图的顺序重要性抽样算法