【问题标题】:What's the best pathfinding algorithm in complexity?复杂度最好的寻路算法是什么?
【发布时间】:2019-01-06 16:40:37
【问题描述】:

我需要在我的一个程序中实现寻路算法。目标是知道路径是否存在。因此,知道路径本身并不重要。

我已经做了一些研究,但我不确定该选择哪一个。 This 帖子一直在告诉 DFS 或 BFS 将更适合这种程序,但我宁愿确认知道确切的情况。我也有兴趣了解程序本身的复杂性,但我想我能找到这个。不分享也没关系。

这是我正在使用的图表:假设我有一个 x*y 网格,其中包含路径可以和不能走的区域。 我想知道是否存在从图表顶部开始并在图表底部结束的现有路径。这是一个带有红色路径的示例:

我相信 DFS 在复杂性方面是最好的,但我也不确定如何在知道路径可以采用的不同起点的情况下准确地实施它。我不确定在路径可以开始的每个不同点上启动 DFS 是否更好,或者我是否添加一层区域可以让路径进行测试。

感谢您的帮助!

【问题讨论】:

    标签: algorithm complexity-theory depth-first-search


    【解决方案1】:

    您可以在此处采用多种不同的方法。假设您正在使用的网格大致与您在上面显示的大小一样,并且假设您不是一次处理数百万个网格,那么广度优先搜索和深度优先搜索都有可能会同样有效。广度优先搜索的优点是它会找到从顶部任意位置到底部任意位置的最短路径;缺点是它通常需要比深度优先搜索更多的内存。但是同样,如果您使用的网格数量为数百或数千个单元格,那么这种内存开销可能不会成为太大的问题。我会说选择你觉得最舒服的算法并使用它。

    至于如何实现从“顶部任意位置”到“底部任意位置”的搜索,您可以通过几种不同的方式来实现。

    1. 如果您使用深度优先搜索,您可以从顶行中的每个单元格运行一次深度优先搜索,然后搜索到底行的路径。 DFS 要求您维护一些有关哪些单元格已访问和未访问的信息。如果您在对 DFS 的所有调用中回收相同的信息,您将确保没有两个调用做任何重复的工作,因此得到的解决方案应该非常有效,对于 m × n 网格在 O(mn) 时间内运行。

    2. 如果您使用广度优先搜索,修改非常简单:不是在搜索开始时将队列中的单个起点排入队列,而是将顶行中的每个单元格排入队列搜索的开始。然后 BFS 将自然地探索从顶行的任何位置开始的所有可能路径。

    3. 这两种想法都可以用不同的方式来思考。想象您的网格是graph,其中每个单元格都是一个节点,边缘对应于相邻单元格对。然后,您可以添加一个位于网格顶行上方的新节点,并连接到顶行中的每个节点。然后添加一个新节点,该节点位于底行的正下方,并连接到底行中的每个节点。现在,如果有一条从新的顶部节点到新的底部节点的路径,这意味着从顶行中的某个节点到底行中的某个节点有一条路径,因此在此图中进行一次搜索就足以检查路径是否存在。 (有趣的事实:上面对 DFS 和 BFS 的两个修改都可以被认为是在这个新图中隐式地进行搜索。)

    您可能需要考虑另一个选项,它实施起来相当容易,而且效率明显低于 DFS 或 BFS,那就是使用 disjoint-set forest data structure 来确定连接的内容。该数据结构支持两种查询:

    • 给定两个单元格,标记有一种方法可以从第一个单元格到达第二个单元格。 (“联合”)
    • 给定两个单元格,确定它们之间是否存在路径,该路径可以是直接路径,也可以通过将多个其他路径链接在一起形成。 (“查找”)

    您可以通过构建一个不相交集的森林,将所有相邻单元对合并在一起,然后将顶行中的所有节点合并在一起并合并底行中的所有节点来实现您的连通性查询。执行“查找”查询以查看是否有任何一个顶部节点连接到任何底部节点将解决您的问题。这将花费 O(mn α(mn)) 的时间,因为函数 α(mn) 增长非常缓慢,基本上只有 3 或 4 个,因此它的效率与 BFS 或 DFS 一样有效。

    【讨论】:

    • 我喜欢这个问题的不相交集解决方案。稍加小心,您可以用很少的内存逐行进行。如果 union() 从不将链接向上指向,您只需要记住两行的集合,并且如果您只为可通过单元格的运行设置集合,那么每行最多有 ceil(width/2) 集合......所以width+2 整数数组是您需要的所有额外内存。由于只检查每个相邻对一次的额外优势,这可能是最坏情况下最快的算法。
    猜你喜欢
    • 1970-01-01
    • 2016-08-20
    • 2012-03-19
    • 2019-03-07
    • 1970-01-01
    • 2013-06-12
    • 1970-01-01
    • 1970-01-01
    • 2022-01-24
    相关资源
    最近更新 更多