Python Networkx:在multiDiGraph中查找给定路径的所有边

时间:2017-06-20 09:15:22

标签: python graph networkx edges

在我的多向图中,我想找到2个节点之间可能的所有(简单)路径。我设法获得所有路径,但无法区分源节点到达目标节点所使用的边缘(假设它是multiDiGraph)。

例如,我具有A-> B-> C,其中在(A,B)和(B,C)之间存在多个平行边缘。如果我说A-> B的5个平行边和B-> C的2个平行边,则all_simple_path(图,源=' A',目标=' C&#39 ;)将总共返回7个路径,所有路径当然都是A-> B-> C

使用get_edge_data()时,它返回每个节点之间的所有平行边。但我想要的是能够列出路径中指定节点所采用的所有组合边缘。

谢谢!

2 个答案:

答案 0 :(得分:0)

我认为OP不需要此答案,但对其他人可能有用。

networkx没有内置函数来处理它,因此我们必须手动执行所有操作。 nx.all_simple_paths()返回节点列表,因此对于MultiDiGraph,将有很多重复。因此,我们首先通过将nx.all_simple_paths()输出转换为set来删除它们,然后对其进行迭代。对于每条路径,我们提取节点对(例如:[1,2,3,4] -> [[1,2],[2,3],[3,4]]),对于每对路径,我们得到节点之间所有边的AtlasView。这是该算法的代码:

import networkx as nx
from pprint import pprint

# Create the graph with unique edges to check the algorithm correctness
G = nx.MultiDiGraph()
G.add_edges_from([
    [1,2],
    [1,2],
    [1,2],
    [2,3],
    [2,3],
    [2,3],
    [3,4],
    [3,4],
    [2,4]
])
G.add_edge(1,2,data='WAKA')
G.add_edge(2,3,data='WAKKA')
G.add_edge(2,4,data='WAKA-WAKA')

# Our source and destination nodes
source = 1
destination = 4

# All unique single paths, like in nx.DiGraph
unique_single_paths = set(
    tuple(path)  # Sets can't be used with lists because they are not hashable
    for path in nx.all_simple_paths(G, source, destination)
)

combined_single_paths = []
for path in unique_single_paths:
    # Get all node pairs in path:
    # [1,2,3,4] -> [[1,2],[2,3],[3,4]]
    pairs = [path[i: i + 2] for i in range(len(path)-1)]

    # Construct the combined list for path
    combined_single_paths.append([
        (pair, G[pair[0]][pair[1]])  # Pair and all node between these nodes
        for pair in pairs
    ])
pprint(combined_single_paths)
[[((1, 2), AtlasView({0: {}, 1: {}, 2: {}, 3: {'data': 'WAKA'}})),
  ((2, 3), AtlasView({0: {}, 1: {}, 2: {}, 3: {'data': 'WAKKA'}})),
  ((3, 4), AtlasView({0: {}, 1: {}}))],
 [((1, 2), AtlasView({0: {}, 1: {}, 2: {}, 3: {'data': 'WAKA'}})),
  ((2, 4), AtlasView({0: {}, 1: {'data': 'WAKA-WAKA'}}))]]

答案 1 :(得分:0)

使用“ all_simple_edge_paths”。它将给出边缘的索引。

import networkx as nx

G = nx.MultiDiGraph()
G.add_edge(1, 2, **{'prop1': 'A', 'prop2': 'B'})
G.add_edge(1, 3, **{'prop1': 'A', 'prop2': 'C'})
G.add_edge(2, 3, **{'prop1': 'B', 'prop2': 'C'})
G.add_edge(2, 3, **{'prop1': 'B1', 'prop2': 'C1'})

# Our source and destination nodes
source = 1
destination = 3



paths = nx.all_simple_edge_paths(G, source, destination)

for path in paths:
   print(" Path :: ")
   for edge in path:
       src = edge[0]
       dst = edge[1]
       print(str(src)+ " - "+str(dst)+ " :: "+str(G.get_edge_data(edge[0], edge[1])[edge[2]]))