如何使用双向BFS查找最短路径?

Zik*_*Zik 12 algorithm breadth-first-search bidirectional path-finding shortest-path

如何使用双向BFS查找最短路径?假设有一个6x6网格.起点在(0,5),终点在(4,1).使用双向bfs的最短路径是什么?没有路径成本.它是无向的.

ami*_*mit 36

双向BFS如何工作?

同时从源顶点和目标顶点运行两个BFS,一旦发现两个运行共同的顶点就终止.该顶点将位于源和目标之间.

为什么它比BFS好?

在大多数情况下,双向BFS将比简单BFS产生更好的结果.假设源和目标之间的距离是k,并且分支因子是B(每个顶点具有平均B边缘).

  • BFS将遍历1 + B + B^2 + ... + B^k顶点.
  • 双向BFS将遍历2 + 2B^2 + ... + 2B^(k/2)顶点.

对于大B而且k,第二个显然比第一个快得多.


在你的情况下:

为简单起见,我假设矩阵中没有障碍物.这是发生的事情:

iteration 0 (init):
front1 = { (0,5) }
front2 = { (4,1) }

iteration 1: 
front1 = { (0,4), (1,5) }
front2 = { (4,0), (4,2), (3,1), (5,1) }

iteration 2:
front1 = { (0,3), (1,4), (2,5) }
front2 = { (3,0), (5,0), (4,3), (5,2), (3,2), (2,1) }

iteration 3:
front1 = { (0,2), (1,3), (2,4), (3,5) }
front2 = { (2,0), (4,4), (3,3), (5,3), (2,2), (1,1), }

iteration 4:
front1 = { (0,1), (1,2), .... }
front2 = { (1,2) , .... }
Run Code Online (Sandbox Code Playgroud)

现在,我们发现前沿在(1,2)处相交,以及从源顶点和目标顶点到达那里的路径:

path1: (0,5) -> (0,4) -> (0,3) -> (0,2) -> (1,2)
path2: (4,1) -> (3,1) -> (2,1) -> (1,1) -> (1,2)
Run Code Online (Sandbox Code Playgroud)

我们现在只需要反转路径2并将其附加到路径1(当然,移除一个常见的交叉顶点),为我们提供完整的路径:

(0,5) -> (0,4) -> (0,3) -> (0,2) -> (1,2) -> (1,1) -> (2,1) -> (3,1) -> (4,1)
Run Code Online (Sandbox Code Playgroud)