我想用递推方程找出程序的时间复杂度。 那是......
int f(int x)
{
if(x<1) return 1;
else return f(x-1)+g(x);
}
int g(int x)
{
if(x<2) return 1;
else return f(x-1)+g(x/2);
}
我写了它的递推方程并尝试解决它,但它继续变得复杂
T(n) =T(n-1)+g(n)+c
=T(n-2)+g(n-1)+g(n)+c+c
=T(n-3)+g(n-2)+g(n-1)+g(n)+c+c+c
=T(n-4)+g(n-3)+g(n-2)+g(n-1)+g(n)+c+c+c+c
……………………….
……………………..
Kth time …..
=kc+g(n)+g(n-1)+g(n-3)+g(n-4).. .. . … +T(n-k)
Let at kth time input become 1
Then n-k=1
K=n-1
Now i end up with this..
T(n)= (n-1)c+g(n)+g(n-1)+g(n-2)+g(n-3)+….. .. g(1)
我无法进一步解决这个问题。 如果我们计算这个程序中函数调用的数量,可以很容易地看出时间复杂度是指数级的,但我想用重复证明它。怎么办呢?
在Anwer 1中的解释,看起来正确,我做过类似的工作。
此代码中最困难的任务是编写其递归方程。我已经绘制了另一个图,我确定了一些模式,我认为我们可以从这个图中得到一些帮助,可能是可能的递归方程。
And I came up with this equation , not sure if it is right ??? Please help.
T(n) = 2*T(n-1) + c * logn
答案 0 :(得分:3)
好的,我想我已经能够证明f(x) = Theta(2^x)
(注意时间复杂度是一样的)。这也证明g(x) = Theta(2^x)
为f(x) > g(x) > f(x-1)
。
首先,每个人都注意到,很容易证明f(x) = Omega(2^x)
。
现在我们的关系是f(x) <= 2 f(x-1) + f(x/2)
(自f(x) > g(x)
)
我们将证明,对于足够大的x
,有一些常量K > 0
,
f(x) <= K*H(x), where H(x) = (2 + 1/x)^x
这意味着f(x) = Theta(2^x)
,H(x) = Theta(2^x)
,它本身来自H(x)/2^x -> sqrt(e) as x-> infinity
(wolfram alpha限制的链接)这一事实。
现在(警告:更重的数学,perhap cs.stackexchange或math.stackexchange更适合)
根据wolfram alpha(点击链接查看x =无穷大附近的系列展开),
H(x) = exp(x ln(2) + 1/2 + O(1/x))
再次,根据wolfram alpha(点击链接(与上面不同)并查看x =无穷大的系列展开),我们有
H(x) - 2H(x-1) = [1/2x + O(1/x^2)]exp(x ln(2) + 1/2 + O(1/x))
等等
[H(x) - 2H(x-1)]/H(x/2) -> infinity as x -> infinity
因此,对于足够大的x
(比如说x > L
),我们就会有不平等
H(x) >= 2H(x-1) + H(x/2)
现在有一些K
(仅依赖于L
(例如K = f(2L)))
f(x) <= K*H(x) for all x <= 2L
现在我们继续(强烈)归纳(如果你愿意,可以恢复自然数字)
f(x+1) <= 2f(x) + f((x+1)/2)
通过归纳,右侧是
<= 2*K*H(x) + K*H((x+1)/2)
我们之前证明了
2*H(x) + H((x+1)/2) <= H(x+1)
因此f(x+1) <= K * H(x+1)
答案 1 :(得分:1)
使用memoisation,可以在O(n)时间内轻松计算这两个函数。但程序至少花费O(2 ^ n)时间,因此是一种非常低效的计算方法f(n)
和g(n)
为了证明程序在大多数 O(2 + epsilon)^ n时间对于任何epsilon&gt; 0:
设F(n)和G(n)分别是在评估f(n)和g(n)时进行的函数调用的数量。显然(将加法计为1函数调用):
F(0)= 1; F(n)= F(n-1)+ G(n)+ 1
G(1)= 1; G(n)= F(n-1)+ G(n / 2)+ 1
然后可以证明:
后记(在看到Knoothes先生的解决方案之后):因为i.m.h.o一个好的数学证明给出了洞察力,而不是很多公式,并且所有后代都存在SO(hi gals!):
对于许多算法,计算f(n + 1)涉及f(n),加上更多的工作量的两倍(三次,...)。如果随着n的增加(通常是这种情况),这种情况会变得相对较少,使用上述固定的epsilon并不是最佳的。 在许多情况下,用n的某些递减函数ε(n)代替上面的epsilon(如果ε以足够快的速度减小,比如ε(n)= 1 / n),则产生上限O((2 +ε(n))^ n)= O(2 ^ n)
答案 2 :(得分:-1)
设f(0)= 0且g(0)= 0
从我们的功能
f(x) = f(x - 1) + g(x)
g(x) = f(x - 1) + g(x/2)
用f(x)代替g(x)得到,
f(x) = f(x-1) + f(x -1) + g(x/2)
∴f(x)= 2f(x-1)+ g(x / 2)
扩展这个,我们得到,
f(x) = 2f(x-1)+f(x/2-1)+f(x/4-1)+ ... + f(1)
设s(x)是如下定义的函数,
s(x) = 2s(x-1)
现在显然f(x)=Ω(s(x))。
s(x)的复杂度为O(2 x )。
因此函数f(x)=Ω(2 x )。
答案 3 :(得分:-1)
我认为很明显f(n)&gt; 2 n ,因为f(n)> h(n)= 2h(n-1)= 2 n 。
现在我声称对于每一个n,都有一个ε,这样: f(n)&lt; (2 +ε) n ,为了看到这一点,让我们通过归纳来做,但为了使它在开始时更明智我会用ε= 1来表示f(n) &lt; = 3 n ,然后我会扩展它。
我们将使用强感应,假设每m <1。 n,f(m)&lt; 3 m 然后我们有:
f(n) = 2[f(n-1) + f(n/2 -1) + f(n/4 -1)+ ... +f(1-1)]
但对于这部分:
A = f(n/2 -1) + f(n/4 -1)+ ... +f(1-1)
我们有:
f(n/2) = 2[f(n/2 -1) + f(n/4 -1)+ ... +f(1-1]) ==>
A <= f(n/2) [1]
所以我们可以重写f(n):
f(n) = 2f(n-1) + A < 2f(n-1) +f(n/2),
现在回到我们的主张:
f(n) < 2*3^(n-1) + 2*3^(n/2)==>
f(n) < 2*3^(n-1) + 3^(n-1) ==>
f(n) < 3^n. [2]
通过 [2] ,完成了f(n)∈O(3 n )的证明。
但是如果你想将它扩展为(2 +ε) n 的格式,只需使用 1 来替换不等式,然后我们将有
表示ε&gt; 1 /(2 +ε) n / 2-1 →f(n)&lt; (2 +ε)名词 即可。[3]
同样通过 [3] ,你可以说每n都有一个ε,使得 f(n)&lt; (2 +ε) n 实际上存在常数ε,使得n> 1。 n 0 ,f(n)∈O((2 +ε) n )。 [4]
现在我们可以像@Knoothe一样使用wolfarmalpha,设置ε= 1 / n,然后我们将:
f(n)&lt; (2 + 1 / n) n ,其结果为f(n)<1。 e * 2 n ,并且通过我们在开始时的简单下界,我们得到: f(n)∈Θ(2 ^ n)。[5]
PS:我没有完全计算epsilon,但你可以用笔和纸简单地做,我认为这个epsilon不正确,但很容易找到它,如果很难告诉我很难,我我会写的。