Python 如何使用Networkx创建每个节点至少有一条边的随机图

Python 如何使用Networkx创建每个节点至少有一条边的随机图,python,networkx,graph-theory,weighted-graph,Python,Networkx,Graph Theory,Weighted Graph,我已经设法创建了一个随机无向加权图,用Dijkstra的算法进行测试,但是如何使每个节点至少有一条边将它们连接到图上呢 我正在使用Networkx,我的图形生成器如下所示: import networkx as nx import random random.seed() nodes = random.randint(5,10) seed = random.randint(1,10) probability = random.random() G = nx.gnp_random_graph(n

我已经设法创建了一个随机无向加权图,用Dijkstra的算法进行测试,但是如何使每个节点至少有一条边将它们连接到图上呢

我正在使用Networkx,我的图形生成器如下所示:

import networkx as nx
import random

random.seed()
nodes = random.randint(5,10)
seed = random.randint(1,10)
probability = random.random()
G = nx.gnp_random_graph(nodes,probability,seed, False)
for (u, v) in G.edges():
    G.edges[u,v]['weight'] = random.randint(0,10)

这很好地创建了图形,我成功地绘制了它,所以我可以看到它,我的问题是创建边的概率。我不希望它太高,以至于所有节点都有最大数量的边,但如果设置较低的值,则会导致节点的边数为0。有没有办法确保每个节点至少有一条边?

似乎没有办法直接生成满足此类要求的图形

但是,您可以稍微调整中使用的方法,这样,我们就不用以随机概率在所有可能的边组合中设置边,而是为每个节点随机添加一条边,然后以概率
p
添加其余边

下面的方法不仅生成一个每个节点至少有一条边的图,而且还生成一条边。下面将在进一步的注释中对此进行解释-


进一步说明-

上述方法不仅确保每个节点至少有一条边,而且如上所述,结果图是连通的。这是因为我们正在使用
itertools.combinations(范围(n_节点),2)
的结果为每个节点设置至少一条边。举例来说,这可能更清楚:

edges = combinations(range(5), 2)
for _, node_edges in groupby(edges, key=lambda x: x[0]):
    print(list(node_edges))

#[(0, 1), (0, 2), (0, 3), (0, 4)]
#[(1, 2), (1, 3), (1, 4)]
#[(2, 3), (2, 4)]
#[(3, 4)]
在这种情况下,我们在每种情况下至少设置一条边,从每次迭代的可用边中选择一个
random.choice
,这些边是尚未设置的边。这是使用
itertools.compositions
的结果设置边的结果。对于无向图,如果以前已经以概率
p
添加了所有现有边,则在每次迭代时迭代所有现有边是没有意义的


这不是采用
排列的情况
(请参阅源代码以了解详细信息)。在有向图的情况下,这种方法无法保证连通性,因为可能有两个节点由两条方向相反的边连接,并且与图的其余部分隔离。因此,应该遵循另一种方法(可能是扩展上述想法)。

似乎没有直接生成满足此类要求的图形的方法

但是,您可以稍微调整中使用的方法,这样,我们就不用以随机概率在所有可能的边组合中设置边,而是为每个节点随机添加一条边,然后以概率
p
添加其余边

下面的方法不仅生成一个每个节点至少有一条边的图,而且还生成一条边。下面将在进一步的注释中对此进行解释-


进一步说明-

上述方法不仅确保每个节点至少有一条边,而且如上所述,结果图是连通的。这是因为我们正在使用
itertools.combinations(范围(n_节点),2)
的结果为每个节点设置至少一条边。举例来说,这可能更清楚:

edges = combinations(range(5), 2)
for _, node_edges in groupby(edges, key=lambda x: x[0]):
    print(list(node_edges))

#[(0, 1), (0, 2), (0, 3), (0, 4)]
#[(1, 2), (1, 3), (1, 4)]
#[(2, 3), (2, 4)]
#[(3, 4)]
在这种情况下,我们在每种情况下至少设置一条边,从每次迭代的可用边中选择一个
random.choice
,这些边是尚未设置的边。这是使用
itertools.compositions
的结果设置边的结果。对于无向图,如果以前已经以概率
p
添加了所有现有边,则在每次迭代时迭代所有现有边是没有意义的


这不是采用
排列的情况
(请参阅源代码以了解详细信息)。在有向图的情况下,这种方法无法保证连通性,因为可能有两个节点由两条方向相反的边连接,并且与图的其余部分隔离。因此,应该遵循另一种方法(也许是扩展上述想法)。

非常感谢!!我也很感谢你的解释!非常感谢,有没有办法在networkx文档中宣传这一点?非常感谢!!我也很感谢你的解释!感谢您的支持,有没有办法在networkx文档中宣传这一点?
nodes = 40
seed = random.randint(1,10)
probability = 0.001
G = gnp_random_connected_graph(nodes,probability)

plt.figure(figsize=(10,6))

nx.draw(G, node_color='lightblue', 
        with_labels=True, 
        node_size=500)
edges = combinations(range(5), 2)
for _, node_edges in groupby(edges, key=lambda x: x[0]):
    print(list(node_edges))

#[(0, 1), (0, 2), (0, 3), (0, 4)]
#[(1, 2), (1, 3), (1, 4)]
#[(2, 3), (2, 4)]
#[(3, 4)]