簡體   English   中英

在循環 networkx python 中查找邊

[英]Find edges in a cycle networkx python

我想制作一個算法來在無向圖中使用 Python 中的 networkx 來查找邊是否屬於一個循環。 我正在考慮使用cycle_basis並獲取圖中的所有循環。 我的問題是cycle_basis返回一個節點列表。 如何將它們轉換為邊緣?

您可以通過連接相鄰節點來構建循環中的邊。

In [1]: import networkx as nx

In [2]: G = nx.Graph()

In [3]: G.add_cycle([1,2,3,4])

In [4]: G.add_cycle([10,20,30])

In [5]: basis = nx.cycle_basis(G)

In [6]: basis
Out[6]: [[2, 3, 4, 1], [20, 30, 10]]

In [7]: edges = [zip(nodes,(nodes[1:]+nodes[:1])) for nodes in basis]

In [8]: edges
Out[8]: [[(2, 3), (3, 4), (4, 1), (1, 2)], [(20, 30), (30, 10), (10, 20)]]

這是我的看法,僅使用 lambda 函數(我喜歡 lambda 函數!):

import networkx as nx

G = nx.Graph()

G.add_cycle([1,2,3,4])

G.add_cycle([10,20,30])

G.add_edge(1,10)


in_path = lambda e, path: (e[0], e[1]) in path or (e[1], e[0]) in path
cycle_to_path = lambda path: list(zip(path+path[:1], path[1:] + path[:1]))
in_a_cycle = lambda e, cycle: in_path(e, cycle_to_path(cycle))
in_any_cycle = lambda e, g: any(in_a_cycle(e, c) for c in nx.cycle_basis(g))

for edge in G.edges():
    print(edge, 'in a cycle:', in_any_cycle(edge, G))

如果你沒有找到一個很好的解決方案,這里有一個丑陋的解決方案。

  1. 使用edges()可以獲得與循環中的節點相鄰的邊列表。 不幸的是,這包括與循環外的節點相鄰的邊
  2. 您現在可以通過刪除那些連接不屬於循環的節點的邊來過濾邊列表。

如果您找到了一個不那么浪費的解決方案,請通知我們。

在 Aric 的幫助下,加上一個檢查兩個方向的小技巧,我終於做到了看起來不錯的事情。

import networkx as nx

G = nx.Graph()

G.add_cycle([1,2,3,4])

G.add_cycle([10,20,30])

G.add_edge(1,10)


def edge_in_cycle(edge, graph):
    u, v = edge
    basis = nx.cycle_basis(graph)
    edges = [zip(nodes,(nodes[1:]+nodes[:1])) for nodes in basis]
    found = False
    for cycle in edges:
        if (u, v) in cycle or (v, u) in cycle:
            found = True            
    return found

for edge in G.edges():
    print edge, 'in a cycle:', edge_in_cycle(edge, G)

輸出:

(1, 2) in a cycle: True
(1, 4) in a cycle: True
(1, 10) in a cycle: False
(2, 3) in a cycle: True
(3, 4) in a cycle: True
(10, 20) in a cycle: True
(10, 30) in a cycle: True
(20, 30) in a cycle: True

您可以使用find_cycle方法直接獲取循環中的邊。 如果你想測試一條邊是否屬於一個循環,你應該檢查它的兩個頂點是否屬於同一個循環。

使用上述答案中的示例:

import networkx as nx

G = nx.Graph()
G.add_cycle([1,2,3,4])
G.add_cycle([10,20,30])
G.add_edge(1,10)
nx.find_cycle(G, 1) # [(1, 2), (2, 3), (3, 4), (4, 1)]
nx.find_cycle(G, 10) # [(10, 20), (20, 30), (30, 10)]

另一方面,邊(2, 3) (或(3, 2)因為你的圖是無向的)是首先定義的循環的一部分:

nx.find_cycle(G, 2) # [(2, 1), (1, 4), (4, 3), (3, 2)]

暫無
暫無

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

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