如何从未连接的图形中随机选择两个节点(节点对),Python,networkx

时间:2012-06-07 09:38:06

标签: python nodes networkx

我想从图中提取两个节点,因为它们不应该被连接,即它们之间不存在直接边缘。我知道我可以使用“random.choice(g.edges())获得随机边缘”,但这会给我连接的随机节点。我想要一对未连接的节点(一对未连接的边)。帮帮我们......伙计们

4 个答案:

答案 0 :(得分:10)

简单! :)

抓取一个随机节点 - 然后从排除邻居及其自身的节点列表中选择一个随机节点。代码说明如下。 :)

import networkx as nx
from random import choice

# Consider this graph
#
#     3
#     |
# 2 - 1 - 5 - 6
#     | 
#     4

g = nx.Graph()
g.add_edge(1,2)
g.add_edge(1,3)
g.add_edge(1,4)
g.add_edge(1,5)
g.add_edge(5,6)

first_node = choice(g.nodes())                  # pick a random node
possible_nodes = set(g.nodes())
neighbours = g.neighbors(first_node) + [first_node]
possible_nodes.difference_update(neighbours)    # remove the first node and all its neighbours from the candidates
second_node = choice(list(possible_nodes))      # pick second node      

print first_node, second_node

答案 1 :(得分:3)

到目前为止,这里提出的解决方案都不会均匀地对非边缘(v1,v2)进行采样。考虑具有4个节点和2个边的示例图:

1 —— 2
|
3    4

有4种非边缘可供选择:(1,4),(2,3),(2,4),(3,4)。使用玛丽亚或菲利普的方法从所有4个顶点中随机选择第一个顶点,然后从受限制的顶点集中选择第二个顶点,以便不创建任何边(或自循环)为每个要选择的非边缘提供以下概率:

p(1,4)= 1/4 * 1 + 1/4 * 1/3 = 8/24

p(2,3)= 1/4 * 1/2 + 1/4 * 1/2 = 6/24

p(3,4)= p(2,4)= 1/4 * 1/2 + 1/4 * 1/3 = 5/24

所以程序不统一。

这意味着如果您想要均匀采样的非边缘,则必须选择两个不受限制的顶点,并在它们形成现有边(或相等)时拒绝样本(两个顶点)。在NetworkX中:

v1 = np.random.choice(G.nodes())
v2 = np.random.choice(G.nodes())

while G.has(edge(v1,v2)) or v1==v2:
  v1 = np.random.choice(G.nodes())
  v2 = np.random.choice(G.nodes())

答案 2 :(得分:1)

我不知道那个库,但我猜你可以做到以下几点:

  n1 = random.choice(g.nodes())
  n2 = random.choice(g.nodes()) 
  while (n1 == n2 or any of the edges of n1 lead to n2):
    n2 = random.choice(g.nodes())
  enjoy(yourNodes)

干杯

答案 3 :(得分:0)

如果图表很小,您可以将nx.non_edges()收集到np.arrayrandom.choice中:

non_edges = np.array(nx.non_edges(graph))

sample_num = 10000
sample = non_edges[np.random.choice(len(non_edges), sample_num, replace=False)]

请注意non_edges()本身会返回生成器,而不是实际列表。但是如果你把它变成np.array,你就会收集生成器中的所有物品。如果你的图形很大且稀疏,这可能会引起内存错误,但对于小图形,这将是最直接的方法。