2016-04-08 24 views
2

私は、正の整数Nをx^yとして表すことができるかどうかを決定するこのアルゴリズムの時間複雑度を計算しようとしています。アルゴリズムの作成者はVaibhav Guptaです。このアルゴリズムの時間計算量を計算する

// Returns true if n can be written as x^y 
bool isPower(unsigned int n) 
{ 
    // Base case 
    if (n <= 1) return true; 

    // Try all numbers from 2 to sqrt(n) as base 
    for (int x=2; x<=sqrt(n); x++) 
    { 
     unsigned p = x; 

     // Keep multiplying p with x while is smaller 
     // than or equal to x 
     while (p <= n) 
     { 
      p *= x; 
      if (p == n) 
       return true; 
     } 
    } 
    return false; 
} 

著者は、このアルゴリズムは最初の1の最適化バージョンであることを言う:

// Returns true if n can be written as x^y 
bool isPower(unsigned n) 
{ 
    if (n==1) return true; 

    // Try all numbers from 2 to sqrt(n) as base 
    for (int x=2; x<=sqrt(n); x++) 
    { 
     unsigned y = 2; 
     unsigned p = pow(x, y); 

     // Keep increasing y while power 'p' is smaller 
     // than n. 
     while (p<=n && p>0) 
     { 
      if (p==n) 
       return true; 
      y++; 
      p = pow(x, y); 
     } 
    } 
    return false; 
} 

んこの最初の一つは、彼が捕虜機能を使用していますので、異なる時間の複雑さを持っていますか?外側のループは、nの平方根であるよう

+0

私にとっては、 'if(n%x!= 0)continue;' 'while'の直前にチェックがないことは非常に奇妙です。この最適化を避ける理由はありますか? – Ilya

+0

@ilya - 質問はそれに関するものではありません。アルゴリズム*の複雑さについて書かれています*。 –

答えて

1

は私に見える、と(数は指数関数的に増加するので)、内側のループは、ログ、nの順になっているので、あなたの複雑さが

O(sqrt(n)*log n) 
の曲で何かする必要があります
+1

内部ループはlog_x(n)回実行されます(log_xはログベースxです)。集計を行う際に変化するベースを無視するのはなぜ有効ですか? –

+0

@PaulHankinはい、それは単純にhttp://www.mathwords.com/c/change_of_base_formula.htm定数を乗算することによって、xのログベースAをxのログベースbに変えることができ、定数乗数がなくなるからですビッグO表記:) – Rob

+0

@PaulHankin私は似たような質問に戻って答えた:http://stackoverflow.com/questions/6314337/is-this-function-in-the-complexity/6314497#6314497 – Rob

2

falseを返すと、アルゴリズムはを超えるまで、すべての整数の累乗を増加しようとします。xx = √nが試行された後、検索が停止します。

だからラフな評価のために、 x^d = nまで力を評価することについて log n/log x乗算を取り、 x=√nx=2から繰り返されます。

したがって複雑さが

推定する不安である
log n.Sum(x=2 to √n)1/log x 

が、O(log n.√n)Ω(√n)ようなものです。

powバージョンは、電力を計算するために1の代わりにlog dの乗算を使用します(ただし、繰り返されるスクエア化によって得られます)。 d = log n/log xとして、複雑さが

log n.Sum(x=2 to √n)(log log n - log log x)/log x 

のように見積もることはさらに困難であるが、O(log n.log log n.√n)Ω(√n)

nがint型の場合、pow関数のオーバーヘッドが大きい場合を除き、powのバージョンが1倍から5倍遅くなることが予想されます。

+0

複雑さがO(√n)であるように、合計(x = 2〜√n)1/log x〜=√n/ log(√n)。 (合計の詳細はhttp://mathforum.org/kb/message.jspa?messageID=89138)。 –

+0

@PaulHankin:ありがとう。これはO(log n・√n)とΩ(√n)を確認する。:) –

+1

ここでは、あなたがここで行ったより慎重な分析を促し、他の答えの近似の素朴なアプローチが間違った答えを与えることを示しているので、とにかく、私はupvoted :) –