4

我正在用 Java 编写一个程序,我必须实现三个搜索算法,其中三个是深度优先图形搜索算法。我的程序遍历由邻接矩阵内部表示的连通图,并使用每个算法的边界和探索集。

边界存储扩展父节点的未探索子节点,探索集存储实际已扩展的节点。探索集的目的是避免重复,从而避免无限循环。

我的边界是使用链接的阻塞双端队列实现的,而我的探索集是使用链接的哈希集实现的。

然而,在测试这个算法实现的初始版本时,我注意到仍然有少量重复,特别是当目标节点不存在并且算法肯定必须访问图中的每个节点时。最终我意识到这是因为当一个节点被扩展时,它的所有子节点都被添加到边界,但只有一个被探索。因为图是连接的,所以节点可能存在其他路径,这可能导致节点在它被扩展并因此添加到探索集之前被多次遇到。

这引出了我的问题,我要解决它吗?

深度优先搜索应该首先探索由图形成的树的一侧,然后回溯,这意味着即使它在树的一侧遇到不太理想的目标节点,它也应该返回那个而不是(更优) 一个以前遇到但尚未探索的问题。

但是,如果我为了避免重复而实施探索集,那么在某些情况下我允许它们似乎是矛盾的。

我相信真正的错误可能在于对算法缺乏透彻的理解,我真诚地希望得到一些帮助,在此先感谢。

4

1 回答 1

2

通常称为深度优先搜索的算法不需要您所说的“边界”。然而,这个概念用于 A* 图形搜索(它通常在那里被称为“开放集”)。

对于标准深度优先搜索,您只需要一堆节点:将初始节点压入堆栈,然后在每一步中从堆栈中弹出一个节点,检查它并将其所有邻居(*)压入堆栈顶部。然后,重复。

(*)记住将您推送到堆栈上的所有节点标记为已访问(我相信您在问题中将此称为“已探索集”)并且不要推送已访问过的节点。

通过使用堆栈,您可以避免您描述的问题。

如果您确实想维护该边界/开放集,请确保它从不包含重复项:使用不允许重复的数据结构(例如 a set)。

(旁注:如果您的图形节点具有自然编号,并且您希望您的 DFS 访问大多数注释,那么您也可以使用array/vector作为您的探索集/封闭集。)

于 2013-01-25T23:48:43.433 回答