【问题标题】:Number of calls for nth Fibonacci number第 n 个斐波那契数的调用次数
【发布时间】:2009-11-15 21:33:07
【问题描述】:

考虑以下代码sn-p:

int fib(int N)
{
   if(N<2) return 1;
   return (fib(N-1) + fib(N-2));
}

鉴于 fib 是从 main 调用的,N 为 10,35,67,...(比如说),总共有多少调用 发给fib

这个问题有关系吗?

PS:这是一个理论问题,不应该执行。

编辑:

我知道其他更快计算斐波那契数列的方法。

我想要一个解决方案来计算 fib 被调用的次数 fib(40),fib(50) ,.. 没有编译器的帮助,并且在考试条件下你应该回答类似于这个问题的 40 个问题规定的时间(约 30 分钟)。

谢谢,

【问题讨论】:

  • 你想完成什么?假设你不只是在找人来回答你的作业。
  • 这是一道作业题吗?你不应该要求其他人为你做作业;你至少应该展示你迄今为止尝试过的东西,并询问你遇到的具体问题。
  • 相关(几乎但不完全重复):stackoverflow.com/questions/360748/…
  • 不,这不是家庭作业问题!!
  • 我会说这取决于你是否使用记忆来保留先前计算的斐波那契数的结果:)

标签: c++ c algorithm


【解决方案1】:

f(n) 为计算 fib(n) 的调用次数。

  • 如果 n 则 f(n) = 1
  • 否则,f(n) = 1 + f(n - 1) + f(n - 2)

所以,f 至少是 O(fib(n))。事实上,f(n)2 * fib(n) - 1。我们通过归纳来证明这一点:

  • 基本情况(n ,即n = 0n = 1):
    • f(n) = 1 = 2 * 1 - 1 = 2 * fib(n) - 1.
  • 感应步骤 (n >= 2):
    • f(n + 1) = f(n) + f(n - 1) + 1
    • f(n + 1) = 2 * fib(n) - 1 + 2 * fib(n - 1) - 1 + 1
    • f(n + 1) = 2 * fib(n + 1) - 1

存在efficient ways 来计算任何斐波那契项。因此 f(n) 也是如此。

【讨论】:

  • 谢谢,我知道这个递归关系。我很想通过一些直接的公式来解决它。在论文中给出了找到 Fib(40) 的值,它实际上是 331160281。我想知道如何在大约 30 秒内解决它(当然没有编译器)
  • @nthrgeek:我希望我更新的答案可以帮助你回答这个问题。
  • @Stephan202:谢谢,正如我已经说过的,我知道生成第 n 个斐波那契数的更快算法。您的归纳步骤是正确的,但仍然无法在很短的时间内手动计算 f(40)。
  • @nthrgeek:你不应该应用归纳法,而是使用公式 f(n) = 2 * fib(n) - 1。正如你所说,因为你确实有一个快速算法来计算斐波那契数,这解决了这个问题。对吗?
  • 请注意,这使用了斐波那契数列的定义,其中F₀ = 1(如问题中所定义)。如果你期待F₀ = 0,那么你会得到f(n) = 2 • fib(n+1) - 1
【解决方案2】:

这个问题有关系吗 ?

第 n 个斐波那契数有一个近似方程:http://en.wikipedia.org/wiki/Fibonacci_number#Closed_form_expression

在你贴的伪代码中,调用次数满足递归关系

x(n) = x(n-1) + x(n-2) +1   # for n>=2
x(1) = 1
x(0) = 1

这与斐波那契递归关系几乎相同。归纳证明可以证明 fib(n) 调用 fib 的次数等于 2*fib(n)-1,此时 n>=0。

当然,可以通过使用封闭式表达式来加快计算速度,或者通过添加代码来记忆先前计算的值。

【讨论】:

  • 不应该是x(n) = x(n-1) + x(n-2) + 1吗?
  • @David:我们说的是函数调用的数量,而不是实际的斐波那契数列。例如。 fib(0)fib(1) 需要 1 个调用,但 fib(2) 需要 3 个调用(不是 2 个!):调用本身和两个递归调用。
  • Stephan202,感谢您指出这一点。我已经更正了我的答案。
  • @~unutbu:你真的用归纳法进行了证明吗?我认为该公式不正确(请参阅我的答案)。
  • 再次感谢 Stephan202。那是我的马虎。如果可以的话,我会更多地投票给你的答案。
【解决方案3】:

如上所述,您需要求解以下循环方程: K(n)=K(n-1)+K(n-2)+1

我们把它写成 n-1:K(n-1)=K(n-2)+K(n-3)+1

现在,从第一个中减去第二个: K(n)-K(n-1) = K(n-1) - K(n-3),

K(n) - 2*K(n-1) + K(n-3) = 0。

各自的特征方程将是: x^3 - 2*x^2 + 1 = 0。

它有以下根:1, (1+sqrt(5))/2, (1-sqrt(5))/2

因此对于任何真正的 A、B、C,以下函数 K(n) = A*(1)^n + B*((1+sqrt(5))/2)^n + C*((1-sqrt(5))/2)^n

将成为您方程的解。

要找到 A、B、C,您需要定义几个初始值 K(0)、K(1)、K(2) 并求解方程组。

【讨论】:

  • -1。 K(n) - 2*K(n-1) + K(n-3) = 0 不会翻译成x^3 - 2*x^2 + 1 = 0...K(n) 不是x^3K(n-1) 不是x^2K(n-3) 肯定不是1。充其量,你可以翻译@ 987654329@ 转换为 x - 2*y + z = 0 除非你能证明这些变量之间的关系。误导性答案。
  • 尼尔,答案没有误导。您最好阅读有关使用特征方程求解线性递归的信息。这是链接:[hcmop.wordpress.com/2012/04/20/…
【解决方案4】:

phi 是一个常数

position = ceil(log((n - 0.5)*sqrt(5))/log(phi));

n 是斐波那契数... 位置会给你哪个斐波那契数是n

例如给定 13 ,位置将是 7 - 0 1 1 2 3 5 8 13

使用此位置只需计算位置 1 处的斐波那契数或相对于给定斐波那契数的任何位置。

Previous Fibo Num = floor((pow(phi,position-1)/sqrt(5))+0.5);

floor((pow(phi, position)/sqrt(5))+0.5) - 是计算第 N 个斐波那契数的标准公式(注意 - 这不是近似值)

我刚刚把这个公式倒过来计算位置,用位置-1来计算前面的斐波那契数。

参考 - http://itpian.com/Coding/20951-Given-the-Nth-fib-no-and-find-the--N-1-th-fib-number-without-calculating-from-the-beginning---------.aspx

【讨论】:

    【解决方案5】:

    这是使用Recurrence Relations 解决的经典问题。

    具体来说,斐波那契问题有以下参数:

    f(0) = 1
    f(1) = 1
    f(n) = f(n-1) + f(n-2)
    

    一旦你掌握了递归解决方法,你就可以毫无问题地找到解决方案(顺便说一下,这与 fib(n) 完全相同)。

    【讨论】:

      【解决方案6】:

      有趣的问题,我不能给你一个公式,但我写了一个 Ruby 程序来做,它适用于我在纸上计算的数字,它应该适用于任何人。

      #!/usr/bin/ruby
      #find out how many times fib() would need to be called
      
      def howmany(n)
          a = [ ]
          a.push n-1
          a.push n-2
          while a.select{|n| n > 2}.length > 0
              a.map! do |n|
                  n > 2 ? [n-1,n-2] : n
              end
              a.flatten!
          end
          a.length
      end
      

      .

      >> howmany(10)
      => 55
      

      速度很慢。我现在正在计算 35,完成后我会进行编辑。

      编辑:

      >> howmany(35)
      => 9227465
      

      【讨论】:

        猜你喜欢
        • 2022-12-10
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2012-10-12
        • 2010-12-04
        • 2015-04-17
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多