【问题标题】:Memory usage in Iterative-Deepening DFS(ID-DFS) and BFS迭代深度 DFS(ID-DFS) 和 BFS 中的内存使用情况
【发布时间】:2017-07-07 03:20:33
【问题描述】:

我正在阅读https://www.ics.uci.edu/~welling/teaching/271fall09/UninformedSearch271f09.pdf的讲座

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)。

【问题讨论】:

  • 是的,除了您对 DFS 搜索的“节点等待”的含义含糊不清。 IDFS 的唯一成本是为根路径中的每个节点存储某种迭代器(例如,子指针数组的索引)。
  • 感谢cmets,我已经修改了一些词,使其更全面(我希望),并添加一些注释来讨论它的内存使用情况。

标签: algorithm search


【解决方案1】:

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

让我们首先确保我们谈论的是树搜索而不是图搜索。在树搜索中,您只需要一个边缘,而在图形搜索中您将需要一个边缘和一个封闭集。边缘通常是一个优先队列,仅存储要访问的节点。对于BFS和DFS,可以分别简化为队列和栈。对于图搜索,将使用关闭集来存储所有子节点都访问过的节点,以修剪不必要的重复搜索。

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

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

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

以下是 DFS 与 BFS 的示意图:

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

【讨论】:

  • 感谢您的回答,还有一个问题:为什么我们不需要存储在BFS中生成的所有节点?您推断“BFS 需要 O(b^s)”,而所有生成的节点都是 1+b+b^2+b^3+...b^s = O(b^(s+1))。我认为我们需要存储所有生成的节点,然后我们才能知道如何找到解决方案。
  • 所有生成的节点是什么意思?
  • @user3148602 这里假设最浅的解在深度s。所以边缘的最大大小是O(b^s),大致是深度s的节点数。上面的任何节点都已经从边缘弹出,因此它不会导致最大的内存消耗。
  • @user3148602 如果您担心解决方案的路径。有几个方法可以实现。一个特别是有一个从子节点指向父节点的指针。然后,一旦找到解决方案,您就可以使用这些指针轻松地追溯到根目录。另一种我认为更通用的方法是将path 存储在边缘而不是node
  • 我们可以认为旅行商问题,每个节点代表一个城市,当你找到解决方案时,你需要知道要遍历城市,所以你应该将之前的节点存储到内存中。在 BFS 中,你不能放弃你已经生成(扩展或访问)的节点,直到你访问了最后一个城市。然后你就可以知道从头到尾的路径了。
猜你喜欢
  • 2017-08-16
  • 1970-01-01
  • 1970-01-01
  • 2022-12-11
  • 1970-01-01
  • 2016-02-16
  • 1970-01-01
  • 2022-01-05
  • 1970-01-01
相关资源
最近更新 更多