用于递增基于斐波那契的整数的摊销分析

时间:2016-05-17 18:40:53

标签: algorithm fibonacci amortized-analysis

假设整数表示为Fibonacci数的和,而不是2的幂,因此100101代表F(6)+F(3)+F(1)=8+2+1=11(我们假设F(1)=F(2)=1)。我希望在O(1)摊销时间内以此表示形式递增一个整数。

我有增量算法:直觉是不应该有两个连续的1位。所以我首先将最低有效0位设置为1,然后从最高有效位开始,如果数字有两个连续的1位,比如位i和i-1,则将它们都设置为0并设置i + 1 bit to 1.递归执行此操作,直到没有两个连续的1位。

我使用会计方法进行摊销分析。因此,对于每个增量操作,我将授予k美元,并且每个位翻转将花费1美元。但是,我无法设置和证明k的正确值。根据经验,我认为k=3可以起作用,但我不知道如何证明这一点。

3 个答案:

答案 0 :(得分:0)

以下是如何进行的概述。

首先,证明每个整数n在Fibonacci数中都有唯一表示,没有两个连续的1位。 (更正,最低位为0.我会将该位称为0.)因此,您将从一个开始,应用您的算法,然后结束一个。

其次,证明如果在操作期间i位翻转,你提出的表示将是位1,2,3,...,i-1中的所有0#1 。 (更正说明,我忽略了第0位。)

接下来,如果在翻转之前i位为0,那么让我们把它翻转到自身的成本。如果在翻转之前i位是1,那么让我们把它翻转为2的成本,因为你必须将它翻转到它之前的那个。 (除了第1位的特殊情况。)

如果i位为0,那么在你前面的序列...010101之前,你不会再次翻转。您从...000开始,下一个数字是Fib(i),这就是这些位翻转之间的时间长度。从这里你可以设置从i0翻转1位的成本的上限。 (上限是它总是0。)

如果i位为1,那么在你前面的序列...101010之前,你不会再次翻转。您从...000开始,下一个数字是Fib(i-1),这就是这些位翻转之间的时间长度。从这里你可以设置从i1翻转0位的成本的上限。 (上限是它始终为1.)在Fib(i-1)小于Fib(i)的事实与我们将2位翻转到此操作的事实之间,此约束将大于前。

总结这两个界限,你会得出一个分摊上限来计算翻转i位的成本。此上限以指数方式衰减。

将所有可能位的上限求和,并且每个操作的位翻转的摊销成本都有一个上限。这将是一个有限的数字。 : - )

答案 1 :(得分:0)

使用电位方法,让表示的电位为1位数。然后递增最低位将电位增加1,因此它仍然是摊销的恒定时间,并且每个进位都是自由摊销的,因为它通过将两位一位变为一位来释放一个势能单位。

答案 2 :(得分:0)

以下是一些命题和观察结果,得出的结论是 k = 3

  1. 该算法的应用包括单个增量(从 0 1 )和零个或多个三重翻转( 011 100 )。

  2. 运行算法后,可以保证位模式中不再有 11 模式。

  3. 增量应用于最右边的位或左边的位,因为算法启动时它们不是 1

  4. 增量后,最右边的位置或左边的一个位置可能会出现 11 模式。它可能都是( 111 ),但算法会选择左边的算法。

  5. 翻转始终执行此子模式转换: 011 - > 100 ,因此每个三元组翻转时1位的数量减少。此外,在tripliet翻转之后保留的1位仅在其右侧具有0位,除了最右位可能是 1 (在增量阶段结果的情况下)在 ... 111 )。

  6. 在三元组翻转之后,新的 11 模式可能出现的唯一位置是前一次出现的左侧的两个位位置。所以可能会有一连串的三重翻转向左移动。这个过程是有限的,因为每个三元组翻转时1位的数量会减少。

  7. 算法是正确的,因为增量发生在表示值1的位(两个最右边的两个斐波那契数字都是1),因此表示的值增加为1.三重翻转不会由于Fibonacci属性而改变了代表值。

  8. 除了最右边的2位之外,所有其他位只能通过在某一点上作为三重态翻转的最左位而成为1位。

  9. F i +1 生成的表示,其中 F i i th Fibonacci数大于2,总是恰好有两个1位,包括最右边的位。这是因为对应于值 F i 的位在所有其他位 0 的时刻设置,除了最右边的位。如果最右边的位不是 1 ,则在下一次应用算法时它将变为 1 。因此可以保证将生成 10 ... 01 模式,其值为 F i +1

  10. 0 F i +1 执行的增量数量显然是 F 1 即可。从 0 F i +1 的三元组翻转次数为 F i -1 即可。这是因为增量会使模式中的1位数增加1,而三重翻转会将此数字减少为1.当 F i +1 时有两个1-比 0 的表示更多的位数,三重翻转的数量比增量数少2。

  11. 结论

    为了增加 i ,达到 F i +1 的增量数和三元组翻转之间的比率收敛为1,因为2的差异变得可以忽略不计。这意味着问题中的 k 收敛到3(三次翻转包含3次翻转)。

    演示

    请参阅重复应用算法的this JS Fiddle,显示位显示,增量总数和三元组翻转及其比率。看看比率(非常)如何慢慢收敛到1。

    上述小提琴算法的实现如下:

    // Apply the algorithm once
    var mask; 
    this.bits |= 1 << (this.bits & 1);
    this.increments++;
    mask = (this.bits & 6) === 6 ? 4 
         : (this.bits & 3) === 3 ? 2 : 0;
    while (this.bits & mask) {
        this.bits ^= mask * 3.5; // 3 flips
        mask <<= 2;
        this.flips++;
    }