📜  计数器增量的摊销分析

📅  最后修改于: 2021-04-26 10:11:00             🧑  作者: Mango

摊销分析是指确定序列(而不是单个)操作的时间平均运行时间。它与平均案例分析不同,因为在这里,我们不假定数据像我们进行快速排序的平均案例分析那样以平均(不是很差)的方式排列。也就是说,摊销分析是最坏的情况分析,但是对于一系列操作而不是单个操作。它适用于由操作顺序组成的方法,在该方法中,大多数操作很便宜,但有些操作很昂贵。可以在下面实现的二进制计数器的帮助下将其可视化。

让我们通过在C中实现一个增量计数器来了解这一点。首先,让我们看看计数器增量是如何工作的。
让变量i包含值0,我们执行i ++很多次。由于在硬件上,所有操作都以二进制形式执行。让二进制数存储在8位中。因此,值是00000000。让我们增加很多次。因此,我们发现的模式为:
00000000、00000001、00000010、00000011、00000100、00000101、00000110、00000111、00001000等…..

脚步 :
1.从最右边进行迭代,并将全为零,直到找到第一个零。
2.迭代后,如果index大于或等于零,则使该位置上的零位于一。

C++
#include 
using namespace std;
 
int main()
{
    char str[] = "10010111";
    int length = strlen(str);
    int i = length - 1;
    while (str[i] == '1') {
        str[i] = '0';
        i--;
    }
    if (i >= 0)
        str[i] = '1';
    printf("% s", str);
}


Java
import java.util.*;
 
class GFG{
 
public static void main(String args[])
{
    String st = "10010111";
    char[] str = st.toCharArray();
    int lengthh = st.length();
    int i = lengthh - 1;
     
    while (str[i] == '1')
    {
        str[i] = '0';
        i--;
    }
     
    if (i >= 0)
        str[i] = '1';
         
     System.out.print( str);
}
}
 
// This code is contributed by sanjoy_62


输出:

10011000

简单地看程序或算法,其运行成本看起来与位数成正比,但实际上,它与位数不成比例。让我们看看如何!

假设递增操作执行了k次。我们看到,在每个增量中,其最右边的位都在翻转。因此,LSB的翻转次数为k。因为,最右边的第二个在间隙之后翻转,即以2增量递增1次。最右边的第3个– 1次,以4为增量。最右边的第4位-1次,以8为增量。因此,翻转数是最右边的第二位为k / 2,最右边的第三位为k / 4,最右边的第四位为k / 8,依此类推……

总费用将是翻转的总次数,即
C(k)= k + k / 2 + k / 4 + k / 8 + k / 16 +……
C(k)因此,C(k)所以C(k)<2k
因此,C(k)/ k <2
因此,我们发现一次增加一个计数器的平均成本是恒定的,并且不取决于位数。我们得出结论,增加计数器是恒定成本操作。

参考 :

  1. http://www.cs.cornell.edu/courses/cs3110/2013sp/supplemental/recitations/rec21.html
  2. http://faculty.cs.tamu.edu/klappi/csce411-s17/csce411-amortized3.pdf