摊销分析的基本问题

Fundamental question of amortized analysis

一个数据结构支持一个操作 foo 使得 n 个操作 foo 的序列在最坏的情况下需要 Θ(n log n) 时间来执行。

a) What is the amortized time of an foo operation?

b) How large can the actual time of a single foo operation be?

a) 首先我假设 foo 是 O(log n) 最坏的情况。 因此,摊销成本来自 foo 讲述其最坏情况的频率。由于我们一无所知,因此摊销在 O(1) 和 log n

之间

b) O(log n)

这是正确的吗?在这里争论的正确方式是什么?

a) 如果 n 操作需要 Θ(n log n),那么根据定义,foo 操作的摊销时间是 Θ(log n) 摊销时间是所有操作的平均值,因此您不会仅将最坏的情况与导致它的操作进行计算,但也会对所有其他情况进行摊销。

b) foo 偶尔会花费 O(n),只要不超过 O(log n) 次。 foo 甚至偶尔会花费 O(n log n),只要这种情况发生的次数不超过常量(即 O(1))。

进行摊销分析时,不会将最坏情况乘以操作次数,而是乘以最坏情况实际发生的次数。

例如,采取将元素一次一个地推入向量的策略,但每次新元素不适合当前分配时,通过将分配的大小加倍来增加内存。每个加倍实例的成本为 O(n),因为您必须 copy/move 所有当前元素。但摊销时间实际上是线性的,因为您复制了 1 个元素一次、2 个元素一次、4 个元素一次,等等:总的来说,您已经完成了 log(n) 倍增,但每个成本的总和只是 1+2+4+8+...+n = 2*n-1 = O(n)。所以这个 push 实现的摊销时间是 O(1),即使最坏的情况是 O(n).