什么是算法的摊销分析?[关闭]


85

与渐进分析有何不同?您何时使用它,为什么?

我读过一些写得不错的文章,例如:

但我仍然没有完全理解这些概念。

那么,有人可以为我简化一下吗?



2
@lanzz也许它现在属于cs.stackexchange.com
nbro

恒定摊销时间”含义的重要线索。
RBT

Answers:


87

摊销分析不会天真地将调用次数与一次调用的最坏情况相乘。

例如,对于需要时将大小增加一倍的动态数组,正常的渐近分析只会得出结论,将一个项目添加到该数组中会花费O(n),因为它可能需要增长并将所有元素复制到新数组中。摊销分析考虑到要增长,必须添加n / 2个项目,而自上一次增长起就不会导致增长,因此添加项目实际上只需要O(1)(O(n)的成本为分摊到n / 2个操作中)。

摊销分析与“平均绩效”不同-摊销分析为如果您执行大量操作将对绩效产生硬性保证


1
“摊销分析考虑到要增长,必须添加n / 2个项目,而自上一次增长以来就不会导致增长,因此添加项目实际上只需要O(1)(O(n)的成本摊销n / 2个动作)。” 这是相当混乱和不清楚的。
AleksandrH

@AleksandrH的任何特定部分吗?
harold

是的,如果不对数字的来源进行解释,就很难理解数学
AleksandrH

44

对于“什么”有很多答案,但对于“为什么”却没有答案。

正如其他所有人所说,渐进分析是关于给定操作的性能如何扩展到大型数据集。摊销分析是关于大型数据集上所有操作的平均性能如何扩展的。摊销分析永远不会给出比渐近更差的界限,有时会给出更好的界限。

如果您担心较长工作的总运行时间,则可能要考虑摊销分析的更好范围。这就是为什么脚本语言(例如)经常乐于以某种方式增长数组和哈希表,即使这是一项昂贵的操作。(增长可以是一项O(n)操作,但摊销是O(1)因为您很少这样做。)

如果您正在进行实时编程(单个操作必须在可预测的时间内完成),则摊销分析的更好界限并不重要。平均操作速度是否快,是否没有及时完成操作以在切割得太远之前调回带锯都没有关系...

在您的情况下,哪一个重要取决于确切的编程问题。


1
“增长可以进行O(n)运算,但摊销为O(1),因为您很少这样做”,我认为此声明确实需要严格的数学证明。
nbro

“如果您正在执行实时编程...”,则应更加精确,并确切说明为什么将该段​​落视为“ true”。
nbro

1
@nbro为什么您认为“应该”?该问题询问了摊销分析与渐进分析有何不同以及何时使用它们。它链接到说明如何执行操作的文章。因此,数学分析似乎是多余的。至于实时编程,我确实做了解释。实时编程是指必须在可预测的时间内完成单个操作的编程。一个典型的例子是嵌入式编程,您需要定期监视某些内容。如控制机械。对于这种情况,偶尔的慢速操作是不可接受的。
btilly

26

渐近分析

该术语是指在对算法进行操作的数据(输入)用外行的话来说是“大到足以使其变大不会改变结论”的假设下对算法性能的分析。虽然不需要输入的准确大小不被指定(我们只需要一个上限),该数据集本身具有被指定。

请注意,到目前为止,我们仅讨论了分析方法。我们没有确切指定要分析的数量(时间复杂度?空间复杂度?),也没有指定我们感兴趣的度量标准(最坏情况?最佳情况?平均值?)。

在实践中,术语“渐近分析”通常是指算法的上限时间复杂度,即,以总运行时间衡量的最坏情况性能,用big-Oh表示法表示(例如,排序算法可能是O(nlogn))。

摊销分析

该术语指的是基于针对最坏情况的特定操作序列对算法性能进行的分析-也就是说,摊销分析确实表明该指标是最坏情况的性能(尽管仍然没有说要测量哪个数量) )。要执行此分析,我们需要指定输入的大小,但是我们不需要对其输入形式进行任何假设。

用外行的术语来说,摊销分析是为输入选择任意大小,然后“遍历”算法。每当必须根据输入做出决定时,都会采取最差的做法¹。算法运行完成后,我们将计算出的复杂度除以输入的大小以产生最终结果。

¹注意:确切地说,理论上可能的最坏路径。如果您的向量每次容量耗尽时都会动态加倍,“最坏情况”并不意味着假定每次插入都需要加倍,因为插入是按序列处理的。即使在输入仍然未知的情况下,我们也被允许(并且确实必须)使用已知状态以数学方式消除尽可能多的“甚至更糟”的情况。

最重要的区别

渐近分析与摊销分析之间的关键区别在于,前者取决于输入本身,而后者则取决于算法将执行的操作顺序。

因此:

  • 渐近分析使我们可以断言,算法的最佳/最差/平均情况输入值接近N时,算法的复杂性受某个函数F(N)的约束-其中N是变量
  • 摊销分析使我们可以断言,算法输入未知特征但已知大小N时,算法的复杂度不比函数F(N)的值-其中N为已知值

7
上面的答案说明了为什么人们不应该盲目地评价排名靠前的人的长答案。
btilly 2014年

2
@btilly:如果您的反馈是可行的,那么它的反馈将更加有用-也就是说,您能否让我知道此答案的确切问题以及如何改进它?
2014年

7
从哪里开始?您将两个术语都定义为错误,并提供了许多澄清的细节,这也是错误的。对于一个随机的例子,摊销分析并不总是最坏的情况。在其他情况下,我们不能说插入动态调整大小的哈希后的摊余性能为O(1)
btilly 2014年

@btilly CLRS第451页说:“ ...摊销分析可确保在最坏的情况下每个操作的平均性能。”
Glen Selle

1
@GlenSelle摊销分析是一种数学技术。它可以用于多种目的,包括最坏情况下的性能。但是,它并没有最坏的情况。在您的情况下,它显然是用于最坏的情况。如果是散列,则不是。
btilly

14

答案由《摊销分析》一书的第一句话-算法简介简要定义:

摊销分析中,执行一系列数据结构操作所需的时间在所有执行的操作中平均。

我们通过渐近分析来表示程序增长的复杂性-通过函数来​​限制程序的增长,并定义最坏,最好或平均的情况。

但是,在仅一种情况下,程序的复杂性达到顶峰的情况下,这可能会产生误导,但总的来说,该程序不需要太多的计算。

因此,即使单个操作可能很昂贵,也要对一系列操作进行平均费用才有意义。这是摊销分析!

摊销分析是渐进技术的替代方法,用于计算复杂度。它可以帮助我们根据实用性计算出更真实的复杂度,以便在两个或多个算法之间进行比较和确定。


5

到目前为止,我找到的关于理解算法的摊销分析的最佳参考是《算法简介》第三版,第17章:“摊销分析”。一切都在这里,比在Stack Overflow帖子中可以找到的解释要好得多。您可以在任何体面的大学的图书馆中找到这本书。


是。从所提到的书中阅读有关摊销算法的信息更好,并且最终使情况更清晰。
Rajesh Mappu

2

定期渐近分析根据问题的大小渐近地观察单个操作的性能。O()表示渐近分析。

摊销分析(也是一种渐进分析)着眼于共享数据结构上多个操作的总体性能。

所不同的是,摊销分析通常证明,M个操作所需的总计算量比单个操作的最坏情况的M倍具有更好的性能保证。

例如,对大小为N的八叉树的单个操作可能要花费O(N)个时间。但是,大小为N的树上的M个操作序列以O(M(1 + log N)+ N log N)时间为界,这大约是每个操作O(log N)。但是,请注意,摊销分析比“平均情况”分析严格得多:它证明任何可能的操作序列都将满足其渐近最坏情况。


1

摊销分析处理了该例程多次运行的总成本以及可从中获得的收益。例如,搜索n个项目的未排序数组以进行单个匹配可能需要进行n次比较,因此复杂度为o(n)。但是,如果我们知道要在同一数组中搜索m个项目,那么重复整个任务将具有O(m * n)的复杂度。但是,如果我们预先对数组进行排序,则成本为O(n log(n)),并且连续搜索仅需要O(log(n))即可获得排序后的数组。因此,采用这种方法的m个元素的总摊销成本为O(n * log(n)+ m * log(n))。如果m> = n,则与不进行排序的O(n ^ 2)相比,通过预排序就等于O(n log(n))。因此,摊销成本更便宜。

简而言之,通过尽早花一些额外的钱,我们可以在以后节省很多。

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.