【问题标题】:calculate distance between 2 nodes in a graph计算图中2个节点之间的距离
【发布时间】:2014-11-13 17:07:21
【问题描述】:

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

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

非常感谢!

【问题讨论】:

标签: python


【解决方案1】:

你可以see here

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

如果你有非负边,你可以使用Dijkstra

如果你有消极或积极的边缘,你最常使用Bellman-Ford

【讨论】:

    【解决方案2】:

    鉴于距离是跳数,并且是最佳的(最短路径)。您可以使用 Python 的列表/集来跟踪访问过的节点和当前可到达的节点。从第一个节点开始,然后不断从当前节点集跳跃,直到到达目标。

    例如,给定这张图:

    [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
    

    visited-node list的要点是防止访问visited节点,造成循环。为了获得最短距离,重新访问是没有用的,因为它总是使结果路径的距离更长。

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

    【讨论】:

      【解决方案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
      

      【讨论】:

        【解决方案4】:

        【讨论】:

          【解决方案5】:

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

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

          【讨论】:

            猜你喜欢
            • 1970-01-01
            • 2019-08-27
            • 1970-01-01
            • 1970-01-01
            • 2013-04-28
            • 2021-08-06
            • 1970-01-01
            • 2021-02-05
            • 2017-07-29
            相关资源
            最近更新 更多