具有两个递归调用的算法的复杂性

时间:2013-05-12 13:19:34

标签: c++ algorithm recursion

我有一个奇怪的算法,而不是递归调用2次。这是

int alg(int n)
   loop body = Θ(3n+1)
   alg(n-1);
   alg(n-2)

不知何故,我需要找到这个算法的复杂性。我试图用上面方程的特征多项式找到它,但结果系统太难解决所以我想知道是否还有其他直接方式..

4 个答案:

答案 0 :(得分:4)

复杂性:alg(n) = Θ(φ^n)其中φ=黄金比率= (1 + sqrt(5)) / 2

我一开始无法正式证明这一点,但是通过一夜工作,我找到了我的遗失部分 - 替换方法 减去 低阶词。对不起我的表达不好(∵英语不好)。


loop body = Θ(3n+1) ≦ tn

假设(猜测)cφ^n ≦ alg(n) ≦ dφ^n - 2tn

n (n ≧ 4)

考虑alg(n+1)

 Θ(n) + alg(n) + alg(n-1) ≦ alg(n+1) ≦ Θ(n) + alg(n)     + alg(n-1)
    c * φ^n + c * φ^(n-1) ≦ alg(n+1) ≦ tn   + dφ^n - 2tn + dφ^(n-1) - 2t(n-1)
              c * φ^(n+1) ≦ alg(n+1) ≦ tn   + d * φ^(n+1) - 4tn + 2
              c * φ^(n+1) ≦ alg(n+1) ≦ d * φ^(n+1) - 3tn + 2
              c * φ^(n+1) ≦ alg(n+1) ≦ d * φ^(n+1) - 2t(n+1)  (∵ n ≧ 4)

n + 1这是正确的。通过数学归纳,我们可以知道它对所有n都是正确的。

所以cφ^n ≦ alg(n) ≦ dφ^n - 2tn然后是alg(n) = Θ(φ^n)

答案 1 :(得分:3)

johnchen902是正确的:

  

alg(n)=Θ(φ^n)其中φ = Golden ratio = (1 + sqrt(5)) / 2

但他的论点有点过于挥手,所以让我们严格要求。他原来的论点是不完整的,所以我加了我的,但现在he has completed the argument


loop body = Θ(3n+1)

让我们用n来表示参数g(n)的循环体的成本。然后是g(n) ∈ Θ(n)Θ(n) = Θ(3n+1)

此外,让T(n)alg(n) n >= 0的总费用。然后,对于n >= 2我们有重复

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

对于n >= 3,我们可以将应用于T(n-1)的重复插入其中,

T(n) = 2*T(n-2) + T(n-3) + g(n) + g(n-1)

对于n > 3,我们可以继续,将重复应用于T(n-2)。因此,对于足够大的n,我们有

T(n) = 3*T(n-3) + 2*T(n-4) + g(n) + g(n-1) + 2*g(n-2)
     = 5*T(n-4) + 3*T(n-5) + g(n) + g(n-1) + 2*g(n-2) + 3*g(n-3)
     ...
                                       k-1
     = F(k)*T(n+1-k) + F(k-1)*T(n-k) +  ∑ F(j)*g(n+1-j)
                                       j=1

                                 n-1
     = F(n)*T(1) + F(n-1)*T(0) +  ∑ F(j)*g(n+1-j)
                                 j=1

使用Fibonacci数字F(n) [F(0) = 0, F(1) = F(2) = 1]。

T(0)T(1)是一些常量,所以第一部分显然是Θ(F(n))。仍需要调查总和。

g(n) ∈ Θ(n)以来,我们只需要调查

       n-1
A(n) =  ∑ F(j)*(n+1-j)
       j=1

现在,

                 n-1
A(n+1) - A(n) =   ∑ F(j) + (((n+1)+1) - ((n+1)-1))*F((n+1)-1)
                 j=1

                n-1
              =  ∑ F(j)  + 2*F(n)
                j=1

              = F(n+1) - 1 + 2*F(n)
              = F(n+2) + F(n) - 1

总结一下,从A(2) = 2 = F(5) + F(3) - 5开始,我们获得

A(n) = F(n+3) + F(n+1) - (n+3)

因此,

c*n <= g(n) <= d*n

估计

F(n)*T(1) + F(n-1)*T(0) + c*A(n) <= T(n) <= F(n)*T(1) + F(n-1)*T(0) + d*A(n)

代表n >= 2。自F(n+1) <= A(n) < F(n+4)起,所有依赖于n左右部分Θ(φ^n)的术语都是{{1}},q.e.d。

答案 2 :(得分:1)

<强>假设:

1:n >= 0

2:Θ(3n+1) = 3n + 1

<强>复杂度:

O(2 ^ n * (3n - 2));

<强>推理:

int alg(int n)
   loop body = Θ(3n+1)// for every n you have O(3n+1)
   alg(n-1);
   alg(n-2)

假设alg不执行n&lt; 1,您有以下重复:

第n步:

3 * n + 1
alg(n - 1) => 3 * (n - 1) + 1
alg(n - 2) => 3 * (n - 2) + 1

现在你基本上有一个师。您必须想象一个数字树,其中N为父级,n-1为n-1,n-2为子级。

                                       n
                 n-1                                  n-2
          n - 2        n - 3                     n - 3       n - 4
     n - 3   n - 4   n - 4 n - 5              n - 4 n - 5  n - 5  n - 6
    n-4 n-5 | n-5 n-6 |n-5 n-6 |n-6 n-7    n-5 n-6 n-6 n-7  n-6 n-6| n-6 n-8

很明显,这里有重复模式。对于除前两个和后两个(n - k, n - k - 1) in A = {k, with k from 0 to n)之外的每一对(n - 1, n - 2) and (n-2, n-3)3k + 1 * (2 ^ (k - 1))复杂度为(n - k, n - k - 1)

我正在查看对k的重复次数。现在,对于来自0 to n的每个(3k + 1) * (2 ^ (k - 1)) iterations. ,我有:

(3k + 1) * (2 ^ (k - 1)) = 3k * 2 ^ (k - 1) + 2 ^ (k - 1)

如果你从1到n加总,你应该得到想要的结果。我将扩展表达式:

1 + 2 + 2^2 + 2^3 + ... + 2^n = 2 ^ (n + 1) - 1

<强>更新

2^n - 1

在你的情况下,最终结果是:

3k * 2 ^ (k - 1)

基于求和公式并且k = 0,n。现在是第一个:

k = 0, n of k * 2 ^ (k - 1)

这相当于1 + a ^ 2 + a ^ 3 + ... + a ^ n的3和。 可以通过切换到polinomial函数,使用(n - 1) * 2 ^ n + 1公式进行积分,收缩,然后再次进行区分以获得结果2 ^ n - 1 + 3 * (n - 1) * 2 ^ n + 1 来确定该总和。

所以你有:

2 ^ n * (3n - 2);

签约的是:

{{1}}

答案 3 :(得分:0)

该函数的主体需要Θ(n)次。 该函数以递归方式调用两次。

对于给定的函数,复杂性是,

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

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

3 -->    T(n-1) = 2T(n-2) + T(n-4) + c      -----  4

3-4 ->   T(n) = 3T(n-1) - 2T(n-2) - T(n-3) - T(n-4) ----- 5

g(n) = 3g(n-1)

有,我们可以近似T(n) = O(g(n))

g(n)Θ(3 n

T(n)= O(3 n