Big O記法の実用的なJavaの例

Big O表記の実用的なJavaの例

1. 概要

このチュートリアルでは、Big O Notation means. We’ll go through a few examples to investigate its effect on the running time of your code.が何であるかについて説明します

2. BigO表記の直感

performance of an algorithm described using Big O Notation.をよく耳にします

アルゴリズムのパフォーマンス、またはアルゴリズムの複雑さの研究は、algorithm analysisの分野に分類されます。 アルゴリズム分析は、ディスクスペースや時間など、アルゴリズムが消費するリソースの数の質問に答えます。

時間をリソースとして検討します。 通常、アルゴリズムが完了するまでの時間が短いほど効果的です。

3. 一定時間アルゴリズム–O(1)

アルゴリズムのこの入力サイズは、実行時間にどのように影響しますか? Key to understanding Big O is understanding the rates at which things can grow.ここで問題のレートはtime taken per input size.です

次の簡単なコードを検討してください。

int n = 1000;
System.out.println("Hey - your input is: " + n);

明らかに、上記のnが何であるかは問題ではありません。 このコードは、実行に一定の時間がかかります。 nのサイズには依存しません。

同様に:

int n = 1000;
System.out.println("Hey - your input is: " + n);
System.out.println("Hmm.. I'm doing more stuff with: " + n);
System.out.println("And more: " + n);

上記の例も一定時間です。 実行に3倍の時間がかかる場合でも、doesn’t depend on the size of the input, n.一定時間アルゴリズムを次のように表します:O(1)O(2)O(3)、さらにはO(1000)も同じことを意味することに注意してください。

実行にかかる時間を正確に気にする必要はありません。一定の時間がかかるだけです。

4. 対数時間アルゴリズム–O(log n)

一定時間アルゴリズムは(漸近的に)最も高速です。 Logarithmic time is the next quickest.残念ながら、想像するのは少し難しいです。

対数時間アルゴリズムの一般的な例の1つは、binary searchアルゴリズムです。 Javaでバイナリ検索を実装する方法を確認するには、click here.

ここで重要なのは、running time grows in proportion to the logarithm of the input (in this case, log to the base 2):

for (int i = 1; i < n; i = i * 2){
    System.out.println("Hey - I'm busy looking at: " + i);
}

nが8の場合、出力は次のようになります。

Hey - I'm busy looking at: 1
Hey - I'm busy looking at: 2
Hey - I'm busy looking at: 4

単純なアルゴリズムはlog(8)= 3回実行しました。

5. 線形時間アルゴリズム–O(n)

対数時間アルゴリズムの後、次に速いクラスを取得します:linear time algorithms.

何かが線形に成長すると言う場合、入力のサイズに直接比例して成長することを意味します。

単純なforループを考えてください:

for (int i = 0; i < n; i++) {
    System.out.println("Hey - I'm busy looking at: " + i);
}

このforループは何回実行されますか? もちろん、n回! これが実行されるのにどれくらいの時間がかかるかは正確にはわかりません。それについては心配していません。

私たちが知っていることは、上に示した単純なアルゴリズムは、その入力のサイズに比例して大きくなるということです。

実行時間は(1000n + 1000)よりも0.1nの方が望ましいですが、どちらも線形アルゴリズムです。それらは両方とも、入力のサイズに比例して直接成長します。

再び、アルゴリズムが次のように変更された場合:

for (int i = 0; i < n; i++) {
    System.out.println("Hey - I'm busy looking at: " + i);
    System.out.println("Hmm.. Let's have another look at: " + i);
    System.out.println("And another: " + i);
}

ランタイムは、入力のサイズnで線形になります。 線形アルゴリズムを次のように表します:O(n)

一定時間アルゴリズムと同様に、ランタイムの詳細は気にしません。 O(2n+1) is the same as O(n)、Big ONotationは入力サイズの増加に関係しているため。

6. NログN時間アルゴリズム–O(n log n)

n log n is the next class of algorithms.実行時間は、入力のn log nに比例して増加します。

for (int i = 1; i <= n; i++){
    for(int j = 1; j < 8; j = j * 2) {
        System.out.println("Hey - I'm busy looking at: " + i + " and " + j);
    }
}

たとえば、nが8の場合、このアルゴリズムは8 * log(8) = 8 * 3 = 24回実行されます。 forループに厳密な不等式があるかどうかは、Big O表記のために無関係です。

7. 多項式時間アルゴリズム–O(np)

次は、多項式時間アルゴリズムです。 これらのアルゴリズムは、n log nアルゴリズムよりもさらに低速です。

多項式という用語は、2次(n2)、3次(n3)、4次(n4)などを含む一般的な用語です。 関数。 What’s important to know is that O(n2) is faster than O(n3) which is faster than O(n4), etc.

二次時間アルゴリズムの簡単な例を見てみましょう。

for (int i = 1; i <= n; i++) {
    for(int j = 1; j <= n; j++) {
        System.out.println("Hey - I'm busy looking at: " + i + " and " + j);
    }
}

このアルゴリズムは82 = 64回実行されます。 別のforループをネストする場合、これはO(n3)アルゴリズムになることに注意してください。

8. 指数時間アルゴリズム–O(k _n)_

今、私たちは危険な領域に入りつつあります。これらのアルゴリズムは、入力サイズによって指数化されるいくつかの要因に比例して大きくなります。

たとえば、O(2n) algorithms double with every additional input.したがって、n = 2の場合、これらのアルゴリズムは4回実行されます。 n = 3の場合、8回実行されます(対数時間アルゴリズムの反対のようなものです)。

O(3n)アルゴリズムは、入力が追加されるたびに3倍になり、O(kn)アルゴリズムは、入力が追加されるたびにk倍大きくなります。

O(2n)時間アルゴリズムの簡単な例を見てみましょう。

for (int i = 1; i <= Math.pow(2, n); i++){
    System.out.println("Hey - I'm busy looking at: " + i);
}

このアルゴリズムは28 = 256回実行されます。

9. 階乗時間アルゴリズム–O(n!)

ほとんどの場合、これはそれが得るのと同じくらい悪いです。 このクラスのアルゴリズムの実行時間は、入力サイズのfactorialに比例します。

この典型的な例は、ブルートフォースアプローチを使用してtraveling salesmanの問題を解決することです。

巡回セールスマン問題の解決策の説明は、この記事の範囲外です。

代わりに、前のセクションのように、単純なO(n!)アルゴリズムを見てみましょう。

for (int i = 1; i <= factorial(n); i++){
    System.out.println("Hey - I'm busy looking at: " + i);
}

ここで、factorial(n)は単にn!を計算します。 nが8の場合、このアルゴリズムは8! = 40320回実行されます。

10. 漸近関数

Big O is what is known as an asymptotic function.これはすべて、アルゴリズムのパフォーマンスに関係していることを意味します。at the limit –つまり、 -大量の入力がスローされたとき。

Big Oは、アルゴリズムが小さいサイズの入力でどれだけうまく機能するかを気にしません。 これは、大量の入力に関係しています(100万個の数値のリストを並べ替えることを考えてください。 5つの数字のリストを並べ替えます)。

もう1つの注意点は、there are other asymptotic functions.のBigΘ(シータ)とBigΩ(オメガ)の両方が限界のアルゴリズムを記述していることです(the limitは、これは巨大な入力を意味するだけです)。

これらの3つの重要な関数の違いを理解するには、まず、Big O、BigΘ、BigΩのそれぞれがset(つまり、要素のコレクション)を表すことを知る必要があります。

ここでは、セットのメンバーはアルゴリズムそのものです。

  • Big Oは、特定の速度よりもno worseを実行するすべてのアルゴリズムのセットを表します(これは上限です)。

  • 逆に、BigΩは、特定の速度よりもno betterを実行するすべてのアルゴリズムのセットを表します(これは下限です)。

  • 最後に、BigΘは、atを特定の速度で実行するすべてのアルゴリズムのセットを記述します(平等のようなものです)

上記の定義は数学的に正確ではありませんが、理解に役立ちます。

Usually, you’ll hear things described using Big Oですが、BigΘとBigΩについて知っていても問題ありません。

11. 結論

この記事では、Big O表記と、understanding the complexity of an algorithm can affect the running time of your code.の方法について説明しました。

さまざまな複雑さのクラスcan be found here.の優れた視覚化

いつものように、このチュートリアルのコードスニペットはover on GitHubにあります。