考虑到您有一个只有 10 条边的 {5, 6} 二分图,您的图很可能会断开连接(它非常稀疏,您甚至很有可能有孤立的节点)。
import networkx as nx
import random
random.seed(0)
B = nx.bipartite.gnmk_random_graph(5,6,10)
isolated_nodes = set(B.nodes())
for (u, v) in B.edges():
isolated_nodes -= {u}
isolated_nodes -= {v}
print(isolated_nodes)
将显示 id=1 的节点是孤立的。要使图形连接,您可以做的就是只保留其最大的连接组件:
import networkx as nx
import random
random.seed(0)
B = nx.bipartite.gnmk_random_graph(5,6,11)
components = sorted(nx.connected_components(B), key=len, reverse=True)
largest_component = components[0]
C = B.subgraph(largest_component)
这里只会删除节点 1(一个孤立的节点)。
现在唯一的问题是“这个新图表有多随机”。换句话说,它是否在具有 5-6 个节点和 10 条边的随机连接二分图中以相等的概率选择任何图。现在我不确定,但我认为它看起来不错。
当然你的建议(选择一个图表直到它连接)是可以的,但它可能很昂贵(当然取决于 3 个参数)。
编辑我很笨,这不行,因为新图没有正确数量的节点/边。但是应该有一个更好的解决方案,而不是重试直到你得到一个好的图表。嗯,这很有趣......
第二次编辑也许这个answer可以帮助找到解决这个问题的好方法。
第三次修改和建议
正如您在我链接的问题中注意到的那样,接受的答案并不是真正正确的,因为生成的图表不是在预期图表集中随机均匀选择的。我们可以在这里做一些类似的事情来获得第一个体面的解决方案。这个想法是首先通过迭代挑选孤立节点并将它们连接到二分图的另一侧来创建具有最少边数的连通二分图。为此,我们将创建两个集合N 和M,创建从N 到M 的第一条边。然后我们将选择一个随机隔离节点(来自N 或M)并将其连接到另一侧的随机非隔离节点。一旦我们不再有任何孤立节点,我们将恰好有 n+m-1 条边,因此我们需要向图中添加 k-(n+m-1) 条额外边以匹配原始约束。
这是该算法对应的代码
import networkx as nx
import random
random.seed(0)
def biased_random_connected_bipartite(n, m, k):
G = nx.Graph()
# These will be the two components of the bipartite graph
N = set(range(n))
M = set(range(n, n+m))
G.add_nodes_from(N)
G.add_nodes_from(M)
# Create a first random edge
u = random.choice(tuple(N))
v = random.choice(tuple(M))
G.add_edge(u, v)
isolated_N = set(N-{u})
isolated_M = set(M-{v})
while isolated_N and isolated_M:
# Pick any isolated node:
isolated_nodes = isolated_N|isolated_M
u = random.choice(tuple(isolated_nodes))
# And connected it to the existing connected graph:
if u in isolated_N:
v = random.choice(tuple(M-isolated_M))
G.add_edge(u, v)
isolated_N.remove(u)
else:
v = random.choice(tuple(N-isolated_N))
G.add_edge(u, v)
isolated_M.remove(u)
# Add missing edges
for i in range(k-len(G.edges())):
u = random.choice(tuple(N))
v = random.choice(tuple(M))
G.add_edge(u, v)
return G
B = biased_random_connected_bipartite(5, 6, 11)
但我再说一遍,这个图并不是在所有可能的二分图的集合中随机均匀选择的(我们在 n、m 和 k 上定义了约束)。正如我在另一篇文章中所说的那样,这个图表往往会有一些节点的度数高于其他节点。这是因为我们将孤立的节点与连接的组件一一连接,因此在此过程中较早添加的节点将倾向于吸引更多的节点(优先附加)。我问了question on cstheory,看看有没有什么好主意。
edit 我添加了另一种解决方案,而不是这里介绍的解决方案,它稍微好一点,但仍然不是一个好的解决方案。