【问题标题】:What is amortized analysis of algorithms? [closed]什么是算法的摊销分析? [关闭]
【发布时间】:2012-06-21 14:06:31
【问题描述】:

它与渐近分析有何不同?你什么时候使用它,为什么?

我读过一些似乎写得很好的文章,比如:

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

那么,谁能帮我简化一下?

【问题讨论】:

标签: algorithm analysis amortized-analysis


【解决方案1】:

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

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

摊销分析与“平均绩效”不同 - 摊销分析可以硬保证如果您执行如此多的操作,绩效会发生什么。

【讨论】:

  • " 摊销分析考虑到,为了必须增长,必须添加 n/2 个项目而不会导致自上次增长以来增长,因此添加一个项目实际上只需要 O(1) (O(n) 的成本在 n/2 次行动中摊销)。”这非常令人困惑和不清楚。
  • @AleksandrH 有什么特别的部分吗?
  • 是的,如果不解释数字的来源,就很难按照数学计算
【解决方案2】:

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

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

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

如果您正在进行实时编程(单个操作必须在可预测的时间内完成),那么摊销分析的更好界限并不重要。平均而言,操作是否很快并不重要,如果您未能及时完成操作以在带锯切得太远之前返回并调整带锯......

在您的情况下,哪一个重要取决于您的编程问题到底是什么。

【讨论】:

  • “增长可以是 O(n) 操作,但摊销是 O(1),因为你很少这样做”我认为这句话确实需要严格的数学证明。
  • “如果你正在做实时编程......”你应该更准确,并准确解释为什么该段落应该被视为“真实”。
  • @nbro 为什么你认为“应该”?该问题询问摊销分析与渐近分析有何不同以及何时要使用它们。它链接到解释如何做的文章。所以数学分析似乎是多余的。至于实时编程,我确实解释过了。实时编程是指单个操作必须在可预测的时间内完成的编程。一个典型的例子是在嵌入式编程中,您需要定期监控某些东西。比如控制机械。在这种情况下,偶尔的缓慢操作是不可接受的。
【解决方案3】:

渐近分析

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

请注意,到目前为止我们只讨论了分析的方法;我们没有具体说明我们正在分析哪个数量(时间复杂度?空间复杂度?),我们也没有具体说明我们对哪个指标感兴趣(最坏情况?最好情况? 平均?)。

在实践中,渐近分析一词通常是指算法的上界时间复杂度,即用总运行时间衡量的最坏情况性能,用大哦符号表示(例如排序算法可能是O(nlogn))。

摊销分析

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

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

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

最重要的区别

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

因此:

  • 渐近分析允许我们断言算法的复杂性当它被给定一个大小接近 N 的最佳/最坏/平均情况输入时受某个函数 F(N) 的限制——其中N 是一个变量
  • 摊销分析允许我们断言算法的复杂性当它被给定一个未知特征但已知大小 N 的输入时并不比函数 F(N) 的值差——其中 N 是一个已知值

【讨论】:

  • 上面的答案说明了为什么人们不应该盲目地支持排名靠前的人的长答案。
  • @btilly:如果您的反馈是可行的,那么您的反馈会更加有用——也就是说,您能否告诉我这个答案到底有什么问题以及如何改进它?
  • 从哪里开始?你对这两个术语的定义都是错误的,并且给出了很多也是错误的澄清细节。举一个随机的例子,摊销分析并不总是最坏的情况。否则我们不能说插入到动态调整大小的哈希中的摊销性能是O(1)
  • @btilly CLRS 第 451 页说“……摊销分析保证了在最坏情况下每个操作的平均性能。”
  • @GlenSelle 摊销分析是一种数学技术。它可用于多种用途,包括最坏情况下的性能。然而,它不一定是最坏的情况。在你的情况下,它显然被用于最坏的情况。在散列的情况下,它不是。
【解决方案4】:

本书“摊销分析”一章的第一句话简洁地定义了这个问题的答案——算法简介:

摊销分析中,执行一系列 数据结构操作对所有操作进行平均 执行。

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

但这在程序复杂度达到峰值的情况下可能会产生误导,但一般来说,程序不需要太多计算。

因此,在一系列操作中平均成本更有意义,即使单个操作可能很昂贵。这是摊销分析!

摊销分析是用于计算复杂性的渐近技术的替代方法。它帮助我们在实用性方面计算出更真实的复杂度,从而在两种或多种算法之间进行比较和决定。

【讨论】:

    【解决方案5】:

    到目前为止,我找到的了解算法摊销分析的最佳参考资料在书 Introduction to Algorithms,第三版,第 17 章:“摊销分析”中。一切都在那里,解释得比 Stack Overflow 帖子中的内容要好得多。您可以在任何体面大学的图书馆中找到这本书。

    【讨论】:

    • 是的。从提到的书中阅读 Amortized algorithm 更好,最终给出了清晰的说明。
    【解决方案6】:

    常规渐近分析渐近地查看单个操作的性能,作为问题大小的函数。 O() 表示法表示渐近分析。

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

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

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

    【讨论】:

      【解决方案7】:

      摊销分析处理多次运行例程的总成本,以及从中可以获得的收益。例如,在一个未排序的 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 log(n)) 通过预排序与 O(n^2) 相比不排序。因此摊销成本更便宜。

      简单地说,通过在早期多花一点,我们可以在以后节省很多。

      【讨论】:

        猜你喜欢
        • 2012-12-09
        • 2016-03-16
        • 2013-11-08
        • 2022-01-15
        • 2019-08-10
        • 2015-05-20
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多