Algorithm 非专业人士的摊销复杂性';什么条件?

Algorithm 非专业人士的摊销复杂性';什么条件?,algorithm,amortized-analysis,Algorithm,Amortized Analysis,有人能用外行的术语解释摊销后的复杂性吗?我一直很难在网上找到一个精确的定义,我不知道它与算法分析有什么关系。任何有用的东西,即使是外部引用的,都将受到高度赞赏。摊销复杂性原则是,尽管某些事情在你做的时候可能相当复杂,但由于不经常做,因此被认为是“不复杂”。例如,如果您创建了一个需要不时进行平衡的二叉树(例如,每2^n插入一次),因为平衡树非常复杂,但每n次插入只发生一次(例如,在插入编号256处一次,然后在512th、1024th处再次发生)。在所有其他插入上,复杂性是O(1)-是的,每n个插入

有人能用外行的术语解释摊销后的复杂性吗?我一直很难在网上找到一个精确的定义,我不知道它与算法分析有什么关系。任何有用的东西,即使是外部引用的,都将受到高度赞赏。

摊销复杂性原则是,尽管某些事情在你做的时候可能相当复杂,但由于不经常做,因此被认为是“不复杂”。例如,如果您创建了一个需要不时进行平衡的二叉树(例如,每
2^n
插入一次),因为平衡树非常复杂,但每n次插入只发生一次(例如,在插入编号256处一次,然后在512th、1024th处再次发生)。在所有其他插入上,复杂性是O(1)-是的,每n个插入需要O(n)一次,但它只是
1/n
概率-因此我们将O(n)乘以1/n得到O(1)。这就是所谓的“O(1)的摊销复杂性”——因为当你添加更多的元素时,重新平衡树所花费的时间是最小的

摊销指的是在重复运行中进行分割。最坏情况下的行为保证不会频繁发生。例如,如果最慢的情况是O(N),但发生这种情况的机会只有O(1/N),否则过程是O(1),那么算法仍然会有摊销常数O(1)时间。只需将每个O(n)运行的工作分为N个其他运行。


这个概念取决于是否有足够的跑步时间来分配总时间。如果算法只运行一次,或者每次运行都必须满足截止日期,那么最坏情况下的复杂度更为相关。

这有点类似于将算法中不同分支的最坏情况复杂度乘以执行该分支的概率,然后将结果相加。因此,如果某个分支不太可能被采用,那么它对复杂性的贡献就较小

摊销复杂度是在一系列操作中评估的每个操作的总费用

其想法是保证整个序列的总费用,同时允许单个操作比摊余成本昂贵得多

示例:
C++的代码> STD::向量< /代码>。当
push_back()
将向量大小增加到其预先分配的值以上时,它将使分配的长度加倍

因此,执行单个
push_back()
可能需要
O(N)
时间(因为数组的内容被复制到新的内存分配中)

但是,由于分配的大小增加了一倍,对
push_back()
的下一次
N-1
调用将分别花费
O(1)
时间执行。因此,
N
操作的总数仍然需要
O(N)
时间;因此,每次操作的摊余成本为
O(1)


除非另有规定,摊销复杂性是任何操作序列的渐近最坏情况保证。这意味着:

  • 与非摊销复杂性一样,用于摊销复杂性的big-O表示法忽略了固定的初始开销和恒定的性能因素。因此,为了评估big-O摊销绩效,您通常可以假设任何摊销操作序列都“足够长”以摊销固定的启动费用。具体来说,对于
    std::vector
    示例,这就是为什么您不必担心是否会遇到
    N
    额外的操作:分析的渐进性质已经假设您会遇到

  • 除了任意长度外,摊销分析不会对您正在计量成本的操作顺序做出假设——它是对任何可能的操作顺序的最坏情况保证。无论操作选择得多么糟糕(比如,恶意对手!),摊销分析必须确保足够长的操作顺序的成本不会持续超过其摊销成本的总和。这就是为什么(除非作为限定词特别提及)“概率”和“平均情况”与摊销分析不相关的原因——它们与普通最坏情况下的大O分析不相关

在摊销分析中,执行一系列数据结构操作所需的时间是所有执行的操作的平均值。。。摊销分析不同于一般案例分析,因为不涉及概率;摊销分析保证在最坏情况下每个操作的平均性能

(摘自Cormen等人的《算法简介》)

这可能有点令人困惑,因为它既说时间是平均的,也说它不是平均案例分析。因此,让我试着用一个金融类比来解释这一点(事实上,“摊销”一词最常与银行和会计联系在一起)

假设你在开彩票。(不是买彩票,我们马上就会看到,而是经营彩票本身。)你打印100000张彩票,每张售价为1个货币单位。其中一张票将授予购买者40000货币单位的权利

现在,假设你能卖出所有的门票,你将获得60000个货币单位:100000个货币单位的销售额,减去40000个货币单位的奖金。对你来说,每张票的价值是0.60货币单位,在所有票上摊销。这是一个可靠的值;你可以放心。如果你厌倦了自己卖票,有人走过来,提出以每张0.30货币单位的价格出售,你就知道自己的立场了

对于买彩票的人来说,情况就不同了。购买者在购买彩票时预计损失0.60个货币单位。但这是可能的
put(x):  Push x on the right-hand stack.
y=get(): If the left-hand stack is empty:
           Pop each element off the right-hand stack and
             push it onto the left-hand stack. This effectively
             reverses the right-hand stack onto the left-hand stack.
         Pop and return the top element of the left-hand stack.