web-dev-qa-db-ja.com

forループ内の入れ子になったWhileループの時間の複雑さ

以下の2つのネストされたループのTheta()表記で簡略化された漸近実行時間を導出しようとしています。

For i <-- 1 to n do
    j <-- 1
    while j*j <= i
        j = j+1
For i <-- 1 to n
    j <-- 2
    while j <= n
        j = j*j

私は総和法を使用してこれを解決しようとしましたが、実際には正しい答えが得られませんでした。下の画像は、問題に対する私の試みを示しています。最初のアルゴリズムで(n ^ 3/2)を取得できましたが、2番目のアルゴリズムの処理方法がわかりませんでした。

enter image description here

2
Freakup2

最初のアルゴリズム

外側のループでn回繰り返します。すべての反復iについて、内部ループは1からsqrt(i)まで反復するため、sqrt(i)回繰り返します。したがって、反復の総数は次のとおりです。

_ n
 ∑ √i
i=1
_

私はあなたと私 maths を割愛しますが、結果は_√n_の積分である_(2/3)*n^(3/2)_で近似できます。非常に大きな数の場合、これは主に最強の多項式因子によって駆動されるため、複雑度はO(n^(3/2))です。

2番目のアルゴリズム

タイプミスがあり、whileが<= iである必要がある場合

外側のループでn回繰り返します。すべての反復iについて、内部ループはk回反復します。ここで、kは_2^k>i_となるようなものです。 klog2(i)として簡単に決定できるので、log(i)/log(2)となります。

今回は合計の反復回数があります

_ 1      n
---- .  ∑ log(i)
log2   i=1
_

マグニチュードについては、定数係数を無視して、合計を見るだけです。繰り返しますが、あなた(そして私も!) math を節約すると、合計はlog(n!)であり、これはnlog(n)で近似されます

タイプミスがなく、実際に<= nの場合

次に、n倍のlog(n)/log(2)反復で構成される同じ内部ループを実行します。したがって、ここでの反復数は

_ 1      n             1
---- .  ∑ log(n)  = ---- . n log(n)
log2   i=1          log2
_

だから、まさにO(nlog(n))

2
Christophe