web-dev-qa-db-ja.com

アルゴリズムがOであるかどうかの判別(log n)

私のCS理論を更新しています。アルゴリズムO(log n)の複雑さを特定する方法を知りたいです。具体的には、それを識別する簡単な方法はありますか?

O(n)を使用すると、通常、ループが1つになります。 O(n ^ 2)は二重ループです。 O(n ^ 3)はトリプルループなどです。O(log n)はどうですか?

26
Atif

O(n)を使用すると、通常、ループが1つになります。 O(n ^ 2)は二重ループです。 O(n ^ 3)はトリプルループなどです。O(log n)はどうですか?

あなたは本当にここでそれを間違った方法で行っています。どのbig-O式が特定のアルゴリズム構造に適合するかを記憶しようとしていますが、実際には、アルゴリズムに必要な演算の数を数え、それを入力のサイズと比較するだけです。入力全体をループするアルゴリズムは、ループが1回であるのではなく、ループがn回実行されるため、O(n)パフォーマンスを発揮します。O(log n)パフォーマンスの単一ループは次のとおりです。 :

for (i = 0; i < log2(input.count); i++) {
    doSomething(...);
}

したがって、必要な操作の数が次数であるアルゴリズムはすべて、入力サイズの対数はO(log n)です。 big-O分析が示す重要なことは、入力のサイズに対してアルゴリズムの実行時間がどのように変化するかです。入力のサイズを2倍にすると、アルゴリズムはさらに1ステップを実行します(O(log n)) 、2倍のステップ(O(n))、4倍のステップ(O(n ^ 2))など。

入力を繰り返し分割するアルゴリズムは通常、パフォーマンスのコンポーネントとして「log n」を持っていることを経験から知るのに役立ちますか?承知しました。しかし、パーティショニングを探すのではなく、アルゴリズムのパフォーマンスがO(log n)であるという結論にジャンプします。これは、O(n log n)のようなもので、かなり異なります。

33
Caleb

考え方は、アルゴリズムがO(log n)であり、構造を1ずつスクロールする代わりに、構造を半分に何度も繰り返し、分割ごとに一定数の操作を行う場合です。回答スペースが分割され続ける検索アルゴリズムはO(log n)です。この例は binary search です。ここで、番号が見つかるまで、順序付けられた配列を半分に繰り返し分割し続けます。

注:必ずしも半分に分割する必要はありません。

26
Casey Patton

典型的な例は、バイナリサーチを扱うものです。たとえば、 バイナリ検索アルゴリズム は通常O(log n)です。

バイナリ検索ツリー がある場合、ルックアップ、挿入、削除はすべてO(log n)の複雑さです。

スペースを継続的に分割する状況では、多くの場合_log n_コンポーネントが関係します。多くのソートアルゴリズムがO(nlog n)の複雑さを持っているのはこのためです。これは、多くの場合、セットを分割し、それらをソートするためです。

2
Kris Harper

「単一ループ-> O(n)、二重ループ-> O(n ^ 2)」のように単純にしたい場合、答えはおそらく「ツリー-> O(log n)」です。より正確に木を根から1つ(すべてではない)の葉まで、またはその逆にトラバースします。ただし、これらはすべて単純化しすぎです。

1
scarfridge

アルゴリズムがO(log N)かどうかを識別する簡単な方法があるかどうかを知りたいとします。

さて:実行して時間を計るだけです。入力1.000、10.000、100.000、100万に対して実行します。

実行時間が3,4,5,6秒(または数倍)のように見える場合は、O(log N)と安全に言えます。 1,10,100,1000秒のような場合は、おそらくO(N)です。そして、それが3,40,500,6000秒のような場合、それはO(N log N)です。

0
Pieter B