通过归纳证明指数运行时间

时间:2019-01-17 19:06:55

标签: haskell math runtime big-o induction

我在归纳中发现给定功能

时遇到问题
foo :: [Int] -> Int
foo    []  = 0
foo (x:xs) = max (max x (foo xs)) (max (-x) (foo xs))

返回给定列表Int的最大绝对值,运行时间为O(2^n)

我到现在为止:

t(0) = 1t(n>1)= 2 * t(n-1) + 4,其中t显示foo元素列表中maxn的调用总和。

Base Case:            n = 0 => t(0) = 1 <= c * 2^0, for c >= 1
Induction Hypothesis: t(n) <= c * 2^n
Induction Step:       n -> n+1
                   => t(n+1) <= c * 2^{n+1}
                  <=> 2 * t(n) + 4 <= c * 2^{n+1} | Induction Hypothesis
                  <=> 2 * c * 2^n + 4 <= c * 2^{n+1}
                  <=> c * 2^{n+1} + 4 <= c * 2^{n+1}

这显然是错误的,我不知道该如何解决。

谢谢!

2 个答案:

答案 0 :(得分:4)

让我们尝试证明更紧密的界限,例如

t(n) <= c*2^n - k        (*)

对于某些常量ck

假设归纳假设(*)成立,我们得到

t(n+1) 
= { recursive definition }
2*t(n) + 4
<= { induction hypothesis }
2*(c*2^n - k) + 4
<= { math }
c*2^(n+1) - 2k + 4
<= { ???? }
c*2^(n+1) - k

现在,我们只需要选择k,以便我们可以证明最后一步的合理性,但这很容易。

请注意,我们还需要检查基本情况t(0),然后选择c

剩下的我留给你

答案 1 :(得分:1)

让我们证明一些一般性的说法。如果算法复杂度如下:

 t(0) = c
 t(n) = a*t(n-1) + b 

假设a>1的算法复杂度为O(a^n)

让我们选择k1 = cd = b/(a-1)(此d的选择将在最后清楚显示)和k2 = a + d。假设a > c(否则应该是k1 = min(a,c)d= b/(max(a,c)-1)k2 = max(a,c) + d,但我懒得写所有max和{{ 1}})。我们想证明

min

但这是一个转折,让我们证明更严格的上限:

k1*a^n <= t(n) <= k2*a^n

基本案例

k1*a^n <= t(n) <= k2*a^n - d

显然是真的

归纳步骤

我们知道

c <= c <= (a + d) - d

是真的,想证明这一点

k1*a^n <= t(n) <= k2*a^n - d

左侧很简单:

k1*a^(n+1) <= t(n+1) <= k2*a^(n+1) - d

右侧有点复杂

t(n+1) = a*t(n) + b >= a*t(n) >= a*(k1*a^n) = k1*a^(n+1)

最后一步是正确的,因为

t(n+1) = a*t(n) + b <= a*(k2*a^n - d) + b = a*k2*a^n - a*b/(a-1) + b = k2*a^(n+1) - b/(a-1) =  k2*a^(n+1) - d

换句话说

a*b/(a-1) - b = b*(a/(a-1) - 1) = b*(a - (a-1))/(a-1) = b/(a-1)