计算图中2个节点之间的距离

时间:2010-08-30 14:18:22

标签: python

我在数据库{STARTNODE,ENDNODE}中指导了以下格式存储的图形。因此,{5,3}表示从节点5到节点3有一个箭头。

现在我需要计算两个随机节点之间的距离。什么是最有效的方式?顺便说一下,图表有循环。

非常感谢!

5 个答案:

答案 0 :(得分:9)

尽可能see here

如果您有未加权的边缘,可以使用BFS

如果您有非负边缘,则可以使用Dijkstra

如果您有正面或正面边缘,则大多数情况下使用Bellman-Ford

答案 1 :(得分:4)

答案 2 :(得分:3)

如果距离是指最小跳数,那么你可以使用Guido van Rossum的find_shortest_path函数:

def find_shortest_path(graph, start, end, path=[]):
    """
    __source__='https://www.python.org/doc/essays/graphs/'
    __author__='Guido van Rossum'
    """
    path = path + [start]
    if start == end:
        return path
    if not graph.has_key(start):
        return None
    shortest = None
    for node in graph[start]:
        if node not in path:
            newpath = find_shortest_path(graph, node, end, path)
            if newpath:
                if not shortest or len(newpath) < len(shortest):
                    shortest = newpath
    return shortest

if __name__=='__main__':
    graph = {'A': ['B', 'C'],
             'B': ['C', 'D'],
             'C': ['D'],
             'D': ['C'],
             'E': ['F'],
             'F': ['C']}
    print(find_shortest_path(graph,'A','D'))
    # ['A', 'B', 'D']
    print(len(find_shortest_path(graph,'A','D')))
    # 3

答案 3 :(得分:2)

假设距离是跳数,并且是最佳的(最短路径)。您可以使用Python的列表/集跟踪被访问节点和当前可到达节点。从第一个节点开始,然后继续从当前节点集跳转,直到达到目标。

例如,给出此图:

alt text

[hop 0]
visited: {}
current: {A}

[hop 1]
visited: {A}
current: {B, C, J}

[hop 2]
visited: {A, B, C, J}
current: {D, E, F, G, H}

[hop 3]
visited: {A, B, C, D, E, F, G, H, J}
current: {K} // destination is reachable within 3 hops

访问节点列表的目的是防止访问受访节点,从而产生循环。为了获得最短的距离,重新访问是没有用的,因为它总是使得路径的距离更长。

这是Breadth-first search的简单实现。效率在一定程度上取决于如何检查访问节点,以及如何查询给定节点的相邻节点。广度优先搜索始终保证提供最佳距离,但如果您的数据库中有大量节点(例如十亿/百万),则此实现可能会产生问题。我希望这能提出这个想法。

答案 4 :(得分:0)

如果您真的在寻找最有效的方法,那么解决方案是在C中实现breadth first search,然后从Python层调用实现。 (当然,这仅适用于边缘未加权;如果权重为非负,则加权边需要Dijkstra's algorithm;如果权重为负,则加权边需要Bellman-Ford algorithm

顺便说一下,igraph library在C中实现了所有这些算法,所以你可能想尝试一下。如果您更喜欢基于Python的纯解决方案(比igraph更容易安装),请尝试NetworkX包。