在图中找到N条最短路径

时间:2019-06-05 07:53:03

标签: python networkx

我需要找到两个节点之间的最短路径N。 例如,以下代码创建三个节点和四个边缘,两个最短路径为(1, 3) and (1, 2, 3)

import networkx as nx

G = nx.MultiDiGraph()
G.add_edge(1, 2, **{'weight': 15, 'max': 3})
G.add_edge(1, 3, **{'weight': 30, 'max': 4})
G.add_edge(2, 3, **{'weight': 20, 'max': 3})
G.add_edge(2, 3, **{'weight': 20, 'max': 5})

NetworkX中是否有找到它们的方法?

我知道方法nx.all_shortest_paths(rete,1, 3, weight='weight'),但是在这种情况下,该方法仅返回 最短路径(1,3)。

谢谢!

1 个答案:

答案 0 :(得分:1)

从文档中看来,您可以使用shortest_simple_paths从最短路径开始生成两个顶点之间的所有简单路径:

https://networkx.github.io/documentation/stable/reference/algorithms/generated/networkx.algorithms.simple_paths.shortest_simple_paths.html#

编辑:多图的答案

这是一种非常原始的解决方案,可以得到您想要的答案。我认为这仅适用于小型图:

G = nx.MultiDiGraph()
G.add_edge(1, 2, **{'weight': 15, 'max': 3})
G.add_edge(1, 3, **{'weight': 30, 'max': 4})
G.add_edge(2, 3, **{'weight': 20, 'max': 3})
G.add_edge(2, 3, **{'weight': 20, 'max': 5})

# get all paths and convert them to tuples so that we can
# deduplicate them
paths = [tuple(p) for p in nx.all_simple_paths(G, 1, 3)]

# sort the paths according to the number of nodes in the path
print(sorted(set(paths), key=lambda x:len(x)))

编辑2:加权多图的答案

这有点复杂,您需要编写自己的“路径得分”功能并将其传递给分类器。

G = nx.MultiDiGraph()
G.add_edge(1, 2, **{'weight': 15, 'max': 3})
G.add_edge(1, 3, **{'weight': 30, 'max': 4})
G.add_edge(2, 3, **{'weight': 20, 'max': 3})
G.add_edge(2, 3, **{'weight': 20, 'max': 5})


def get_edge_weight(u, v):
    """Return the minimum weight of all edges between nodes u and v."""
    return min([e['weight'] for e in G.get_edge_data(u, v).values()])


def weighted_path_score(path):
    """Sum of edge weights in path."""
    edges = zip(path, path[1:])
    return sum(get_edge_weight(u, v) for u, v in edges)


paths = [tuple(p) for p in nx.all_simple_paths(G, 1, 3)]

# sort using the weighted path score
print(sorted(set(paths), key=weighted_path_score))

您可以试一下边缘权重,并检查返回路径的顺序是否符合该规则(例如,将高权重设置为1-3边缘将导致路径(1,2,3)首先列出)。