C++ 查找路径是否存在的最有效算法

C++ 查找路径是否存在的最有效算法,c++,algorithm,path-finding,C++,Algorithm,Path Finding,我在寻找一个算法,告诉我a点和B点之间是否存在路径。 我不需要知道路径实际上是什么,我只需要知道它是否存在,执行时间是关键。基本网格要么是空的字段,要么是空的墙,只有这两个。 你们能给点建议吗 编辑:我想我会澄清的。我的基本网格如下所示: O O O X O O O O X X O O O X O O O X X O O O O X O 其中O-空白,X-墙,起点A(0,0)和终点B(4,4)。我试图做的是检查我可以移除一堵墙多少次,以便路径存在,端点可以到达。如果在二维网格中只有两个点a和B

我在寻找一个算法,告诉我a点和B点之间是否存在路径。 我不需要知道路径实际上是什么,我只需要知道它是否存在,执行时间是关键。基本网格要么是空的字段,要么是空的墙,只有这两个。 你们能给点建议吗

编辑:我想我会澄清的。我的基本网格如下所示:

O O O X O
O O O X X
O O O X O
O O X X O
O O O X O

其中O-空白,X-墙,起点A(0,0)和终点B(4,4)。我试图做的是检查我可以移除一堵墙多少次,以便路径存在,端点可以到达。

如果在二维网格中只有两个点
a
B
,则可以采用或检查路径是否存在


如果以查询的形式向您提供了网格和几对要检查的点,您可以采用以下方法:

  • 我们仅在未访问的空单元上逐单元迭代二维网格单元

  • 我们将使用深度优先搜索(或广度优先搜索),以您喜欢的方式标记这些单元格

  • 标记过程包括在空单元格上移动并用一个值(比如一个数字)标记它们。所有连接的空单元形成一个岛

  • 这样,如果任意两对点属于同一个岛,则它们之间存在路径,如果它们不属于同一个岛,则不存在路由

您可以参考下面的图片以获得更好的可视化效果。在这里,黑色单元格是墙,彩色单元格是岛,这意味着标记了某个值的单元格属于同一连接组件

  • 在上述算法中,使用颜色或数字标记每个单元格的时间复杂度将为
    O(m*n)
    ,其中
    m
    n
    是行数和列数,因为我们在DFS或BFS期间只访问每个单元格一次

  • 回答任何2对点的每个查询的时间复杂度将为
    O(1)

及其变体通常用于此类问题

一个*搜索算法在搜索之前,会根据信息决定下一步应该搜索哪些单元格,通过这样做,它可以更快地搜索“不感兴趣”的节点(单元格)

因为您不太关心优化,所以也可以利用优化,这通常会加快搜索(以优化为代价)


对于网格来说,一个很好的简单启发式方法是。

感谢这些wiki链接,但是这些链接在确定路径是否存在方面真的是最快的吗?如果网格很大,但是路径很短,那么将是最有效的。是的,你详细阐述了这一点很好,因为你提出了一个假设,假设你需要快速遍历,因为你假设你需要进行数千次才能猜出解。看看Dijkstra,甚至只是一个*。两者都是基于成本的BFS遍历。如果将墙作为成本要素合并,则将计算出要删除的墙的最小数量。通过回溯,您将知道它们是哪堵墙。基本上只需一个BFS就可以实现所有这些。在DFS中为下一个要选择的单元格应用启发式可能会提高性能,类似于*@Justin有趣的例子。你能给出下一个要选择的单元格的启发式示例吗?见amit的答案。“最接近目的地”是一个不错的启发式方法,但我对a*不够熟悉,不知道好的启发式方法。a*将在(理论)性能上有一个小的提升,但可能比BFS慢,因为它需要使用堆(使其在节点数
n
上为O(n log n))这些现实世界应用程序的真正优化是进行双向搜索(在中间相遇),请参阅以了解为什么搜索速度会很快。