簡體   English   中英

圖中的K階鄰居 - Python networkx

[英]K-th order neighbors in graph - Python networkx

我有一個有向圖,我想有效地找到一個節點的所有K階鄰居的列表。 K階鄰居被定義為可以從所討論的節點以恰好 K跳躍到達的所有節點。

我查看了networkx ,唯一相關的功能是neighbors 但是,這只返回1個鄰居的順序。 對於更高階,我們需要迭代以確定完整集。 我相信應該有一種更有效的方式來訪問networkx K階鄰居。

是否有一個有效地返回K階鄰居的函數,而不是逐步構建集合?

編輯:如果在Python中存在其他可能有用的圖形庫,請提及這些。

您可以使用: nx.single_source_shortest_path_length(G, node, cutoff=K)

其中G是你的圖形對象。

對於NetworkX,最好的方法可能是在每個k上構建一組鄰居。 你沒有發布你的代碼,但似乎你可能已經這樣做了:

import networkx as nx

def knbrs(G, start, k):
    nbrs = set([start])
    for l in range(k):
        nbrs = set((nbr for n in nbrs for nbr in G[n]))
    return nbrs

if __name__ == '__main__':
    G = nx.gnp_random_graph(50,0.1,directed=True)
    print(knbrs(G, 0, 3))

您可以使用修改后的BFS算法解決問題。 當您將節點存儲在隊列中時,也存儲它的級別(與根的距離)。 處理完節點(所有訪問的鄰居 - 節點標記為黑色)后,您可以將其添加到其級別的節點列表中。 以下是基於這個簡單實現的示例:

#!/usr/bin/python
# -*- coding: utf-8 -*-

from collections import defaultdict 
from collections import deque

kth_step = defaultdict(list)

class BFS:
    def __init__(self, node,edges, source):
        self.node = node
        self.edges = edges
        self.source = source
        self.color=['W' for i in range(0,node)] # W for White
        self.graph =color=[[False for i in range(0,node)] for j in range(0,node)]
        self.queue = deque()

        # Start BFS algorithm
        self.construct_graph()
        self.bfs_traversal()

    def construct_graph(self):
        for u,v in self.edges:
            self.graph[u][v], self.graph[v][u] = True, True

    def bfs_traversal(self):
        self.queue.append((self.source, 1))
        self.color[self.source] = 'B' # B for Black
        kth_step[0].append(self.source)

        while len(self.queue):
            u, level =  self.queue.popleft()
            if level > 5: # limit searching there
                return
            for v in range(0, self.node):
                if self.graph[u][v] == True and self.color[v]=='W':
                    self.color[v]='B'
                    kth_step[level].append(v)
                    self.queue.append((v, level+1))

'''
0 -- 1---7
|    |
|    |
2----3---5---6
|
|
4

'''


node = 8 # 8 nodes from 0 to 7
edges =[(0,1),(1,7),(0,2),(1,3),(2,3),(3,5),(5,6),(2,4)] # bi-directional edge
source = 0 # set fist node (0) as source

bfs = BFS(node, edges, source)


for key, value in kth_step.items():
    print key, value

輸出:

$ python test.py
0 [0]
1 [1, 2]
2 [3, 7, 4]
3 [5]
4 [6]

我不知道networkx ,我也沒有准備好在Graph Tool中使用算法。 我相信這樣的問題不足以擁有自己的功能。 此外,我認為在圖形實例中為任何節點存儲第k個鄰居列表會過於復雜,效率低下且冗余,因此無論如何這樣的函數可能必須迭代節點。

我有一個類似的問題,除了我有一個有向圖,我需要維護邊屬性字典。 如果需要,這種相互遞歸解決方案可以保留邊緣屬性字典

def neighbors_n(G, root, n):
    E = nx.DiGraph()

    def n_tree(tree, n_remain):
        neighbors_dict = G[tree]

        for neighbor, relations in neighbors_dict.iteritems():
          E.add_edge(tree, neighbor, rel=relations['rel'])

        #you can use this map if you want to retain functional purity
        #map(lambda neigh_rel: E.add_edge(tree, neigh_rel[0], rel=neigh_rel[1]['rel']), neighbors_dict.iteritems() )

        neighbors = list(neighbors_dict.iterkeys())
        n_forest(neighbors, n_remain= (n_remain - 1))

    def n_forest(forest, n_remain):
        if n_remain <= 0:
            return
        else:
            map(lambda tree: n_tree(tree, n_remain=n_remain), forest)

    n_forest( [root] , n)

    return E

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM