如何在networkx中找到图的所有连通子图?

时间:2019-01-30 12:34:20

标签: python networkx

我正在开发python应用程序,并且我想列出所有可能的连接子图,无论大小如何,并使用NetworkX从每个节点开始。

我只是尝试使用itertools库中的Combines()来找到所有可能的节点组合,但是它太慢了,因为它还会搜索未连接的节点:

for r in range(0,NumberOfNodes)
for SG in (G.subgraph(s) for s in combinations(G,r):
    if (nx.is_connected(SG)):
        nx.draw(SG,with_labels=True)
        plt.show()

实际输出正确。但是我需要另一种更快的方法来执行此操作,因为具有50个节点的图形和8个作为LenghtTupleToFind的节点的所有节点组合都高达10亿(n!/ r!/(nr)!),但其中只有一小部分是相连的子图也是我感兴趣的。所以,可能有一个功能可以做到这一点?

对不起,我的英文,谢谢你

编辑

这是一个示例:

example of starting graph

所以,我想要的结果是

[0]
[0,1]
[0,2]
[0,3]
[0,1,4]
[0,2,5]
[0,2,5,4]
[0,1,4,5]
[0,1,2,4,5]
[0,1,2,3]
[0,1,2,3,5]
[0,1,2,3,4]
[0,1,2,3,4,5]
[0,3,2]
[0,3,1]
[0,3,2]
[0,1,4,2]

以及所有生成关联图的组合

3 个答案:

答案 0 :(得分:0)

您可以在O(n)时间和内存复杂度中找到所有连接的组件。保留可见的布尔数组,然后运行深度优先搜索(DFS)或面包优先搜索(BFS),以找到连接的组件。
在我的代码中,我使用DFS查找连接的组件。

seen = [False] * num_nodes
def search(node):
    component.append(node)
    seen[node] = True
    for neigh in G.neighbors(node):
        if not seen[neigh]:
            dfs(neigh)

all_subgraphs = []    

# Assuming nodes are numbered 0, 1, ..., num_nodes - 1
for node in range(num_nodes):
    component = []
    dfs(node)
    # Here `component` contains nodes in a connected component of G
    plot_graph(component)  # or do anything
    all_subgraphs.append(component)

答案 1 :(得分:0)

我有相同的要求,最终使用了这段代码,非常接近您的工作。这段代码可以准确地产生您要求的输入。

import networkx as nx
import itertools

G = you_graph
all_connected_subgraphs = []

# here we ask for all connected subgraphs that have at least 2 nodes AND have less nodes than the input graph
for nb_nodes in range(2, G.number_of_nodes()):
    for SG in (G.subgraph(selected_nodes) for selected_nodes in itertools.combinations(G, nb_nodes)):
        if nx.is_connected(SG):
            print(SG.nodes)
            all_connected_subgraphs.append(SG)

答案 2 :(得分:0)

我通过使用自我图修改了 Charly Empereur-mot 的答案以使其更快:

import networkx as nx
import itertools

G = you_graph.copy()
all_connected_subgraphs = []

# here we ask for all connected subgraphs that have nb_nodes
for n in you_graph.nodes():
    egoG = nx.generators.ego_graph(G,n,radius=nb_nodes-1)
    for SG in (G.subgraph(sn+(n,) for sn in itertools.combinations(egoG, nb_nodes-1)):
        if nx.is_connected(SG):
            all_connected_subgraphs.append(SG)
    G.remove_node(n)