确定样本代码的计算复杂度

时间:2015-01-25 16:44:59

标签: complexity-theory

我给你三个简短的代码:

第一个代码:

procedure Proc (n:integer)
  begin
  if n>0 then
    begin
    writeln('x')
    Proc(n-2)
     writeln('*');
     Proc(n-2)
     end 
   end

第二段代码:

procedure Proc (n:integer)
  begin
  if n>0 then
    begin
    writeln('*');
    Proc(n-1)
    end 
   end

第三个代码:

procedure Proc (n:integer)
  begin
  if n>0 then
    begin
    writeln('x')
    Proc(n/2)
     writeln('*');
     Proc(n/2)
     end 
   end

我想知道如何确定我给出的每个代码的计算复杂度,因为它会帮助我更好地理解..有人可以编写一个算法来逐步确定示例代码的计算复杂度,并且它可以将此算法应用于另一个代码示例吗?

1 个答案:

答案 0 :(得分:0)

第一个问题:假设您知道对于n - 2的值,Proc称为T(n-1)次。因此,对于n的值,T(n)= 1 + 2T(n-2),因为将有一次调用Proc(n),这将调用Proc(n-2)两次。 T(n)= 1 + 2T(n-2)是河内塔的变体,其为T(n)= 1 + 2T(n-1)。这里有证明http://en.wikipedia.org/wiki/Tower_of_Hanoi来证明T(n)= 1 + 2T(n-1)= 2 ^ n-1。因此,T(n-1)= 1 + 2T((n-1)-1)= 1 + 2T(n-2)= 2 ^(n-1)-1。在你的情况下,T(n)= 1 + 2T(n-2)= 2 ^(n-1)-1。换句话说,在河内塔问题中减去每隔一个术语可以节省大约一半的电话。 2 ^(n-1)-1 = 2 ^ n / 2 - 1,其为O(2 ^ n)。

第二个问题:这更容易。 T(0)= 1且T(n)= 1 + T(n-1)。您可以通过多种不同方式解决这个问题,但其中一种方法是通过伸缩式实现:

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

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

...

T(1)= 1 + T(0)

加上双方......

T(n)+ T(n-1)+ ... + T(1)= 1 + T(n-1)+ ... + 1 + T(0)= n + T(n- 1)+ ... + T(0)

减去类似的条款。

T(n)= n + T(0)= n + 1.所以这是O(n)。

第三个问题:与第一个类似。 T(0)= 1,假设我们知道对于n-1的值,你可以看到T(n)= 1 + 2 T(n / 2)。这里注意,T(n)= 1 + 2T(n / 2)< n + 2T(n / 2)。

因此解决2T(n / 2)+ n并推出重现:

T(n)= 2T(n / 2)+ n

T(n / 2)= 2T(n / 4)+ n / 2

因此T(n)= 4T(n / 4)+ n + n

T(n / 4)= 2T(n / 8)+ n / 4

因此T(n)= 8T(n / 8)n + n + n

......对于正k,看起来像T(n)= 2 ^ kT(n / 2 ^ k)+ kn。

通过归纳证明。 k = 1:给出T(n)= 2T(n / 2)+ n。这是我们的基本案例。 如果对于k-1为真,则对于k显示为真:

T(n)=(2 ^(k-1))T(n / 2 ^(k-1))+(k-1)n //归纳假设

T(n / 2 ^(k-1))= 2 T([n / 2 ^(k-1))] / 2)+ n / 2 ^(k-1))//给定复发< / p>

= 2T(n / 2 ^ k)+ n / 2 ^(k-1)

=&GT; T(n)=(2 ^ k)T(n / 2 ^ k)+ n +(k-1)n =(2 ^ k)T(n / 2 ^ k)+ kn。对于k来说是如此。

T(n)= 2 ^ kT(n / 2 ^ k)+ kn,选择合适的正k,例如k = ln(n)。

T(n)= 2 ^ ln(n)T(n / 2 ^ Ln(n))+ nln(n)= nT(1)+ nln(n)。

T(1)= 1,因为Proc刚刚结束。所以n(T(1))+ nln(n)= nln(n)+ n = O(nln(n))。

不幸的是,没有一个适合所有程序的复杂性。你必须根据具体情况采取它并找出问题。