繁体   English   中英

加权图的 BFS 算法 - 寻找最短距离

[英]A BFS Algorithm for Weighted Graphs - To Find Shortest Distance

我已经看过很多关于这个主题的帖子(即post1post2post3 ),但没有一个帖子提供了备份相应查询的算法。 因此,我不确定接受这些帖子的答案。

在这里,我提出了一种基于 BFS 的最短路径(单源)算法,该算法适用于非负加权图。 任何人都可以帮助我理解为什么 BFS(根据以下基于 BFS 的算法)不用于此类问题(涉及加权图)!

算法:

SingleSourceShortestPath (G, w, s):
    //G is graph, w is weight function, s is source vertex
    //assume each vertex has 'col' (color), 'd' (distance), and 'p' (predecessor) 
        properties

    Initialize all vertext's color to WHITE, distance to INFINITY (or a large number
        larger than any edge's weight, and predecessor to NIL
    Q:= initialize an empty queue

    s.d=0
    s.col=GREY     //invariant, only GREY vertex goes inside the Q
    Q.enqueue(s)  //enqueue 's' to Q

    while Q is not empty
        u = Q.dequeue()   //dequeue in FIFO manner
        for each vertex v in adj[u]  //adj[u] provides adjacency list of u
             if v is WHITE or GREY       //candidate for distance update
                  if u.d + w(u,v) < v.d        //w(u,v) gives weight of the 
                                               //edge from u to v
                      v.d=u.d + w(u,v)
                      v.p=u
                      if v is WHITE
                          v.col=GREY    //invariant, only GREY in Q
                          Q.enqueue(v)
                      end-if
                  end-if
              end-if
         end-for
         u.col=BLACK  //invariant, don't update any field of BLACK vertex.
                      // i.e. 'd' field is sealed 
    end-while

运行时:据我所知它是 O(|V| + |E|) 包括初始化成本

如果此算法类似于任何现有算法,请告诉我

由于伪代码是带有 FIFO 队列的 Dijksta 算法,而不是始终根据距离排序的优先级队列。 到目前为止,每个访问过的(黑色)顶点已经计算出可能的最短距离的关键不变量不一定是真的。 这就是为什么优先队列是计算(正)加权图中距离的必要条件的原因。

您可以将算法用于未加权的图,或者通过将权重为n每条边替换为由权重n-1的边连接的n-1顶点来使其不加权。

反例:

第一个Q.enqueue(s)之后的计算状态:

第一个 <code>Q.enqueue(s)</code> 之后的计算状态

第一次迭代后的计算状态:

第一次迭代后的计算状态

该图作为反例的重要之处在于adj[u] = adj[S] = [F, M]而不是[M, F] ,因此F首先由Q.enqueue(v)排队

第二次迭代后的计算状态:

第二次迭代后的计算状态

由于顶点F首先通过u = Q.dequeue()出队(与使用距离优先队列时不同),因此此迭代不会更新任何距离, F将变为黑色并且不变量将被违反。

最后一次迭代后的计算状态:

最终状态

我曾经也有同样的困惑。 查看SPFA算法。 当作者早在 1994 年发表这个算法时,他声称它比具有 O(E) 复杂度的 Dijkstra 具有更好的性能,这是错误的。

您可以将此算法视为 Bellman-Ford 的变体/改进。 最坏情况的复杂度仍然是 O(VE),因为一个节点可能会多次从队列中添加/删除。 但是对于随机稀疏图,它绝对优于原始的 Bellman-Ford,因为它跳过了许多不必要的放松步骤。

尽管“SP​​FA”这个名字在学术界似乎并不被广泛接受,但由于它的简单和易于实施,它一经发布就在 ACM 学生中非常受欢迎。 性能明智的 Dijkstra 是首选。

看起来你实现了 Dijkstra 的经典算法,没有堆。 您正在通过每个边缘浏览矩阵,然后查看是否可以改善距离。

通常人们会在没有边缘权重时说它是 BFS。

  • BFS :具有恒定边权重的图。

  • Dijkstra :带有边权重的图(可以处理一些负边,如果
    它没有负循环)

  • Bellman-ford 和SPFA :负循环图。

你的代码是Dijkastra或SPFA变异,而不是一个简单的BFS(虽然它基于基于BFS alrorithm)

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM