web-dev-qa-db-ja.com

O(n log n)vs O(n)-時間の複雑さの実際的な違い

_n log n > n_-しかし、これは_pseudo-linear_関係のようなものです。 _n=1 billion_の場合、ログn〜30;

したがって、_n log n_は_30 billion_、つまり_30 X n_、nの順序になります。 _n log n and n_のこの時間の複雑さの違いは、実際の生活で重要かどうか疑問に思っています。

例:並べ替えられていない配列でk番目の要素を見つける_quick select_は、クイック選択アルゴリズムを使用したO(n)です。

配列を並べ替えてk番目の要素を見つけると、O(n log n)になります。 _1 trillion_要素で配列をソートするには、quicksortと_60 times_を実行すると_index it_遅くなります。

37
brain storm

Big-O表記の主な目的は、投稿で行ったような見積もりを行い、通常より高度なアルゴリズムをコーディングするのに労力を費やすことが、追加のCPUサイクルの価値があるかどうかを自分で決めることです。そのコードの改善を購入します。状況に応じて、データセットが比較的小さい場合でも、異なる答えが得られる場合があります。

  • モバイルデバイスで実行しており、アルゴリズムが実行時間のかなりの部分を占める場合、CPUの使用を削減することは、バッテリ寿命の延長につながります
  • 高頻度取引システムなど、オールオアナッシングの競争環境で実行している場合、マイクロ最適化は、お金を稼ぐこととお金を失うことを区別する可能性があります
  • 問題のアルゴリズムがサーバー環境での実行時間を支配していることをプロファイリングが示している場合、より高速なアルゴリズムに切り替えると、すべてのクライアントのパフォーマンスが向上する場合があります。

Big-O表記法が隠すもう1つのことは、定数乗算係数です。たとえば、Quick Selectには非常に合理的な乗数があり、非常に大きなデータセットでQuick Selectを使用することで時間を節約できます。

留意する必要があるもう1つのことは、スペースの複雑さです。非常に多くの場合、O(N*Log N)時間の複雑さを持つアルゴリズムは、O(Log N)スペースの複雑さを持ちます。これは、非常に大きなデータセットの場合に問題を引き起こす可能性があります。たとえば、制限されたスタック容量のシステムで再帰関数が実行される場合などです。

55
dasblinkenlight

場合によります。

私はAmazonで働いていましたが、リストで線形検索を行う方法がありました。 Hashtableを使用して、O(1) O(n)と比較して)を検索できます。

変更を提案しましたが、承認されませんでした。入力が小さいため、それほど大きな違いはありません。

ただし、入力が大きい場合は違いが生じます。

データ/入力が膨大な別の会社では、ツリーを使用して、リストと比較して大きな違いが生じました。そのため、アプリケーションのデータとアーキテクチャに依存します。

オプションと最適化の方法を知ることは常に良いことです。

29
DarthVader

数十億(およびそれ以上)の要素を使用する場合がありますが、その違いは確かに重要です。

1000未満の要素を使用して作業する場合もありますが、その場合、違いはおそらくそれほど重要ではありません。

あなたのデータがどのように見えるかについてまともなアイデアを持っているなら、最初からどれを選ぶべきかについてまともなアイデアを持っている必要がありますが、O(n)とO(n log n )十分に小さいので、おそらく最も単純なものから始めてベンチマークを行い、遅すぎると思われる場合にのみ改善を試みるのが最善です。

ただし、nの任意の値(=必ずしも小さいというわけではありませんが、nの値が小さい場合)では、O(n)は実際にはO(n log n)よりも遅くなる可能性がありますbig-Oはそれらを無視するため(nが無限大になった場合にのみ何が起こるかを考慮するため)、一定の要因が関係します。

11
Dukeling

ダースベイダーは正しいです。それは常に依存します。また、複雑さは漸近的で、最悪の場合(通常)であり、定数は削除されることを覚えておくことが重要です。これらはそれぞれ考慮することが重要です。

したがって、2つのアルゴリズムを使用できます。1つはO(n)で、もう1つはO(nlogn)です。また、宇宙の原子数までのすべての値( n)の有限値に対して、O(nlogn)アルゴリズムは、O(n)アルゴリズムよりも優れています。これは、低次の項が支配的であるため、または、平均的な場合、O(nlogn)アルゴリズムが実際にO(n)であるか、実際のステップ数が5,000,000n対3nlognのようなものであることが原因である可能性があります。

3
gms7777

PriorityQueueは、Collections.sort()を使用して一度にすべての要素を並べ替えるときに、追加する各要素を並べ替えます。ただし、最大の要素をできるだけ早く取得したいという問題がある場合は、一部の計算を実行する必要があるが、要素を並べ替える必要がある場合はPriorityQueueを使用し、Collections.SortでArrayListを使用するのが最適です

0
Amit_Hora