我在理解Hudak的论文《用箭头堵住空间泄漏》中的空间泄漏有困难。 https://www.sciencedirect.com/science/article/pii/S1571066107005919。
1)O(n)空间复杂度到底是什么意思?相对于输入大小分配的总内存?垃圾收集一路怎么样?
2)如果1)中的定义成立,那么在第34页中,他们如何说dt是常量,信号类型类似于列表类型并且在常量空间中运行?积分C是否还在每一步仍创建1个空间,总共n个空间,即O(n)?
3)我完全不明白为什么时间复杂度是O(n ^ 2)。我确实知道需要评估的内容(下图中的i',i'',i'''),但是O(n ^ 2)怎么样?
该图像代表我用lambda图形表示法绘制的评估步骤。每个步骤都将其结构添加到整个范围,而不是替换其中的任何内容。正方形表示指针,因此,例如,步骤2中的square(i')表示步骤1中的i'块。
答案 0 :(得分:0)
我只是简要浏览了一下论文,但会尽力而为。
通常,空间复杂度意味着在某个时间点,我们需要同时在内存中存储那么多的“东西”。 GC表示,我们可以从不再需要的变量中恢复内存,但是在这里我们需要记住O(n)
的东西,因为我们(可能)仍然需要访问其中的任何部分,因此尚无法恢复内存。您可以认为这是因为重复使用内存(例如通过GC)会增加时间,但不会增加空间复杂度。在这里,n
通过提供n个时间步长(dts)来计算第n个值。
如果dt
是常数,那么我们有C a = (a, dt -> C a)
而不是C' a = (a, C' a)
的类型,它只是一个(非空)列表。本文的重点是,可以使这两种类型都可以在恒定空间中运行,但是如果列表同构,则这是一个已解决的问题。要了解为什么在每个步骤中创建一个新值可以保持不变的内存,请考虑对(iterate f)!!n
进行可能的评估,我们只存储x,然后用f (x)
覆盖,然后用{{1}覆盖},依此类推,直到我们拥有f (f (x))
为止,但仅使用此一个存储单元作为我们的值(从技术上讲,第二个存储单元最多迭代f^n(x)
)。
让我们考虑一个给出这些不同复杂性的非常简单的评估示例。假设我们正在从某个种子生成一个列表,其中每个项目都是所有先前项目的总和。要计算每个下一项,我们可以将列表的初始部分p的全部保留在内存(n
)中并求和(O(Len(p))
),得到总内存O(Len(p))
并运行time O(n)
n个元素-或者我们可以观察到,这实际上与将前一项加倍是相同的,从而允许我们使用恒定的内存和线性时间。我认为所提供的类比部分非常有帮助-您可以机械地为前几个值写出后继者,并看看两种不同的评估策略如何迅速地以所需的步骤分叉吗?