[英]Finding all paths/walks of given length in a networkx graph
最簡單的版本(另一個版本低於我認為更快):
def findPaths(G,u,n):
if n==0:
return [[u]]
paths = [[u]+path for neighbor in G.neighbors(u) for path in findPaths(G,neighbor,n-1) if u not in path]
return paths
這需要網絡G
和節點u
以及長度n
。 它遞歸地找到從u
鄰居開始的所有長度為n-1的路徑,這些路徑不包括u
。 然后它附着u
在每個這樣的路徑的前部和返回這些路徑的列表。
注意,每個路徑都是有序列表。 它們都從指定的節點開始。 所以對於你想要的,只需繞一個循環:
allpaths = []
for node in G:
allpaths.extend(findPaths(G,node,3))
請注意,這將具有任何abcd
路徑以及反向dcba
路徑。
如果您發現“列表理解”是一個需要解釋的挑戰,這里有一個等價的選項:
def findPathsNoLC(G,u,n):
if n==0:
return [[u]]
paths = []
for neighbor in G.neighbors(u):
for path in findPathsNoLC(G,neighbor,n-1):
if u not in path:
paths.append([u]+path)
return paths
為了優化這一點,特別是如果有很多周期,可能值得在一組不允許的節點中發送。 在每次嵌套調用時,它都知道在遞歸中不包括更高級別的任何節點。 if u not in path
檢查中,這將起作用。 代碼將更難理解,但它會運行得更快。
def findPaths2(G,u,n,excludeSet = None):
if excludeSet == None:
excludeSet = set([u])
else:
excludeSet.add(u)
if n==0:
return [[u]]
paths = [[u]+path for neighbor in G.neighbors(u) if neighbor not in excludeSet for path in findPaths2(G,neighbor,n-1,excludeSet)]
excludeSet.remove(u)
return paths
請注意,我要補充u
到excludeSet
遞歸調用之前,然后再返回之前將其刪除。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.