【问题标题】:Amortized analysis for incrementing fibonacci based integers用于递增基于斐波那契的整数的摊销分析
【发布时间】:2016-09-14 00:22:48
【问题描述】:

假设整数表示为斐波那契数的总和而不是 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位为 1。递归执行此操作,直到没有两个连续的 1 位。

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

【问题讨论】:

  • 您是否允许给定数字的任何可能表示形式?例如11 也可以表示为101000 (8 + 3)。 (这将是 Zeckendorf 表示。)
  • @MarkDickinson 我假设我使用此算法从 0 递增,因此每个数字应该只有一个唯一表示。
  • @jbapple 这是很久以前 Jeff Erickson 的家庭作业问题......
  • 您会考虑接受答案还是发表评论?

标签: algorithm fibonacci amortized-analysis


【解决方案1】:

这里是如何进行的概述。

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

其次,证明如果ith 位在操作过程中翻转,那么你想出的表示将在位1、2、3、...、i-1 中全为0。 (更正说明,我忽略了第 0 位。)

接下来,如果ith 位在翻转前为 0,让我们将翻转它的成本归功于它自己。如果ith 位在翻转前是 1,那么让我们将翻转它的成本记为 2,因为您必须翻转它和它之前的那个。 (bit 1 的特殊情况除外。)

如果ith 位以 0 结束,那么在您前面有序列 ...010101 之前,您不会再次翻转。您从...000 开始,下一个数字是Fib(i),这就是这些位翻转之间的时间。由此,您可以设置将ith 位从0 翻转到1 的成本上限。 (上限是始终为0。)

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

将这两个界限相加,您将得出翻转ith 位的成本的摊销上限。这个上限呈指数衰减。

将所有可能位的上限相加,您将获得每次操作的位翻转摊销成本的上限。这将是一个有限的数字。 :-)

【讨论】:

  • 首先,如果ith 位被翻转,它将有尾随0,这是不正确的,因为使用算法3 将是101,4 将是1001
  • 那么您关于ith 位何时为0 或1 的论点也不正确
  • 如果你翻转最低位,它就不起作用。从唯一性开始,因为 101 和 1000 都是 3 的表示。但是如果你从不翻转那个位,那么大纲的其余部分就可以了。
  • 如果你保持最低位 0,那么你认为第 1 位是最低有效位,如果第 1 位是 0,你会先翻转第 1 位。我知道 3 会是1000 和 4会是1010,但 5 会是什么?使用我的算法,我们应该首先翻转第 2 位,因为它是 0,所以 1110,在我的算法下将变为 10010,即 6 而不是 5。
  • @jtsai 你必须特殊情况下如何处理最低有效位......就像你在二进制中所做的那样。你反转它,根据上一个发生的情况翻转下一个位,然后将成对的 1 合并在一起,直到位翻转删除所有成对的 1。所以 0, 10, 100, 110 -> 1000, 1010, 1100 -> 10000, 10010, 10100, 10110 -> 11000 -> 100000。以此类推。
【解决方案2】:

使用势方法,让表示的势是其中 1 的位数。然后将最低位加1,势能加1,所以它仍然是摊销的常数时间,每个进位都是免费摊销的,因为它通过将两个1位变成一个1位来释放一个单位的势能。

【讨论】:

  • 我没学过势法,想用会计法解决这个问题。您能否阐明如何使用会计方法来做到这一点?
【解决方案3】:

这里有一些命题和观察可以得出k=3的结论:

  1. 算法的应用包括一个单一的增量(从01)和零个或多个三重翻转(011100)。

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

  3. 增量应用于最右边的位,或者在其左边的位,因为在算法开始时它们不是 1

  4. 增量后,11 图案可能出现在最右侧或左侧一个位置。可能两者都是(111),但是算法会选择左边的。

  5. 翻转始终执行以下子模式转换:011 -> 100,因此每次三重翻转时 1 位的数量都会减少。此外,在三重翻转后剩下的 1 位在其右侧只有 0 位,除了最右边的位可能是 1 (在这种情况下,增量阶段导致在 ...111)。

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

  7. 该算法是正确的,因为增量发生在表示值 1 的位上(最右边两位表示的两个斐波那契数都是 1),因此表示的值随着 1 增加。三元组翻转不会由于斐波那契属性而更改表示的值。

  8. 除了最右边的 2 位外,所有其他位只能通过在某个时刻成为三元组翻转的最左边的位才能变成 1 位。

  9. Fi+1 生成的表示,其中 Fi >ith 大于 2 的斐波那契数,总是正好有两个 1 位,包括最右边的位。这是因为与值 Fi 对应的位是在所有其他位为 0 的时刻设置的,可能最右边的位除外.如果最右边的位不是1,则在下次应用算法时将变为1。所以保证会产生模式10...01,其值为Fi+1

  10. 0Fi+1所执行的增量显然是F+1。从 0Fi+1 的三元组翻转次数为 Fi-1 。这是因为增量将模式中的 1 位的数量增加了 1,而三光翻转将这个数字减少了 1。因为 Fi+1 有两个 1-比 0 的表示多位,三重翻转的次数比增量的次数少 2。

结论

对于增加 i,达到 Fi+1 的增量和三重翻转数之比收敛到 1,因为2的差异可以忽略不计。这意味着问题中的 k 收敛到 3(三次翻转由 3 次翻转组成)。

演示

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

上述fiddle中算法的实现如下:

// 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++;
}

【讨论】:

  • 您能否就这个答案提供一些反馈?
  • 是否有任何答案适合您的需求?你能发表评论吗?
猜你喜欢
  • 1970-01-01
  • 2017-01-24
  • 1970-01-01
  • 1970-01-01
  • 2022-01-14
  • 1970-01-01
  • 2010-12-03
  • 2014-08-15
相关资源
最近更新 更多