如何使用广度优先搜索来查找地图中的最短路径?

时间:2013-01-30 01:22:39

标签: c++ algorithm search

为简单起见,假设我有图表:

O O P O |
O O O O O
O | O | O
O O O O O
A O O O O

其中我想使用广度优先搜索以最短路径从A行进到P,其中位置由|是禁区。我怎样才能达到这个效果?我总是看到用于查找某个位置的广度优先搜索(在这种情况下为P),但我还没有看到用于存储路径距离和计算最短位置的任何实现(也没有用于存储先前访问过的位置的有效方法)将他们排除在进一步审查之外)。此外,对于必然较大且需要大量推送和弹出的图形,通常建议使用哪种队列?

4 个答案:

答案 0 :(得分:5)

广度优先搜索的优点在于它会自动找到最短路径(您只需跟踪访问节点时的来源)。 通过广度优先搜索,您始终拥有队列开头最便宜的路径和最后的昂贵路径。一旦达到目标P,就可以保证路径长度最小。

std::queue是实施它的绝佳选择。

回复您的评论:您有一个节点 / 顶点的队列(在您的情况下,这些是您的单元格)。访问节点时,将先前未访问过的所有邻居添加到队列中。要跟踪您访问过的节点以及路径的来源,请保留std::array / std::vector wherefrom;,每个节点都有一个元素。然后(伪代码!)

take element v from queue
 for each neighbour x of v
    if wherefrom[x] != NULL
     wherefrom[x] = v
     add x to end of queue

点击目标节点P后,您只需回溯wherefrom即可查找路径。

答案 1 :(得分:2)

我建议您阅读Dijkstra的算法,然后进入A *搜索。

以下是在C ++中解决此问题的简单方法:

  1. 创建一个std :: vector of int(让我们称之为“trail”)初始化为-1,地图中的每个节点都有一个元素(在你的例子中大小为25)。这将用于指示哪些节点已被搜索,以及它们的搜索位置。尚未搜索“trail”值为-1的节点,并且已从节点8搜索“trail”值为8的节点。

  2. 创建一个std :: int of queue(让我们称之为“search_queue”)。然后推送包含“A”的节点的ID,并将其“trail”值标记为自身。例如。如果'A'是节点20,则将trail [20]设置为20;这记录了该点开始的踪迹。

  3. 从'search_queue'弹出前节点,依次查看每个邻居,如果其踪迹值为-1,则将其ID添加到队列中,并且不限制它们(不包含'|' )。

  4. 重复步骤3直到找到'P'(你到达了目标!),或者队列为空(没有有效路径)。

  5. 如果找到'P',则使用'trail'向量将路径追溯到开头 - 每个节点将指向路径中的上一个节点,直到到达指向自身的节点。这就是你开始的地方,所以你现在有了一条完整的道路!

  6. 您不必计算任何距离,因为呼吸优先搜索的性质可确保算法找到的第一个有效路径将是最短的路径。

答案 2 :(得分:1)

我假设你有一个带有A P O |的二维数组值。如果不知道,您将需要使用强力搜索找到A.

对于路径,可以通过创建一组1移动位置(即,如果允许对角线移动,在上方,右方,并且可能在右上方)找到从A开始的最短路径。当你这样做时,你想要跟踪哪些位置已被访问以避免返回到同一个方格,因此您需要对原始数组执行某些操作(例如,将访问位置从“O”更改为“o”)或拥有另一个数组就是为了这个。从1移动位置,您可以创建一组尚未访问过的合法2移动位置。一直走,直到找到“P”。

关于容器的选择:使用上面的算法你不会弹出任何东西 - 只需使用矢量。

作为优化,您可能也想要本地P并尝试深度优先遍历两者之间最明显的路径 - 在您的插图案例中[对角线向右 - ] - 否则向上 - 向右允许“向上”直到您到达目标行,并且“向右”直到您到达列。也可以做对了 - 否则也可以。或者反而。

答案 3 :(得分:0)

获得地图后:

O O P O |
O O O O O
O | O | O
O O O O O
A O O O O

定义图表,1表示是否有边缘:

1 1 P 1 0
1 1 1 1 1
1 0 1 0 1
1 1 1 1 1
A 1 1 1 1

其中a_ij = 0 iff m_ij = | and elsewhere a_ij = 1

然后运行Dijkstra's algorithmBellman-ford algorithm

如果您坚持使用BFS,以下是对其原理的解释:

How does a Breadth-First Search work when looking for Shortest Path?