找到节点的n度邻域

时间:2014-03-30 10:15:46

标签: python algorithm graph-algorithm networkx

我是networkx的新手,实际上对如何有效地找到节点的n度邻域有点困惑。节点v_i的n度邻域是与v_i完全相距n跳的节点集。给定指定的n,我需要找到图/网络中每个节点的n度邻域。

假设我有以下图表,我想找到节点v1的n = 1邻域。那将是v2和v3。接下来假设我想找到节点v1的n = 2邻域,那么那将是v4。

enter image description here

5 个答案:

答案 0 :(得分:7)

import networkx as nx
G = nx.Graph()
G.add_edges_from([('v1','v2'),('v2','v4'),('v1','v3')])

def neighborhood(G, node, n):
    path_lengths = nx.single_source_dijkstra_path_length(G, node)
    return [node for node, length in path_lengths.iteritems()
                    if length == n]

print(neighborhood(G, 'v1', 1))
# ['v2', 'v3']
print(neighborhood(G, 'v1', 2))
# ['v4']

答案 1 :(得分:1)

查找给定节点的n个邻居的最有效方法是使用深度优先搜索: http://en.wikipedia.org/wiki/Depth-first_search。以下函数返回所有距离的起始邻居。但是,如果需要为所有节点找到n个邻居,则对所有节点使用此函数将不是最有效的解决方案。相反,可以将此函数仅用于每个连接组件中的起始节点,并计算相对于起点的其他节点的n个邻居,但这将更加复杂。

import networkx as nx

def n_neighbor(G, start):

    #  {distance : [list of nodes at that distance]}
    distance_nodes = {}

    # nodes at distance 1 from the currently visited ones
    next_shell = G.neighbors(start)

    # set of all visited nodes
    visited=set()
    visited.add(start)

    # how fare we are from start
    distance = 0

    # until we run out of nodes
    while len(next_shell) > 0:

        # this will be the next shell
        shell_after_this = []

        # update distance
        distance += 1
        distance_nodes[distance] = []

        # update visited and distance_nodes
        for node in next_shell:
            visited.add(node)
            distance_nodes[distance].append(node)


        # compute shell_after_this
        for node in next_shell:
            # add neighbors to shell_after_this
            # if they have not been visited already
            for neighbor in G.neighbors(node):
                if neighbor not in visited:
                    shell_after_this.append(neighbor)

        # we repeat with the new_shell
        next_shell = set(shell_after_this)

    return distance_nodes


# example 
G=nx.Graph()

G.add_edge(1,2)
G.add_edge(1,3)
G.add_edge(2,3)
G.add_edge(2,4)
G.add_edge(3,5)
G.add_edge(5,17)
G.add_edge(2,6)

print n_neighbor(G, 1)    

答案 2 :(得分:1)

nx.descendants_at_distance() 可以解决问题(虽然是为有向图设计的):

G = nx.Graph()
G.add_edges_from([('v1', 'v2'), ('v2', 'v4'), ('v2', 'v4'), ('v1', 'v3')])
nx.descendants_at_distance(G, 'v1', distance=2) # returns {'v4'}

来自source code comment

This is basically BFS, except that the queue only stores the 
nodes at `current_distance` from source at each iteration.

答案 3 :(得分:0)

当您在图表上执行广度优先搜索时,从根节点r开始 - 认为节点距离r的距离越来越远。

因此,您只需在执行BFS时跟踪节点级别,请参阅http://en.wikipedia.org/wiki/Level_structure以进行更全面的讨论。

答案 4 :(得分:0)

使用Adj矩阵查找n跳邻居

import networkx as nx
 
G = nx.Graph()
G.add_edges_from([('v1','v2'),('v2','v4'),('v1','v3')])

def n_neighbor(G, id, n_hop):
    node = [id]
    node_visited = set()
    neighbors= []
    
    while n_hop !=0:
        neighbors= []
        for node_id in node:
            node_visited.add(node_id)
            neighbors +=  [id for id in G.neighbors(node_id) if id not in node_visited]
        node = neighbors
        n_hop -=1
        
        if len(node) == 0 :
            return neighbors 
        
    return neighbors

print(n_neighbor(G, 'v2', 1))

功能

  1. G:Networkx图
  2. id:找到邻居的根节点ID
  3. n_hop:跃点长度

返回:

  1. 邻居列表

输出:

  • print(n_neighbor(G,'v2',1))

    ['v1','v4']