【问题标题】:various ways and their runtime to check if a path exists between two nodes or vertices?检查两个节点或顶点之间是否存在路径的各种方法及其运行时间?
【发布时间】:2013-11-18 21:56:56
【问题描述】:

我在 SO 和其他地方看到过文章,其中引用了以下方法来确定图中两个节点之间是否存在路径。我想知道是否有人比其他人更好?

  1. 广度优先搜索 - O(V + E)

  2. 深度优先搜索 - O(V + E)

  3. 使用disjoint sets - O(n log n)(不确定是不是O(n log n)

所有这些方法都适用于有向图和无向图,循环图和非循环图吗?

对其中一个有什么偏好吗?

【问题讨论】:

    标签: algorithm graph depth-first-search breadth-first-search disjoint-sets


    【解决方案1】:

    好吧,我绝对可以回答线性时间算法 - BFS、DFS 应该适用于所有类型的图(有向/无向、循环/非循环)。
    想一想:从给定节点开始,他们将访问每个边缘和每个节点最大一次,因此他们不受循环的影响。
    他们会这样做以不同的方式,BFS - “逐级”,DFS - 以一种贪婪的迷宫逃逸方式,但它们要么在某个点终止(路径存在),要么在遍历之后所有边并访问每个节点,它们将以否定结果终止。
    “方向性”仅影响从给定节点 A 可到达的节点,但算法(bfs 和 dfs)的实现不知道图形是否有向。

    我不确定 union-find 结构(您的最后一个具有不相交集的项目)在有向图的情况下是否会对您有所帮助。
    Afaik,Union-find 将把(merge)节点 ab 放在一组中,如果它们是相互可达的,即从 ab 都有一条路径,反之亦然反之亦然。
    如果您在ab 之间有边缘a -> b,并且没有从ba 的其他路径,那么根据Union-find 数据结构将不会不能把它们放在一个集合中。
    , 但显然路径 a -> b 存在。

    【讨论】:

    • 我不明白你的 union-find 解释,尤其是“再次,只是应用简单的逻辑:如果你在 'a' 和 'b' 之间有边缘 'a -> b',并且没有其他路径领先从'b'到'a',在这种情况下,根据Union-find数据结构,它们不在一个集合中。但显然存在路径'a' -> 'b'。”
    • @user1988876 我更新了我的解释,希望现在更清楚。请检查确切的 union-find 实现,因为我只是认为它不适用于 directed 图表,但我对此不太确定。不过,我对 bfs 和 dfs 非常肯定。
    • 你是对的。 union-find 在有向图中可能没有帮助。你能看看这个SO帖子stackoverflow.com/questions/20060357/…
    【解决方案2】:

    BFS 比 DFS 更好,因为它会找到 最短 路径 [因此您可以更快地停止算法]。

    对不相交集了解不多(很快就会读到),可能会更新我的答案。 [根据我的阅读,它似乎比 BFS 更复杂,因为它用于查找图形的所有组件]。

    您未提及的选项之一是考虑双向 BFS - 因此同时从开始和结束运行 BFS,并在两个搜索相遇时停止。但是,如果很可能不存在路径,并且(在循环图的情况下),它将效率低下,只有在您保留对传入和传出边的引用时才能实现。

    当然:BFS 和 DFS 可用于无向、有向、循环和非循环。

    如果你愿意,你可以和他们玩一会儿here

    【讨论】:

    • 如果不存在路径,双向 BFS 效率低下是什么意思?像 BFS 和 DFS 一样,它只会访问所有节点然后完成,理论上也使用更少的内存。至于在循环图中保留对我们已经访问过的节点的引用,我们也需要对标准 BFS 和 DFS 这样做。所以我不明白这两个 cmet 关于双向 BFS 是什么意思。
    猜你喜欢
    • 2018-08-22
    • 1970-01-01
    • 2021-12-10
    • 2015-11-23
    • 2021-03-04
    • 1970-01-01
    • 1970-01-01
    • 2019-12-23
    • 2017-06-26
    相关资源
    最近更新 更多