Python 获取NetworkX图形中的连接节点

Python 获取NetworkX图形中的连接节点,python,graph,networkx,Python,Graph,Networkx,直截了当的问题:我想检索NetworkX图中连接到给定节点的所有节点,以便创建子图。在下面的示例中,我只想提取圆内的所有节点,给定其中一个节点的名称 我尝试了下面的递归函数,但是达到了Python的递归限制,即使这个网络中只有91个节点 不管下面的代码是否有缺陷,我想实现的最好方法是什么?我将在各种大小的图上运行这段代码,并且事先不知道最大递归深度是多少 def fetch_connected_nodes(node, neighbors_list): for neighbor in a

直截了当的问题:我想检索NetworkX图中连接到给定节点的所有节点,以便创建子图。在下面的示例中,我只想提取圆内的所有节点,给定其中一个节点的名称

我尝试了下面的递归函数,但是达到了Python的递归限制,即使这个网络中只有91个节点

不管下面的代码是否有缺陷,我想实现的最好方法是什么?我将在各种大小的图上运行这段代码,并且事先不知道最大递归深度是多少

def fetch_connected_nodes(node, neighbors_list):
    for neighbor in assembly.neighbors(node):
        print(neighbor)
        if len(assembly.neighbors(neighbor)) == 1:
            neighbors_list.append(neighbor)
            return neighbors_list
        else:
            neighbors_list.append(neighbor)
            fetch_connected_nodes(neighbor, neighbors_list)

neighbors = []
starting_node = 'NODE_1_length_6578_cov_450.665_ID_16281'
connected_nodes = fetch_connected_nodes(starting_node, neighbors)

您可以简单地从给定节点或任何节点开始使用广度优先搜索

在Networkx中,可以使用以下函数从起始节点生成树形图:

bfs_tree(G, source, reverse=False)

这里是指向文档的链接:。

这里是一个递归算法,用于将所有节点连接到输入节点

def create_subgraph(G,sub_G,start_node):
sub_G.add_node(start_node)
for n in G.neighbors_iter(start_node):
    if n not in sub_G.neighbors(start_node):
        sub_G.add_path([start_node,n])
        create_subgraph(G,sub_G,n)
我相信这里防止无限递归调用的关键是检查原始图中的邻居节点在正在创建的子图中是否尚未连接的条件。否则,您将始终在已具有边的节点之间来回移动边

我对它进行了如下测试:

G = nx.erdos_renyi_graph(20,0.08)
nx.draw(G,with_labels = True)
plt.show()
sub_G = nx.Graph()
create_subgraph(G,sub_G,17)
nx.draw(sub_G,with_labels = True)
plt.show()

您将在所附的图像中找到包含节点17的完整图形和子图形。

假设该图形是无向的,则有一个内置的networkx命令:

node_connected_component(G, n)
文件是。它返回
G
的连接组件中包含
n
的所有节点

它不是递归的,但我认为你实际上不需要,甚至不想要


对代码的注释:您有一个bug,它通常会导致无限递归。如果
u
v
都是度至少为2的邻居,则它将从
u
开始,将
v
放入列表,并在处理
v
时将
u
放入列表并不断重复。它需要更改为仅处理不在
邻居\u列表中的邻居。检查这一点很昂贵,因此请使用一套。如果起始节点的阶数为1,则也存在一个小问题。你的一级考试不符合你的要求。如果初始节点的阶数为1,但其邻居的阶数较高,则不会找到邻居的邻居

下面是对您的代码的修改:

def fetch_connected_nodes(G, node, seen = None):
    if seen == None:
        seen = set([node])
    for neighbor in G.neighbors(node):
        print(neighbor)
        if neighbor not in seen:
            seen.add(neighbor)
            fetch_connected_nodes(G, neighbor, seen)
    return seen

您将其称为
fetch\u connected\u node(assembly,start\u node)

这是一个有向图吗?还是非定向的?@AbdallahSobehy是无定向的,尽管我所处理的数据是否是定向的还存在争议。极好的答案。我原以为会有一个networkx函数来完成这项工作,但没能找到它——谢谢!我的代码中的错误似乎非常明显。谢谢你,Kikhos。类似地,我也认为
[v代表u,v在nx中。bfs_边(G,source)]
会根据需要给我一个节点列表。这是一个很好的答案,它教会了算法,而不是像@Joel那样使用内置库函数。非常感谢。