双向搜索与否?速度考虑

时间:2013-10-14 22:16:00

标签: algorithm

我正在实现一种算法,该算法必须快速确定2D网格中两个单元格之间是否存在路径(对于类似迷宫的游戏)。它实际上不必提供路径。该算法运行数千次,因此必须快速。

怪癖是,两个单元格彼此非常接近(曼哈顿距离为2),因此对于大多数合理的迷宫来说,路径通常是微不足道的。现在我有纯粹的广度优先搜索,但我正在考虑实现双向变体。问题是,当然,在路径不存在的情况下,双向搜索将失败得更慢,因为它搜索两个连接的组件而不是一个,但是如果路径存在,它会更快(可能)找到它。 / p>

所以我的问题是,有没有人有双向搜索的经验以及它在上述情况下的表现如何?速度差实际上是非常小的吗?

3 个答案:

答案 0 :(得分:0)

迷宫每次都略有不同(每次不同的细胞不通过)

在这种情况下,通常可以通过保存洪水填充(广度优先)距离来做得更好。

考虑像这样的迷宫(从+到*)

XXXXXXX
X+   *X
X XXX X
X     X
XXXXXXX

有洪水填充距离

XXXXXXX
X+123*X
X1XXX7X
X23456X
XXXXXXX

阻塞点Z给出

XXXXXXX
X+123*X
X1XXX7X
X23Z56X
XXXXXXX

由于Z的值为4,大于最短路径(3),因此您立即知道Z不会影响解,不再进一步搜索。

另一种情况,如果你在Y处阻止,

XXXXXXX
X+1Y3*X
X1XXX7X
X23456X
XXXXXXX

您知道任何大于2的距离(阻挡值)都不可靠,因此您需要重新计算这些点。在这种情况下,这意味着在较长的路径上重复搜索。但这并不比你原来做的贵。

简而言之,如果您进行少量修改,存储填充距离可以节省时间(以内存为代价)。

这只是非常一般的建议。例如,我并不是说在开始时完全填充每个单元格总是最好的。可能是因为第一次成功停止会更有意义,随后会进一步填充。

换句话说,在搜索期间缓存内部结果并且聪明地使缓存无效。那么你可以避免在没有改变的迷宫区域重复工作的成本。

答案 1 :(得分:0)

直觉如果不存在路径,双向搜索 [1] 比单向搜索更多,通常不会。如果您的双向算法被编码为在前向和后向搜索的扩展节点之间频繁交替(正如它应该做的那样),即使在源和目标之间没有路径的情况下,双向变量也有可能在单向之前返回:假设输入图包含2个未连接的组件,例如 V W ;属于 V 的源节点 s ,属于 W 的目标节点; | V | = 1000 | W | = 10 。现在,单向搜索必须在其优先级队列为空之前扩展所有1000个节点。在双向搜索中,只有来自 W 的10个节点和来自 V 的10个节点将被扩展,然后终止。

[1] Java implementation

答案 2 :(得分:0)

我实施了其中一个,它几乎使我的搜索时间增加了一倍。我没有在这个双向搜索中使用bfs的队列版本,而是使用了Erik D.在他的麻省理工学院课程中教授的版本,但我不知道队列版本将如何产生那么大的差异???

另一种快速的方法是使用链接剪切树。它们是通常展开树木的森林,并与动态图形一起使用。