深度优先搜索的时间/空间复杂度

Posted

技术标签:

【中文标题】深度优先搜索的时间/空间复杂度【英文标题】:Time/Space Complexity of Depth First Search 【发布时间】:2016-07-28 12:56:12 【问题描述】:

我查看了其他各种 *** 答案,它们都与我的讲师在幻灯片中写的不同。

深度优先搜索的时间复杂度为 O(b^m),其中 b 是 搜索树的最大分支因子,m是最大深度 的状态空间。如果 m 比 d 大得多,那就太糟糕了,但是如果搜索 树是“浓密的”,可能比广度优先搜索快得多。

他接着说..

空间复杂度为 O(bm),即空间在动作长度上是线性的 顺序!只需要存储从根到叶的单个路径 节点,以及上每个节点的剩余未扩展兄弟节点 路径。

*** 上的Another answer 声明它是 O(n + m)。

【问题讨论】:

深度优先搜索和广度优先搜索是通用术语,可以指代很多算法,例如搜索树或对游戏状态进行蛮力搜索。 【参考方案1】:

时间复杂度:如果您可以在 O(1) 时间内访问每个节点,那么在分支因子为 b 且最大深度为 m 的情况下,这棵树中的节点总数将是最坏的情况= 1 + b + b2 + … + bm-1。使用对几何序列求和的公式(甚至我们自己求解)告诉这个总和为 = (bm - 1)/(b - 1),导致访问每个节点的总时间成正比到 bm。因此复杂度 = O(bm).

另一方面,如果你有节点数n而不是使用分支因子和最大深度,那么你可以直接说复杂度将与n 或等于 O(n)

您在问题中链接的其他答案同样使用不同的术语。这个想法在任何地方都是一样的。一些解决方案也添加了边数以使答案更精确,但一般来说,节点数足以描述复杂性。


空间复杂度:最长路径的长度 = m。对于每个节点,您必须存储其兄弟节点,以便当您访问了所有子节点并返回父节点时,您可以知道接下来要探索哪个兄弟节点。对于沿路径的 m 个节点,您必须为 m 个节点中的每一个额外存储 b 个节点。这就是你获得 O(bm) 空间复杂度的方式。

【讨论】:

如果兄弟姐妹存储在数组/链表中,则可以只保留数组索引/指向链表第一个元素的指针,这使得空间复杂度为O(m)。跨度> @Witiko:这绝对正确。我应该在答案中写下这样一个巨大的改进是可能的。只是当提问者只想知道复杂性如何像 O(bm) 这样的东西时,并没有这样想。【参考方案2】:

复杂度为O(n + m),其中n 是树中的节点数,m 是边数。

您的老师之所以将复杂性表示为O(b ^ m),可能是因为他想强调深度优先搜索和广度优先搜索之间的区别。

使用 BFS 时,如果与深度相比,您的树的扩展量非常大,并且您希望在叶子上找到结果,那么显然 DFS 在这里更有意义,因为它到达叶子的速度比BFS,即使它们都在相同的时间内到达最后一个节点(工作)。

当树非常深,并且非叶子可以提供有关更深节点的信息时,BFS 可以检测修剪搜索树的方法,以减少找到目标所需的节点数量。显然,您发现可以修剪子树的树越高,您可以跳过的节点就越多。 当您使用 DFS 时,这更难,因为您优先考虑到达叶子而不是探索更接近根的节点。

【讨论】:

【参考方案3】:

我想这种 DFS 时间/空间复杂性是在 AI 课上讲授的,而不是在算法课上讲授的。

这里的DFS搜索树含义略有不同:

节点是一种记账数据结构,用于表示搜索 树。一个状态对应于世界的一个配置。 ... 此外,两个不同的节点可以包含相同的世界状态,如果 该状态是通过两个不同的搜索路径生成的。

引自《人工智能 - 一种现代方法》一书

所以这里的时间/空间复杂度集中在你访问节点并检查这是否是目标状态。 @displayName 已经给出了很清楚的解释。

虽然 O(m+n) 属于算法类,但重点是算法本身,当我们将图存储为邻接表时以及我们如何发现节点。

【讨论】:

以上是关于深度优先搜索的时间/空间复杂度的主要内容,如果未能解决你的问题,请参考以下文章

常见的算法和数据结构的时间复杂度和空间复杂度

数据结构学习笔记——图的遍历(深度优先搜索和广度优先搜索)

数据结构学习笔记——图的遍历算法(深度优先搜索和广度优先搜索)

数据结构学习笔记——图的遍历算法(深度优先搜索和广度优先搜索)

算法题——深度优先搜索与广度优先搜索

深度优先搜索