【问题标题】:Fundamental question of amortized analysis摊销分析的基本问题
【发布时间】:2019-08-11 17:38:53
【问题描述】:
一个数据结构支持一个操作 foo,使得一系列 n 个操作 foo 在最坏的情况下需要 Θ(n log n) 时间来执行。
a) foo 操作的摊销时间是多少?
b) 单个 foo 操作的实际时间可以有多大?
a) 首先我假设 foo 是 O(log n) 最坏的情况。
因此,摊销成本来自于 foo 讲述其最坏情况的频率。由于我们一无所知,因此摊销介于 O(1) 和 log n 之间
b) O(log n)
这是正确的吗?在这里争论的正确方式是什么?
【问题讨论】:
标签:
big-o
amortized-analysis
【解决方案1】:
a) 如果n 操作占用Θ(n log n),则根据定义,foo 操作的摊销时间为Θ(log n) 摊销时间是所有操作的平均值,因此您不计算最坏情况仅针对导致它的操作,但也对所有其他操作进行摊销。
b) foo 偶尔会花费 O(n),只要不超过 O(log n) 次。 foo 甚至偶尔会花费 O(n log n),只要这种情况发生的次数不超过一个常数(即 O(1))。
当您进行摊销分析时,您不会将最坏情况乘以操作次数,而是乘以最坏情况实际发生的次数。
例如,采用一次将元素推入向量的策略,但每次新元素不适合当前分配时,通过将分配的大小加倍来增加内存。每个加倍实例的成本为O(n),因为您必须复制/移动所有当前元素。但摊销时间实际上是线性的,因为您复制 1 个元素一次、2 个元素一次、4 个元素一次等:总体而言,您已经完成了 log(n) 加倍,但每项成本的总和仅为 1+2+4+8+...+n = 2*n-1 = O(n)。所以这个push实现的摊销时间是O(1),即使最坏的情况是O(n)。