理論的な複雑さと実際の効率の違い


7

この疑似コードがある場合:

for i=0 to n/2 do
   for j=0 to n/2 do 
       ... do anything ....

反復回数は 2/4

このプログラムの複雑さは何ですか?それは?O2

その複雑さは、どのような直感的な公式/非公式なものですか?

次に、この他の疑似コードがある場合:

for i=0 to n do
   for j=0 to n do 
       ... do anything ....

再び複雑さは -それは正しいですか?O2

この場合、実際の効率と理論上の複雑さの間に違いはありますか?これらの1つは他よりも高速ですか?


1
The Art of Unix Programmingで引用されているRob Pikeのルール3 :「ルール3。ファンシーアルゴリズムは、小さいnと遅く、n通常は小さい。ファンシーアルゴリズムには大きな定数があります。n頻繁に大きくなることがわかるまでは、ファンシーにならないでください。」 これは、以下の回答で明確に定義されている理論上の複雑さと実際の効率の違いによるものです。
ワイルドカード2016年

@ワイルドカードそれは良い経験則のようです。いくつかの競合アルゴリズムのベンチマークはさらに良いでしょう。
G.バッハ

@ワイルドカード非常に興味深い引用。プロシージャを設計/実装するときに複雑さを考えるのは常に興味深いことですが、問題のプロシージャがボトルネックと思われるまで、私は通常それらに頭をぶつけません。
Auberon 2016年

回答:


7

ビッグオーフォーマル

Of={g|c>00>0>00gcf}

非公式にビッグオー

Of は、より遅く(または同等に速く)成長する関数のセットです。 f。これは、選択した機能が何であっても、Of、彼女に名前を付けましょう g、そしてあなたは十分に大きなものを選ぶ f よりも大きくなりますg。または、言い換えれば、f 最終的にはすべての機能を上回ります Of いつ 大きくなる。 アルゴリズムの入力サイズです。


例として。選びましょうf=2

と言える f(n)O(n3)。時間の経過とともに、私たちは表記の乱用を許可したので、ほとんどの人が書いていることに注意してくださいf(n)=O(n3) 今。

通常、アルゴリズムを評価するときは、その順序を調べます。このように、我々は予測することができますどのようにアルゴリズムの実行中の時間(とき入力サイズを大きくしますn)増加します。

あなたの例では、両方のアルゴリズムが正しいです O(n2)。したがって、実行時間は(二次的に)と同じ方法で増加します。n増加します。2番目のアルゴリズムは最初のアルゴリズムより4倍遅くなりますが、これは通常、**理論的には*関心がないものです。同じ順序のアルゴリズムは、異なる要素を持つ可能性があります(c正式な定義では)、またはステップ数を評価する関数内の異なる下位項。しかし、それは通常、実装の詳細によるものであり、私たちはそれに関心がありません。

実行するアルゴリズムがある場合 O(log(n)) 私たちは安全にそれがより速いと言うことができる時間 O(n) [1]なぜなら log(n)=O(n)。どんなに悪いO(log(n)) アルゴリズムが実装されている場合、アルゴリズムにどの程度のオーバーヘッドを加えても、常に[1]より高速になります。 O(n)アルゴリズム。アルゴリズムのステップ数が9999log(n)=O(log(n)) そして 0.0001n=O(n)O(log(n)) アルゴリズムは最終的に高速になります[1]。

しかし、多分、あなたのアプリケーションでは、 n は常に低く、十分な大きさになることはないため、 O(log(n))アルゴリズムは実際には高速なります。したがって、O(n) にもかかわらず、アルゴリズムは実行時間を短縮します =Olog

[1]もし 十分に大きいです。


1
Oログ 常により速いとは限りません O1。それはの値に依存しますそして隠された定数について。代表的な例は、高速な行列乗算ですが、実際には高速ではありません。
Yuval Filmus

それが私が追加した理由です:nが十分に大きい場合。あなたが言及した場合、行列が十分に大きくなると、Olog定義により高速になります
Auberon 2016年

あなたの言っていることがすべて私の答えに含まれていませんか?
Auberon 2016年

7
OPは理論と実践の違いについて尋ねますが、あなたはそれを無視しています。漸近記法は、実際には常にではありませんが、通常は役に立ちます。実行時間を4倍に改善すると、実際には大きな違いが生じる可能性がありますが、漸近表記は完全にそれを意識していません。
Yuval Filmus

5

オーブロンはビッグオーの非常に良い説明を提供しました。それがあなたにとって何を意味するかを説明しようと思います。

あなたの最初は正しいです。最初のコード例は24 反復ですが、まだ複雑さのクラスにあります O(n^2)ます。

どうして?

複雑性クラスについてのことは、何かを数回実行することは、 でですランタイムにとって悪いです。

複雑なアルゴリズムを想像してください O(2^n)実行をn=31秒で、1秒かかる。

これを10回実行しても、約10秒後に応答が期待できます。

n、10 ずつ増加することを想像してください。プログラムは2^10=1024数秒かかります。

したがって、コンピュータ科学者は基本的に次のように述べています。「人間、主要な要因は迷惑です。nが無限大に成長し、そこで関数を比較すると仮定しましょう

ビッグOにつながる。

実際には

実際には、非常に複雑なソリューションが(「小さな」入力の場合)はるかに速く実行される可能性は十分にあります。実行されるO(n)10^10*n反復が必要なプログラムを想像するのは簡単です。

O(n)ですが、O(2^n)小さい場合は解で高速になる可能性があります。

要約すれば:

ビッグOは便利なツールです。ただし、アルゴリズムが実際にどれほど高速であるかを考える必要があります。これは、入力が大きくなった場合に必要な時間だけを表すためです。


3

この疑似コードがある場合:

for i=0 to n/2 do
   for j=0 to n/2 do 
       ... do anything ....

反復回数は 2/4

実際には 1+/22=2/4++1

このプログラムの複雑さは何ですか?正しいO2

それは完全に「何でもする」が何であるかに依存します。たとえば、「何でもする」が次の行に置き換えられた場合

for k=0 to 2^n do {}

その後、実行時間は Θ22

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.