Algorithm 迭代深化DFS(ID-DFS)和BFS中的内存使用

Algorithm 迭代深化DFS(ID-DFS)和BFS中的内存使用,algorithm,search,Algorithm,Search,我正在读一篇英语演讲 BFS中的内存使用率为O(b^d+1),ID-DFS中的内存使用率为O(bd) 我想检查一件事,为什么ID-DFS不存储所有访问的节点 我想出来的原因是它只需要存储路径和它在路径上扩展的节点。对于它访问过的路径之外的其他节点,可以从树中丢弃它们(从内存中释放它们),因为这些节点不利于从根节点指向目标节点 对于BFS,因为我们不知道解决方案在哪里,所以在找到解决方案之前,我们不能丢弃我们访问过的节点 上述想法是正确的还是错误的 注: 更准确地说,在ID-DFS中,据我所知,当

我正在读一篇英语演讲

BFS中的内存使用率为O(b^d+1),ID-DFS中的内存使用率为O(bd)

我想检查一件事,为什么ID-DFS不存储所有访问的节点

我想出来的原因是它只需要存储路径和它在路径上扩展的节点。对于它访问过的路径之外的其他节点,可以从树中丢弃它们(从内存中释放它们),因为这些节点不利于从根节点指向目标节点

对于BFS,因为我们不知道解决方案在哪里,所以在找到解决方案之前,我们不能丢弃我们访问过的节点

上述想法是正确的还是错误的

注:
更准确地说,在ID-DFS中,据我所知,当访问一个节点时,我们应该生成它的所有合法子节点,比如n个子节点,并访问第一个子节点n1。对于第二个子节点n2,将对其进行访问,直到有限深度DFS完成对n1的搜索。这就是为什么ID-DFS中的内存使用率是O(bd),分支因子乘以深度。对于一些不需要在访问节点时生成所有子节点的应用程序,可以只生成第一个子节点;对于第二个子项,可以在搜索n1并返回后生成。对于这样的修改,它只需要存储路径,所以它的内存使用率是O(d)。

我假设这是对AI课程的介绍

让我们首先确定我们讨论的是树搜索而不是图搜索。在树搜索中,您只需要一个条纹,而在图形搜索中,您需要一个条纹和一个闭合集。边缘通常是一个优先队列,只存储要访问的节点。对于BFS和DFS,可以分别简化为队列和堆栈。对于图搜索,关闭集将用于存储所有子节点都访问过的节点,以便删除不必要的重复搜索

考虑每个节点都有
b
子节点和
m
层的搜索树

时间复杂度:DFS需要
O(b^m)
才能找到一个解决方案,而BFS需要
O(b^s)
才能找到一个,其中
s
是最浅解决方案的深度

空间复杂度:这里的空间复杂度指的是边缘将消耗的最大尺寸。DFS只需要
O(bm)
,因为它只需要将滑动节点存储在到根目录的路径上,而BFS大约需要最后一层,即
O(b^s)

以下是DFS与BFS的图示:


我们可以很容易地看到,在大多数情况下,使用BFS比DFS更快地找到一个解决方案,但DFS比BFS占用更少的内存。因此,ID-DFS只是BFS和DFS的组合。因此,要搜索到深度d,内存消耗与DFS相同,即
O(bd)

是,除非DFS搜索的“等待节点”的含义不明确。IDFS的唯一成本是为根路径中的每个节点存储某种迭代器(例如,子指针数组中的索引)。感谢您的评论,我修改了一些单词以使其更全面(我希望如此),并添加了一些注释以讨论其内存使用情况。感谢您的回答,还有一个问题:为什么我们不需要存储BFS中生成的所有节点?您推断“BFS接受O(b^s)”,而所有生成的节点都是1+b+b^2+b^3+…b^s=O(b^s+1)。我认为我们需要存储生成的所有节点,这样我们就可以知道找到解决方案时如何找到。您所说的所有生成的节点是什么意思?@user3148602这里假设最浅的解决方案位于深度
s
。因此,条纹的最大尺寸是
O(b^s)
,这大致是深度
s
的节点数。上面的任何节点都已在前面从边缘弹出,因此不会导致最大内存消耗。@如果您关心解决方案的路径,请使用3148602。有好几种方法需要实施。一个特别的方法是让指针从子节点指向父节点。然后,一旦找到解决方案,就可以使用这些指针轻松地跟踪到root。另一种方法,我认为更通用,是将
路径
存储在边缘,而不是
节点
。我们可以认为旅行推销员的问题,每个节点代表一个城市,当你找到解决方案时,你需要知道如何遍历城市,因此你应该将前一个节点存储到内存中。在BFS中,在访问最后一个城市之前,您不能放弃生成(扩展或访问)的节点。然后你可以知道从开始到结束的路径。