【问题标题】:Using recurrence relations to prove a function has exponential runtime?使用递归关系证明函数具有指数运行时间?
【发布时间】:2013-04-06 04:48:04
【问题描述】:

这是一个简单的 C 程序:

int f(int n) {
  if(n==0 || n==1) {
    return n;
  } else {
    return 2 * f(n - 1) + 3 * f(n - 2);
  }
} 

这个程序具有指数时间复杂度。您可以在 f(5) 的函数调用图中看到这一点:

我想仅使用递推方程来证明该函数具有指数复杂性,而不是通过绘制图表和计算函数调用的次数。

我想出的递归关系是

T(n) = T(n-1) + T(n-2) + c

扩展给予

T(n) = 2T(n - 2) + T(n - 3) + 2c

但是,我不知道如何进一步解决这个问题。如何解决这种递归关系?

【问题讨论】:

标签: c algorithm math recursion big-o


【解决方案1】:

对于初学者,您的重复需要某种基本情况,否则当您达到 0 时它是未定义的。为简单起见,让我们这么说

T(0) = a

T(1) = a + b

T(n + 2) = T(n) + T(n + 1) + c

让我们开始扩展这个循环的前几个术语:

  • T(0) = 一个
  • T(1) = a + b
  • T(2) = 2a + b + c
  • T(3) = 3a + 2b + 2c
  • T(4) = 5a + 3b + 4c
  • T(5) = 8a + 5b + 7c
  • T(6) = 13a + 8b + 12c
  • T(7) = 21a + 13b + 20c

这里有一个非常有趣的模式正在形成。让我们分别看一下 a、b 和 c 项的系数。 a项的系数遵循模式

1, 1, 2, 3, 5, 8, 13, 21, ...

这是斐波那契数列,偏移了一步。 b项的系数为

0, 1, 1, 2, 3, 5, 8, 13, ...

正是斐波那契数列。最后,我们来看看c项:

0, 0, 1, 2, 4, 7, 12, 20, ...

嗯,这看起来并不熟悉。但是,如果我们将其与 a 项放在一起,我们会看到:

a: 1, 1, 2, 3, 5, 8, 13, 21, ...

b: 0, 0, 1, 2, 4, 7, 12, 20, ...

请注意,b 项都是 a 项减去一个!换句话说,就是将斐波那契数列移动了一步,但每一项都减去了 1。

根据这些观察,我们可以推测以下是正确的:

T(n) = aFn+1 + bFn + c(Fn+1 - 1)

我们现在可以尝试通过归纳来证明这一点。作为我们的基本案例:

T(0) = a = 1a + 0b + 0c = 1a + 0b + (1 - 1)c = aF1 + bF0 + c(F 1 - 1)

T(1) = a + b = 1a + 1b + 0c = 1a + 1b + (1 - 1)c = aF2 + bF1 + c (F2 - 1)

对于我们的归纳步骤,假设对于某个自然数 n,

T(n) = aFn+1 + bFn + c(Fn+1 - 1)

还有那个

T(n + 1) = aFn+2 + bFn + 1 + c(Fn+2 - 1)

那么我们就有了

T(n + 2) = T(n) + T(n + 1) + c

= aFn+1 + bFn + c(Fn+1 - 1) + aFn+2 + bFn + 1 + c(Fn+2 - 1) + c

= a(Fn+1 + Fn+2) + b(Fn + Fn+1 ) + c(Fn+1 + Fn+2 - 2 + 1)

= aFn+3 + bFn+2 + c(Fn+3 - 1)

这样就完成了归纳,所以我们的公式一定是正确的!

那么这与效率有何关系?好吧,Binet's formula 告诉我们 Fn = Θ(φn),其中 φ 是 golden ratio(约 1.61)。这意味着

T(n) = aFn+1 + bFn + c(Fn+1 - 1) = aΘ(φ n) + bΘ(φn) + cΘ(φn) = Θ((a + b + c)φn )

所以只要a + b + c ≠ 0,运行时间就是Θ(φn),是指数的。

希望这会有所帮助!

【讨论】:

  • 精彩的解释,你怎么能在 9 分钟内写出这个好答案..你似乎是从计算背景理论...
  • @GrijeshChauhan-我教一门计算理论课程,并​​且碰巧知道这种特殊重复背后的基本思想。这主要来自经验。
  • 很好!!我也喜欢教授和教授计算理论但是我是软件工程师,我刚刚看到你的主页很好的答案我想在我的额外时间阅读......当我发现一些问题/疑问时我会抓住你
  • 我想在上面补充一点,如果你想推导出递归而不是猜测(并通过归纳证明猜测!)那么你可能想要研究生成函数:classes.cs.uchicago.edu/archive/2005/fall/27100-1/gf.pdf 它需要更多的数学(阅读:代数),但它更具建设性。我认为除了猜测+归纳之外,大多数复杂性课程都会教你这种方法,所以你们最终应该学会它吗?
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-06-13
  • 1970-01-01
  • 2013-03-11
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多