以下函数返回一个随机生成的大小为nxn
的邻接矩阵,表示图形。
import random
def random_adjacency_matrix(n):
matrix = [[random.randint(0, 1) for i in range(n)] for j in range(n)]
# No vertex connects to itself
for i in range(n):
matrix[i][i] = 0
# If i is connected to j, j is connected to i
for i in range(n):
for j in range(n):
matrix[j][i] = matrix[i][j]
return matrix
这是一个非常天真的解决方案,我希望它满足另外两个要求。
矩阵表示的图形必须完全连接,换句话说,不能有任何节点在某些步骤中无法从任何其他节点到达。
每个节点都有许多边。现在它是完全随机的,因此节点具有多少边缘相当均匀,并且当n
很大时,对于所有图形,平均边缘数也趋于变大。我希望每个节点的平均边数变化更多,与图形的大小无关,因此一些图形的连接很少,而其他图形很多。
编辑: 使用networkx包,这似乎是我想要的,只有上面的第1点也满足:
import networkx, random
G = networkx.binomial_graph(50, random.random()) # 50 nodes, random probability of an edge
答案 0 :(得分:3)
首先,让我们推荐networkx graph library。它非常易于使用,并且已经包含了一个很好的算法工具箱。例如,您可以轻松地测试图表的连通性,或者在图表中询问一组连接的组件。
其次,有各种命名的历史分布是佳能。如果你能找到你正在考虑的那个,这对你和任何提供帮助的人都有帮助。从你给出的粗略描述中,听起来你可能正在寻找幂律分布(又名“长尾”分布,另见“scale free network”)。您在(例如)社交网络中看到了很多类型的分布,在这种情况下,相对较少的非常高度连接的节点(即流行的节点),然后是许多很多具有非常低连接性的节点。在少数高度连接和许多稀疏连接之间,中间存在一种指数衰减。这似乎是描述随机生成的社交网络的论文:Random Graph Models of Social Networks。
鉴于networkx和适当的统计分布,您应该能够构建您梦想的图表。祝你的项目好运,编码愉快。
答案 1 :(得分:2)
没有足够的信息来完全指定您想要的图表类型。然而,由于图形通常是某些物理结构的抽象,因此对随机图形的常见请求是无标度。这些图具有渐近地遵循幂律的度分布的性质。人口动态,Facebook朋友,引文网络和互联网流量都对某些领域具有幂律依赖性。生成无标度网络的通用方法是Barabási–Albert method。下面(来自维基百科)转载的是创建这样一个网络的动画。保证连接任何N,并且通用允许您设置连接。
networkx
可以轻松生成这些随机图:
import networkx
node_number = 20
initial_nodes = 2
G = networkx.barabasi_albert_graph(node_number, initial_nodes)
答案 2 :(得分:1)
问题1:
首先创建一个随机的spaning树,将所有节点连接在一起,然后添加其他边。
问题2:
为(i,j)
创建所有1 ≤ i < j ≤ n
的列表,随机播放列表并获取前k个边缘。然后,您的图表会有n
个顶点和k±n
个边。
答案 3 :(得分:1)
(1)这个很简单 - 只需首先创建一个树,并且只有在确保连接后才开始添加更多边缘。
通过迭代地增加一组连接的顶点,可以很容易地完成。
伪码:
source <- select random vertex
set <- {source}
while set != V:
chose a random vertex v from set, and u from V\set
add (v,u),(u,v) as an edge
add u to set
(2)
我使用normal distribution选择每个节点的边数。每个节点将获得一个不同的随机变量 - 因此将具有不同数量的节点。