f(n)= n + f(floor(n / 2))是否有封闭形式?

时间:2012-12-25 03:31:45

标签: c performance recurrence

我有以下递推公式:

  f(0) = 0
  f(1) = 1
  f(n) = n + f(floor(n/2))

可以用代码表示为:

  int f(int n) {
    int s = 0;
    for (; n; n >>= 1)
      s += n;
    return s;
  }

是否有封闭表单可以让我一步计算f(n)

如果没有,我还能做些什么来更快地计算f(n)

3 个答案:

答案 0 :(得分:6)

OEIS上搜索给出了这个系列:

  

A005187:a(n)= a([n / 2])+ n;也是扩张的分母   1 / sqrt(1-x)是2 ^ a(n);也是2n - 二进制扩展的1的数量   2n个。

所以第二部分给出了2*n - bitcount(2*n)的公式。您可以使用一些有效的bitcount实现来计算它,例如gcc的__builtin_popcount

答案 1 :(得分:2)

还要注意bitcount(2n)= bitcount(n)

,推导如下:

对于j = 0 ... N

,设n = sum(b [j] 2 ^ j)

假设b [N] = 1. define

(a)F(n)= n + F(n / 2)= n + n / 2 + n / 4 + ... = 2 * n - (1/2 + 1/4 + ... 1/2 ^ N)按几何系列

这个函数F是一个实值函数。现在,对于设置的每个比特b [j],floor函数减去b [j](sum(1/2 ^ k,k = 1 ... j + 1))。这是因为它实际上取出了1/2,但随着它的传播,随后的术语被添加。

所以

(b)f(n)= floor(F(n)-sum(b [j] sum(1/2 ^ k,k = 1 ... j + 1),j = 0 ... N-1)

将(a)代入(b)代表

(c)f(n)= floor(2n - (1/2 + 1/4 + ...... 1/2 ^(N + 1)) - sum < / em>(b [j](sum(1/2 ^(k),对于k = 1..j + 1),对于j = 0 ... N-1))

好的,这部分很酷!观察到当b [j]为1时,如果你将粗体表达式中的1/2 ^(j + 1)隐藏到斜体总和中,则总和内的总和变为1,这意味着

b [j](sum(1/2 ^(k),对于k = 1..j + 1),对于j = 0 ... N-1)= sum(b [j],对于j = 0 ... N-1)

因此等式(c)简化为

f(n) = floor(2*n - sum(b[j], for j=0...N-1) - remainder)
f(n) = 2*n - bitcount(n-2^N) - 1    ; because remainder >0 and <1
f(n) = 2*n - bitcount(n)            ; b[N]=1, so bitcount(n)=bitcount(n-2^N)+1

其中,余数是和(1/2 ^ j,j = 1,... N + 1和b [j-1] == 0),但是该总和总是> 0且<&lt; 0。 1(最多为1-1 / 2 ^(N + 2)且至少为1/2 ^(N + 1),因此它可以移出地板-1。

并且还要注意,bitcount运行时间可以等于设置的位数(http://gurmeet.net/puzzles/fast-bit-counting-routines/)。有些处理器将它作为单独的指令。

不确定乳胶是否适用于此,但没有数学符号会很痛苦。我不得不编辑它,因为总是看起来不对劲。

答案 2 :(得分:1)

The function grows as follows - 

f(n) = n + f(n/2)
f(n/2) can be further simplified as - 

n/2 + f(n/4)

If we keep doing this, we will see n + n/2 + n/4 + n/8.....upto log n terms
= n (1 + 1/2 + 1/4 + 1/8...log n terms)
= n[ (1- (1/2)^log n)/(1/2)]
= 2n [1 - (1/2)^log n]

The term (1/2)^log n will become smaller and smaller as n increases, therefore the 2n term dominates. Hence f(n) belongs to big Theta (n)