「Big O」表記のわかりやすい英語の説明とは何ですか?


4935

できるだけ形式的な定義はせず、単純な数学を好みます。


57
概要:アルゴリズムの複雑さの上限。同様の質問Big Oも参照してください。どのように計算/近似しますか?良い説明のために。
Kosi2801 2009年

6
他の答えは非常に良いですが、それを理解するための1つの詳細です。O(log n)または同様の手段は、値自体ではなく、入力の「長さ」または「サイズ」に依存します。これは理解しにくいかもしれませんが、非常に重要です。たとえば、これは、アルゴリズムが各反復で物事を2つに分割しているときに発生します。
Harald Schilly 2009年

15
MIT講座「コンピュータサイエンスとプログラミング入門」の講義8にアルゴリズムの複雑さに捧げ講義がありyoutube.com/watch?v=ewd7Lf2dr5Qそれは完全に平易な英語ではありませんが、ある例で素敵な説明を与えるには、簡単に理解できます。
ivanjovanovic 2010

17
Big Oは、アルゴリズムが最大数の反復を実行すると仮定した場合の、関数の最悪の場合のパフォーマンスの推定です。
Paul Sweatte、2012

回答:


6627

簡単に言うと、これはほぼ確実にBig O表記(上限)とTheta表記「which」(両側の上限)を混同しています。私の経験では、これは実際には非学術的な設定での議論の典型です。混乱を招きましたことをお詫び申し上げます。


Big Oの複雑さは、次のグラフで視覚化できます。

ビッグオー分析

Big-O表記について私が言える最も簡単な定義は次のとおりです。

Big-O表記は、アルゴリズムの複雑さの相対的な表現です。

その文にはいくつかの重要で意図的に選ばれた単語があります。

  • 相対:リンゴとリンゴのみを比較できます。算術乗算を行うアルゴリズムを、整数のリストをソートするアルゴリズムと比較することはできません。しかし、算術演算(1つの乗算、1つの加算)を実行する2つのアルゴリズムを比較すると、意味のあることがわかります。
  • 表現: Big-O(最も単純な形式)は、アルゴリズム間の比較を1つの変数に減らします。その変数は、観察または仮定に基づいて選択されます。たとえば、並べ替えアルゴリズムは通常、比較演算(2つのノードを比較して相対的な順序を決定する)に基づいて比較されます。これは、比較にコストがかかることを前提としています。しかし、比較は安価ですがスワッピングが高価な場合はどうでしょうか?比較を変更します。そして
  • 複雑さ: 10,000要素を並べ替えるのに1秒かかる場合、100万要素を並べ替えるのにどのくらい時間がかかりますか?この場合の複雑さは、他のものに対する相対的な尺度です。

残りを読んだら、戻って上記をもう一度読んでください。

Big-Oの最も良い例は、算術演算です。2つの数値(123456と789012)を取ります。学校で学んだ基本的な算術演算は次のとおりです。

  • 添加;
  • 減算;
  • 乗算; そして
  • 分割。

これらはそれぞれ操作または問題です。これらを解く方法をアルゴリズムと呼びます

追加は最も簡単です。数値を(右側に)並べ、列に数字を追加して、その加算の最後の数値を結果に書き込みます。その数の「十」の部分は次の列に繰り越されます。

これらの数値の加算が、このアルゴリズムで最もコストのかかる操作であると仮定しましょう。これらの2つの数値を加算するには、6桁を加算する必要がある(そしておそらく7桁を運ぶ)ことは当然のことです。2つの100桁の数字を一緒に追加する場合、100を追加する必要があります。2つの 10,000桁の数字を追加する場合、10,000 を追加する必要があります。

パターンがわかりますか?複雑度(演算の数である)は、桁数に直接比例しているNより大きい数です。これをO(n)または線形複雑度と呼びます

減算も同様です(ただし、キャリーではなく借りる必要がある場合があります)。

乗算は異なります。あなたは数字を並べて、一番下の数字の最初の数字を取り、それを順番に一番上の数字の各数字と掛け合わせます。したがって、2つの6桁の数値を乗算するには、36回の乗算を行う必要があります。最終結果を得るためにも、10列または11列の列の追加が必要になる場合があります。

2つの100桁の数値がある場合、10,000の乗算と200の加算を行う必要があります。200万桁の数字の場合、1兆(10 12)の乗算と200万の加算を行う必要があります。

アルゴリズムはn- 2乗でスケーリングするため、これはO(n 2または2次の複雑度です。これは、別の重要な概念を紹介する良い機会です。

複雑さの最も重要な部分のみを気にします。

巧妙なことに、操作の数をn 2 + 2nと表現できることに気づいたかもしれません。しかし、100万桁の数値が2つある例からわかるように、2番目の項(2n)は重要ではなくなります(その段階での総演算の0.0002%を占めます)。

ここでは最悪のシナリオを想定していることがわかります。6桁の数値を乗算するとき、一方が4桁で、もう一方が6桁の場合、乗算は24回しかありません。それでも、「n」、つまり両方が6桁の数値の場合の最悪のシナリオを計算します。したがって、Big-O表記は、アルゴリズムの最悪のシナリオに関するものです。

電話帳

次に考えられる最良の例は電話帳で、通常はホワイトページなどと呼ばれますが、国によって異なります。しかし、私は人を姓、次にイニシャルまたは名、おそらく住所、次に電話番号でリストしたものについて話しています。

1,000,000の名前が含まれている電話帳で "John Smith"の電話番号を検索するようにコンピュータに指示している場合、どうしますか?Sがどこから始まったのかを推測できるという事実(無視できないと仮定しましょう)を無視して、どうしますか?

典型的な実装は、真ん中まで開いて、50万分の1を取り、それを「スミス」と比較することです。たまたまそれが「スミス、ジョン」だったら、本当にラッキーだった。「ジョン・スミス」はその名前の前または後に来る可能性がはるかに高い。それが後である場合は、電話帳の後半を半分に分けて繰り返します。前の場合は、電話帳の前半を半分に分けて繰り返します。等々。

これはバイナリサーチと呼ばれ、気づいているかどうかにかかわらず、プログラミングで毎日使用されます。

したがって、100万人の名前の電話帳で名前を検索する場合、実際にはこれを最大20回実行することで任意の名前を検索できます。検索アルゴリズムを比較する際、この比較は「n」であると判断します。

  • 3つの名前の電話帳の場合、2つの比較が必要です(多くても)。
  • 7の場合、最大3つかかります。
  • 15の場合は4です。
  • 1,000,000の場合、20かかります。

それは驚異的に良いですね。

Big-Oの用語では、これはO(log n)または対数の複雑さです。ここで、問題の対数は、ln(eを底とする)、log 10、log 2またはその他の底になります。O(2n 2)とO(100n 2)が両方ともO(n 2)であるのと同じように、それがまだO(log n)であるかどうかは関係ありません。

この時点で、Big Oを使用してアルゴリズムで3つのケースを判別できることを説明することは価値があります。

  • 最良のケース:電話帳検索での最良のケースは、1つの比較で名前を見つけることです。これはO(1)または一定の複雑さです。
  • 予想されるケース:上で説明したように、これはO(log n)です。そして
  • 最悪の場合:これもO(log n)です。

通常、私たちは最良のケースを気にしません。予想される最悪のケースに関心があります。時々これらのどちらかがより重要になります。

電話帳に戻ります。

あなたが電話番号を持っていて、名前を見つけたい場合はどうなりますか?警察は逆電話帳を持っているが、そのような調査は一般大衆に否定されている。それとも彼らですか?技術的には、通常の電話帳の番号を逆に検索できます。どうやって?

名から始めて、番号を比較します。マッチした場合は、そうでない場合は、次に進みます。電話帳は(とにかく電話番号で)順序付けされていないため、この方法で行う必要があります。

したがって、電話番号を指定して名前を見つけるには(逆引き):

  • 最良のケース: O(1);
  • 予想されるケース: O(n)(500,000の場合); そして
  • 最悪の場合: O(n)(1,000,000の場合)。

巡回セールスマン

これはコンピュータサイエンスで非常に有名な問題であり、言及する価値があります。この問題では、N個の町があります。これらの各町は、一定の距離の道路によって1つ以上の他の町にリンクされています。巡回セールスマンの問題は、すべての町を訪れる最短のツアーを見つけることです。

簡単に聞こえますか?もう一度考えて。

3つの町A、B、Cがあり、すべてのペアの間に道路がある場合は、次のように移動できます。

  • A→B→C
  • A→C→B
  • B→C→A
  • B→A→C
  • C→A→B
  • C→B→A

まあ、実際にはそれより少ないです。これらのいくつかは同等です(たとえば、A→B→CとC→B→Aは同等です。たとえば、同じ道路を逆に使用しているためです)。

実際には、3つの可能性があります。

  • これを4つの町に持っていけば、(iirc)12の可能性があります。
  • 5では60です。
  • 6は360になります。

これは、階乗と呼ばれる数学演算の関数です。基本的に:

  • 5!= 5×4×3×2×1 = 120
  • 6!= 6×5×4×3×2×1 = 720
  • 7!= 7×6×5×4×3×2×1 = 5040
  • 25!= 25×24×…×2×1 = 15,511,210,043,330,985,984,000,000
  • 50!= 50×49×…×2×1 = 3.04140932×10 64

したがって、巡回セールスマン問題のBig-OはO(n!)または階乗または組み合わせの複雑さです。

200の町にたどり着くまでに、従来のコンピューターの問題を解決するのに十分な時間が宇宙に残っていません。

考えること。

多項式時間

私が簡単に触れておきたいもう1つの点は、O(n a)の複雑さをもつアルゴリズムは多項式複雑さを持っていると言われるか、多項式時間で解けるということです。

O(n)、O(n 2)などはすべて多項式時間です。一部の問題は多項式時間では解決できません。このため、世の中にはある物が使われています。公開鍵暗号化はその代表的な例です。非常に大きな数の2つの素因数を見つけることは計算上困難です。そうでなければ、私たちが使用している公開鍵システムは使用できません。

とにかく、ビッグO(改訂版)についての(できればプレーンな英語の)私の説明は以上です。


578
他の回答はO(1)、O(n ^ 2)などの違いを説明することに重点を置いていますが、アルゴリズムはn ^ 2、nlog(n)などにどのように分類できるかを詳しく説明したものです+ 1は、Big Oの表記法を理解するのに役立つ適切な回答
Yew Long

22
big-Oが上限(アルゴリズムによって与えられる)を表し、big-Omegaが下限(通常、特定のアルゴリズムから独立した証明として与えられる)を追加し、big-Thetaが「最適な」アルゴリズムであることを追加することができますその下限に達することは知られています。
mdm

21
これは、最も長い回答を探している場合に適していますが、Big-Oを簡単に説明する回答には適していません。
kirk.burleson 2010

169
-1:これは露骨に間違っています:_ "BigOhはアルゴリズムの複雑さの相対的表現です"。いいえ。BigOhは漸近的な上限であり、コンピュータサイエンスとはかなり独立して存在します。O(n)は線形です。いいえ、あなたはBigOhをシータと混同しています。log nはO(n)です。1はO(n)です。かなり恥ずかしいさBigOhとシータを混乱の基本的なミスを犯すこの回答へのupvotesの数(およびコメント)、...

74
「200の町に着くまでに、従来のコンピューターの問題を解決するのに十分な時間が宇宙に残っていません。」宇宙はいつ終わるのでしょうか?
アイザック

729

アルゴリズムが入力サイズに基づいてスケーリングする方法を示しています。

O(n 2二次複雑度として知られています

  • 1アイテム:1秒
  • 10アイテム:100秒
  • 100アイテム:10000秒

アイテムの数は10倍に増加しますが、時間は10 2倍に増加します。基本的に、n = 10なので、O(n 2)は、スケーリング係数n 2である10 2を提供します。

O(n)線形複雑度として知られています

  • 1アイテム:1秒
  • 10アイテム:10秒
  • 100アイテム:100秒

今回はアイテム数が10倍に増加し、時間も増加します。n = 10なので、O(n)の倍率は10です。

O(1)一定の複雑度として知られています

  • 1アイテム:1秒
  • 10アイテム:1秒
  • 100アイテム:1秒

アイテム数は依然として10倍に増加していますが、O(1)のスケーリングファクターは常に1です。

O(log n)対数複雑度として知られています

  • 1アイテム:1秒
  • 10アイテム:2秒
  • 100アイテム:3秒
  • 1000アイテム:4秒
  • 10000アイテム:5秒

計算回数は、入力値のログによってのみ増加します。したがって、この場合、各計算に1秒かかると仮定すると、入力のログはn必要な時間ですlog n

それはそれの要点です。彼らは数学を削減するので、それは正確にn 2または彼らが言う何でもないかもしれませんが、それがスケーリングの支配的な要因になるでしょう。


5
この定義は正確にはどういう意味ですか?(アイテム数は依然として10倍に増加していますが、O(1)のスケーリング係数は常に1です。)
Zach Smith

105
秒ではなく、操作。また、階乗時間と対数時間を逃しました。
Chris Charabaruk、2010

7
これは、O(n ^ 2)が正確に.01 * n ^ 2 + 999999 * n + 999999で実行されるアルゴリズムを記述している可能性があることを十分に説明していません。アルゴリズムがこのスケールを使用して比較されていることを知っておくことが重要です。比較は、nが「十分に大きい」場合に機能します。Pythonのtimsortは、オーバーヘッドが小さいため、実際には小さな配列に対して挿入ソート(最悪/平均ケースO(n ^ 2))を使用します。
ケーシークボール

6
この答えは、ビッグO表記とシータ表記も混同します。すべての入力に対して1を返すnの関数(通常は単に1と記述されます)は、実際にはO(n ^ 2)にあります(O(1)にもあります)。同様に、一定の時間を要する1つのステップのみを実行する必要があるアルゴリズムも、O(1)アルゴリズムと見なされますが、O(n)およびO(n ^ 2)アルゴリズムとも見なされます。しかし、おそらく数学者とコンピューター科学者はその定義に同意しないでしょう:-/。
Jacob Akkerboom 2013

1
この回答で考慮されているO(log n)の対数の複雑さは10を底としています。一般に、標準は2を底として計算することです。この事実を覚えておいてください。また、@ ChrisCharabarukで言及されているように、複雑さは秒数ではなく操作の数を示します。
Aksh1801 2016

405

Big-O表記法(「漸近的成長」表記法とも呼ばれます)は、原点付近の一定の要因やものを無視した場合の「外観」の関数です。どのようにスケールするかを説明するために使用します。


基本

「十分に」大きな入力の場合...

  • f(x) ∈ O(upperbound)f「より速く成長しない」ことを意味しますupperbound
  • f(x) ∈ Ɵ(justlikethis)f「まったく同じように成長する」という意味justlikethis
  • f(x) ∈ Ω(lowerbound)f「成長は遅くない」を意味しますlowerbound

big-O表記では、一定の要素は考慮されません。関数9x²は「まったく同じように成長する」と言われてい10x²ます。また、big-O 漸近記法は非漸近的なもの(「原点に近いもの」または「問題のサイズが小さい場合に何が起こるか」)を考慮しません。関数10x²は「まったく同じように成長する」と言われ10x² - x + 2ます。

なぜ方程式の小さな部分を無視したいのですか?より大きなスケールを考えると、それらは方程式の大部分によって完全に小さくなります。彼らの貢献は小さく、無関係です。(例のセクションを参照してください。)

別の言い方をすると、無限大に行くときの比率がすべてです。にかかる実際の時間をで除算O(...)すると、大きな入力の制限において一定の係数が得られます。直感的にはこれは理にかなっています。一方を乗算してもう一方を取得できる場合、関数は互いに「スケーリング」します。それは私たちが言うとき...

actualAlgorithmTime(N) ∈ O(bound(N))
                                       e.g. "time to mergesort N elements 
                                             is O(N log(N))"

...これは、「十分に大きい」問題サイズN(原点付近のものを無視する場合)には、次のような定数(たとえば、2.5、完全に構成されている)が存在することを意味します。

actualAlgorithmTime(N)                 e.g. "mergesort_duration(N)       "
────────────────────── < constant            ───────────────────── < 2.5 
       bound(N)                                    N log(N)         

定数には多くの選択肢があります。多くの場合、「最良の」選択はアルゴリズムの「定数係数」として知られていますが、最大でない項を無視するように、しばしば無視します(通常、重要ではない理由については、定数係数のセクションを参照してください)。また、上記の方程式を「最悪のシナリオではN*log(N)、2.5倍以内(私たちがあまり気にしない一定の係数)以内で、おおよそよりも悪くなることはありません」と言って、限界と考えることもできます。 。

O(...)ワーストケースの振る舞いを気にすることが多いため、一般的にはが最も便利です。f(x)がプロセッサまたはメモリの使用量のような「悪い」ものを表す場合、「f(x) ∈ O(upperbound)」はupperbound、プロセッサ/メモリの使用量の最悪のシナリオであることを意味します。


用途

純粋に数学的構造として、big-O表記は処理時間とメモリの話に限定されません。これを使用して、以下のような、スケーリングが意味のあるあらゆるものの漸近性について議論できます。

  • Nパーティーの人々の間で可能なハンドシェイクの数(Ɵ(N²)特にN(N-1)/2、重要なのは、それが「のようにスケールする」ことです
  • 時間の関数としてバイラルマーケティングを見た確率的な予想人数
  • CPU、GPU、またはコンピュータークラスターのプロセッシングユニットの数に応じてWebサイトのレイテンシがどのように変化するか
  • トランジスタ数、電圧などの関数として、CPUダイでの熱出力のスケーリング方法
  • 入力サイズの関数として、アルゴリズムの実行に必要な時間
  • 入力サイズの関数として、アルゴリズムを実行するために必要なスペースの量

上記のハンドシェイクの例では、部屋にいる全員が他の全員の手を振っています。その例では、#handshakes ∈ Ɵ(N²)。どうして?

少しバックアップしてください:ハンドシェイクの数はちょうどn-choose-2またはN*(N-1)/2(N人はそれぞれN-1人の他の人と握手しますが、これはダブルカウントのハンドシェイクなので2で割ります):

誰もが他の全員と握手します。 Wikipedia / Wikimedia commonsの「完全なグラフ」記事ごとの画像クレジットとライセンス。 隣接行列

ただし、非常に多くの人数の場合、線形項Nは小さめであり、比率に実質的に0を提供します(グラフでは、参加者の数が増えるにつれて、ボックス全体に対する対角線上の空のボックスの割合が小さくなります)。したがって、スケーリングの動作はorder N²、またはハンドシェイクの数が「N²のように大きくなる」です。

#handshakes(N)
────────────── ≈ 1/2
     N²

これは、グラフの対角線上の空のボックス(N *(N-1)/ 2チェックマーク)がそこにもなかったかのようです(N 2チェックマークは漸近的に)。

(「平易な英語」からの一時的な脱線:)これを自分で証明したい場合は、単純な代数を実行して比率を複数の用語に分割することができます(limつまり、「制限があると見なされている」ことを意味します。それを見たことがない、それは単に「そしてNは本当に本当に大きい」という表記です):

    N²/2 - N/2         (N²)/2   N/2         1/2
lim ────────── = lim ( ────── - ─── ) = lim ─── = 1/2
N→∞     N²       N→∞     N²     N²      N→∞  1
                               ┕━━━┙
             this is 0 in the limit of N→∞:
             graph it, or plug in a really large number for N

tl; dr:大きな値の場合、ハンドシェイクの数はx²に非常に似ているため、比率#handshakes /x²を書き留めると、正確に x²ハンドシェイクが必要ないという事実は表示されません。 10進数で任意の長い間。

たとえば、x = 1millionの場合、比率#handshakes /x²:0.499999 ...


直感の構築

これにより、次のようなステートメントを作成できます...

「十分な大きさのinputsize = Nの場合、定数係数が何であっても、入力サイズ2倍にすると ...

  • ... O(N)( "線形時間")アルゴリズムにかかる時間を2倍にします。 "

    N →(2N)= 2(N

  • ...私は二重乗(四)時間O(N²)(「次の時間」)アルゴリズムがかかります。」(例:A問題100Xビッグは限り100²= 10000倍を取るよう...多分持続不可能)

    →(2N)²= 4(

  • ... Iダブル乗(8倍速)時間O(N³)(「キュービック時間」)アルゴリズムがかかります。」(例えば、問題100Xを大に限り= 1000000x100³をとるよう...非常に持続不可能)

    cN³ →c(2N)³= 8(cN³

  • ... O(log(N))( "logarithmic time")アルゴリズムにかかる時間に固定量を追加します。(安い!)

    c log(N) →c log(2N)=(c log(2))+(c log(N))=(固定量)+(c log(N)

  • ... O(1)(「一定の時間」)アルゴリズムにかかる時間は変更しません。」(最も安い!)

    c * 1c * 1

  • ... O(N log(N))アルゴリズムにかかる時間を「(基本的に)2倍にする」(かなり一般的)

    O(N 1.000001)未満であり、基本的に線形と呼んでもかまいません。

  • ... O(2 N)( "指数時間")アルゴリズムにかかる時間を途方もなく増やします。(問題を1つの単位で増やすだけで、時間は2倍(または3倍など)になります)

    2 N →2 2N =(4 N)............別の言い方をすると...... 2 N →2 N + 1 = 2 N 2 1 = 2 2 N

[数学的に傾いている場合は、ネタバレにネタバレすることができます]

https://stackoverflow.com/a/487292/711085へのクレジット付き)

(技術的には、一定の係数がより難解な例では問題になる可能性がありますが、私は上記のように(たとえば、log(N)で)そうしないように言いました)

これらは、プログラマーと応用コンピューター科学者が参照ポイントとして使用する、成長の大まかな順序です。彼らはいつもこれらを見ています。(つまり、「入力を2倍にすると、O(√N)アルゴリズムは1.414倍遅くなる」と技術的に考えることはできますが、「これは対数よりも悪いが、線形よりも優れている」と考えるのが良いでしょう。)


一定の要因

通常、特定の定数因子が何であるかは関係ありません。これらは関数の成長に影響を与えないためです。たとえば、2つのアルゴリズムはどちらもO(N)完了するのに時間がかかる場合がありますが、一方が他方の2倍遅くなる場合があります。最適化はトリッキーなビジネスであるため、通常、要素が非常に大きくない限り、あまり気にしません(最適化は時期尚早ですか?)。また、より良いbig-Oを持つアルゴリズムを選択するという単なる行為は、しばしば桁違いにパフォーマンスを改善します。

いくつかの漸近的に優れたアルゴリズム(非比較O(N log(log(N)))ソートなど)は、非常に大きな定数係数(例100000*N log(log(N)):)、またはO(N log(log(N)))非表示のように比較的大きなオーバーヘッドがあり+ 100*N、「ビッグデータ」でも使用する価値はほとんどありません。


なぜO(N)があなたにできるベストなのか、つまりなぜデータ構造が必要なのか

O(N)すべてのデータを読み取る必要がある場合、アルゴリズムはある意味で「最良の」アルゴリズムです。読書という行為データの束があるO(N)操作。通常、メモリへのロードはO(N)(ハードウェアサポートがある場合は高速で、すでにデータを読み取っている場合はまったく時間がかかりません)。ただし、すべてのデータ(または他のすべてのデータ)を触ったり、たりすると、アルゴリズムはO(N)この見回しに時間がかかります。実際のアルゴリズムにどれほど時間がかかるとしてもO(N)、すべてのデータを調べるのにその時間を費やしたためです。

書くこと自体も同じことが言えます。Nのものを出力するすべてのアルゴリズムは、出力が少なくともその長さであるため、N時間かかります(たとえば、N個のトランプのセットを並べ替えて(再配置するために)出力することは階乗です:) O(N!)

これにより、データ構造の使用が促進されます。データ構造では、データを1回だけ(通常はO(N)時間)読み取るだけでなく、任意の量の前処理(O(N)or O(N log(N))またはO(N²))を使用して、小さく保つ必要があります。その後、データ構造(挿入/削除など)の変更とデータに対するクエリの実行には、O(1)またはのような非常に短い時間がかかりO(log(N))ます。次に、多数のクエリを作成します。一般に、事前に実行する作業が多いほど、後で実行する必要のある作業は少なくなります。

たとえば、何百万もの道路セグメントの緯度と経度の座標があり、すべての交差点を検索したいとします。

  • 単純な方法:道路の交差点の座標があり、近くの道路を調べたい場合は、毎回何百万ものセグメントを調べて、隣接関係を確認する必要があります。
  • これを1回だけ実行する必要がある場合、単純なO(N)作業方法を1回だけ実行する必要はありませんが、何度も実行する場合(この場合は、N各セグメントに対して1回)、O(N²)仕事をする必要がある、または1000000²= 1000000000000操作。良くない(最近のコンピューターは1秒あたり約10億の操作を実行できる)。
  • ハッシュテーブル(インスタントルックアップテーブル、ハッシュマップまたはディクショナリとも呼ばれます)と呼ばれる単純な構造を使用する場合、O(N)時間内にすべてを前処理することで小さなコストを支払います。その後、そのキーで何かを検索するのに平均して一定の時間しかかかりません(この場合、キーは緯度と経度の座標であり、グリッドに丸められます。隣接するグリッドスペースは9つしかなく、絶え間ない)。
  • 私たちの仕事は実行不可能なものO(N²)から管理可能なものO(N)になり、ハッシュテーブルを作成するためにわずかなコストを支払うだけで済みました。
  • アナロジー:この特定のケースでのアナロジーはジグソーパズルです。データのいくつかのプロパティを利用するデータ構造を作成しました。道路セグメントがパズルのピースのようなものである場合、色とパターンを一致させることによってそれらをグループ化します。次に、これを利用して、後で余分な作業を行わないようにします(同じ色のパズルのピースを、他のすべてのパズルのピースと比較するのではなく)。

話の教訓:データ構造により、運用をスピードアップできます。さらに、高度なデータ構造により、驚くほど巧妙な方法で操作を結合、遅延、または無視することもできます。さまざまな問題にはさまざまな類推がありますが、それらはすべて、気になる、または簿記のために人為的に課した構造を利用する方法でデータを編成することを伴います。私たちは事前に作業を行い(基本的に計画と整理)、今や繰り返されるタスクははるかに簡単です!


実用例:コーディング中に成長の順序を視覚化する

漸近記法は、その中心において、プログラミングとはまったく別のものです。漸近表記法は、物事がどのようにスケーリングし、多くの異なる分野で使用できるかを考えるための数学的なフレームワークです。つまり、これは、コーディングに漸近表記を適用する方法です。

基本:サイズAのコレクション内のすべての要素(配列、セット、マップのすべてのキーなど)とやり取りするとき、またはループのA回の反復を実行するとき(サイズAの乗法因子) 。「乗算因子」と言うのはなぜですか?-ループと関数(ほぼ定義上)には乗算の実行時間があるため:反復回数、ループで実行された回数(または関数の場合:呼び出し回数)関数、時間は関数で行われます)。(これは、ループのスキップやループの早期終了など、特別なことをしない場合や、引数に基づいて関数の制御フローを変更する場合に当てはまります。これは、非常に一般的なものです)。

(ここで、xsは一定時間の作業単位、プロセッサーの命令、インタープリターのオペコードなどを表します)

for(i=0; i<A; i++)        // A * ...
    some O(1) operation     // 1

--> A*1 --> O(A) time

visualization:

|<------ A ------->|
1 2 3 4 5 x x ... x

other languages, multiplying orders of growth:
  javascript, O(A) time and space
    someListOfSizeA.map((x,i) => [x,i])               
  python, O(rows*cols) time and space
    [[r*c for c in range(cols)] for r in range(rows)]

例2:

for every x in listOfSizeA:   // A * (...
    some O(1) operation         // 1
    some O(B) operation         // B
    for every y in listOfSizeC: // C * (...
        some O(1) operation       // 1))

--> O(A*(1 + B + C))
    O(A*(B+C))        (1 is dwarfed)

visualization:

|<------ A ------->|
1 x x x x x x ... x

2 x x x x x x ... x ^
3 x x x x x x ... x |
4 x x x x x x ... x |
5 x x x x x x ... x B  <-- A*B
x x x x x x x ... x |
................... |
x x x x x x x ... x v

x x x x x x x ... x ^
x x x x x x x ... x |
x x x x x x x ... x |
x x x x x x x ... x C  <-- A*C
x x x x x x x ... x |
................... |
x x x x x x x ... x v

例3:

function nSquaredFunction(n) {
    total = 0
    for i in 1..n:        // N *
        for j in 1..n:      // N *
            total += i*k      // 1
    return total
}
// O(n^2)

function nCubedFunction(a) {
    for i in 1..n:                // A *
        print(nSquaredFunction(a))  // A^2
}
// O(a^3)

少し複雑なことをしても、何が起こっているのかを視覚的に想像できるかもしれません。

for x in range(A):
    for y in range(1..x):
        simpleOperation(x*y)

x x x x x x x x x x |
x x x x x x x x x   |
x x x x x x x x     |
x x x x x x x       |
x x x x x x         |
x x x x x           |
x x x x             |
x x x               |
x x                 |
x___________________|

ここで、描くことができる最小の認識可能なアウトラインが重要です。三角形は2次元形状(0.5 A ^ 2)であり、正方形が2次元形状(A ^ 2)であるのと同じです。ここで2の定数因数は2つの間の漸近比に残りますが、すべての因数と同様に無視します...(この手法には、ここでは触れませんが、いくつかの残念なニュアンスがあります。誤解を招く可能性があります。)

もちろん、これはループと関数が悪いことを意味するものではありません。それどころか、これらは現代のプログラミング言語の構成要素であり、私たちはそれらを愛しています。ただし、ループや関数、条件文をデータ(制御フローなど)と共に織り込む方法は、プログラムの時間とスペースの使用を模倣していることがわかります。時間とスペースの使用が問題になる場合は、賢明さに頼り、成長の順序を何らかの形で減らすために、私たちが考慮していなかった簡単なアルゴリズムまたはデータ構造を見つけます。それでも、これらの視覚化手法は(常に機能するとは限りませんが)、最悪の場合の実行時に単純な推測を与える可能性があります。

視覚的に認識できるもう1つの点を次に示します。

<----------------------------- N ----------------------------->
x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x
x x x x x x x x x x x x x x x x
x x x x x x x x
x x x x
x x
x

これを並べ替えて、O(N)であることがわかります。

<----------------------------- N ----------------------------->
x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x
x x x x x x x x x x x x x x x x|x x x x x x x x|x x x x|x x|x

または、O(N * log(N))の合計時間に対して、データのlog(N)パスを実行する場合があります。

   <----------------------------- N ----------------------------->
 ^  x x x x x x x x x x x x x x x x|x x x x x x x x x x x x x x x x
 |  x x x x x x x x|x x x x x x x x|x x x x x x x x|x x x x x x x x
lgN x x x x|x x x x|x x x x|x x x x|x x x x|x x x x|x x x x|x x x x
 |  x x|x x|x x|x x|x x|x x|x x|x x|x x|x x|x x|x x|x x|x x|x x|x x
 v  x|x|x|x|x|x|x|x|x|x|x|x|x|x|x|x|x|x|x|x|x|x|x|x|x|x|x|x|x|x|x|x

無関係ですが、もう一度言及する価値があります。ハッシュ(たとえば、ディクショナリ/ハッシュテーブルルックアップ)を実行する場合、それはO(1)の要素です。それはかなり速いです。

[myDictionary.has(x) for x in listOfSizeA]
 \----- O(1) ------/    

--> A*1 --> O(A)

私たちは、このような再帰関数や分割統治アルゴリズムと同様に、非常に複雑な何かを、行う場合は、あなたが使用できるマスター定理を(通常は動作します)、またはばかばかしい例でAkra-Bazzi定理(ほとんど常に動作します)あなたは、ルックアップウィキペディアでのアルゴリズムの実行時間。

しかし、プログラマーはこのように考えません。結局のところ、アルゴリズムの直感はただの自然になってしまうからです。あなたは非効率的な何かをコーディングし始めて、すぐに「私は非常に非効率的な何かをしているのですか?」と考えます。答えが「はい」であり、それが実際に重要であると思われる場合は、一歩下がってさまざまなトリックを考え、処理を高速化できます(ほとんどの場合、答えは「ハッシュテーブルを使用する」、「ツリーを使用する」、非常にまれに、もう少し複雑です)。


償却および平均ケースの複雑さ

「償却」および/または「平均ケース」の概念もあります(これらは異なることに注意してください)。

平均的なケース:これは、関数自体ではなく、関数の期待値にbig-O表記を使用することにすぎません。すべての入力が等しく可能性があると考える通常のケースでは、平均ケースは実行時間の平均にすぎません。たとえば、クイックソートの場合、最悪のケースはO(N^2)一部の本当に悪い入力に対するものですが、平均的なケースが通常ですO(N log(N))(本当に悪い入力は数が非常に少ないため、平均的なケースでは気付かないほど少ないです)。

償却された最悪のケース:一部のデータ構造は、最悪の場合の複雑さが大きくなる可能性がありますが、これらの操作の多くを実行すると、実行する作業の平均量が最悪の場合よりも良くなることが保証されます。たとえば、通常一定のO(1)時間がかかるデータ構造があるとします。ただし、場合O(N)によっては、簿記やガベージコレクションなどを行う必要があるため、「しゃっくり」して1つのランダムな操作に時間がかかることがあります...しかし、しゃっくりが発生しても、Nで再度しゃっくりしないことを約束します。より多くの操作。最悪の場合のコストは依然としてO(N)操作ごとですが、多くの実行での償却コストはO(N)/N=O(1)操作ごと。大きな操作は非常にまれであるため、大量の不定期の作業は、一定の要素として残りの作業と調和すると考えることができます。作品は、それが漸近的に消えるのに十分な数の呼び出しにわたって「償却」されると言います。

償却分析の類推:

あなたは車を運転します。たまに、ガソリンスタンドまで10分間費やしてから、1分間かけてタンクにガスを補充する必要があります。車でどこかに行くたびにこれを行った場合(ガソリンスタンドまで車で10分かかり、数秒でガロンの一部を埋める)、それは非常に非効率的です。しかし、数日おきにタンクを満タンにすると、ガソリンスタンドまでの運転に費やされた11分間は、十分な数のトリップで「償却」されるため、無視して、すべてのトリップがおそらく5%長くなるように見せかけることができます。

平均ケースと償却最悪ケースの比較:

  • 平均的なケース:入力についていくつかの仮定を行います。つまり、入力に異なる確率がある場合、出力/ランタイムには異なる確率(平均を取る)があります。通常、入力はすべて同じ確率(一様確率)であると想定しますが、実際の入力が「平均入力」の想定に適合しない場合、平均出力/実行時間の計算は無意味になる可能性があります。ただし、一様にランダムな入力が予想される場合、これは考えるのに役立ちます。
  • 償却された最悪のケース:償却された最悪のケースのデータ構造を使用する場合、パフォーマンスは償却された最悪のケースの範囲内であることが保証されます...最終的に(すべてを知っている悪魔によって入力が選択され、ねじ込みます)。通常、これを使用して、予期しない大規模なしゃっくりでパフォーマンスが非常に「途切れる」可能性があるアルゴリズムを分析しますが、時間の経過とともに、他のアルゴリズムと同様に実行されます。(ただし、データ構造に、先延ばしにしたい多くの優れた作業に対する上限がない限り、悪意のある攻撃者は、一度に最大量の先延ばし作業に追いつくように強制する可能性があります。

ただし、攻撃者について合理的に心配している場合は、償却や平均ケースの他に、心配すべき他の多くのアルゴリズム攻撃ベクトルがあります。)

平均ケースと償却の両方は、スケーリングを考慮して設計するための非常に便利なツールです。

(このサブトピックに関心がある場合は、平均ケースと償却分析の違いを参照してください。)


多次元ビッグオー

ほとんどの場合、人々は複数の変数が機能していることを認識していません。たとえば、文字列検索アルゴリズムでは、アルゴリズムに時間がかかる場合がありますO([length of text] + [length of query])。つまり、のような2つの変数では線形O(N+M)です。他のもっと素朴なアルゴリズムは、O([length of text]*[length of query])またはかもしれませんO(N*M)。複数の変数を無視することは、アルゴリズム分析で見られる最も一般的な見落としの1つであり、アルゴリズムを設計するときに不利になることがあります。


一部始終

big-Oがすべてではないことに注意してください。キャッシュを使用して一部のアルゴリズムを大幅に高速化し、それらをキャッシュに気付かなくする、ディスクの代わりにRAMを使用する、並列化を使用する、または事前に作業を行うことでボトルネックを回避する-これらの手法は多くの場合独立している、成長順序とはです「big-O」表記。ただし、並列アルゴリズムのbig-O表記ではコアの数がよく表示されます。

また、プログラムの隠れた制約により、漸近的な振る舞いについてはあまり気にしないかもしれないことにも注意してください。制限された数の値を使用している可能性があります。次に例を示します。

  • 5つの要素のようなものを並べ替える場合は、スピーディを使用したくない O(N log(N))クイックソート。挿入ソートを使用したい場合、これはたまたま小さな入力でうまく機能します。これらの状況は、多くの場合、分割統治アルゴリズムで発生します。このアルゴリズムでは、再帰的な並べ替え、高速フーリエ変換、行列の乗算など、問題をますます小さな副問題に分割します。
  • いくつかの隠された事実のためにいくつかの値が効果的に制限されている場合(たとえば、平均的な人間の名前はおそらく40文字で柔らかく制限されており、人間の年齢はおよそ150で柔らかく制限されています)。入力に境界を課して、項を効果的に一定にすることもできます。

実際には、同じまたは類似の漸近的パフォーマンスを持つアルゴリズムの間でも、それらの相対的なメリットは、実際には次のような他の要因によって駆動される可能性がありO(N log(N))ます。実装の容易さなど、パフォーマンスに関する考慮事項。ライブラリが利用可能かどうか、およびライブラリの信頼性と維持管理の程度。

また、プログラムは、500 GHzコンピュータでは2 GHzコンピュータよりも遅く実行されます。実際の1秒あたりではなく、マシンリソース(たとえば、クロックサイクルごと)の観点からスケーリングを考えるため、これをリソース境界の一部とは見なしません。ただし、エミュレーションで実行しているかどうか、コンパイラがコードを最適化しているかどうかなど、パフォーマンスに「密かに」影響を与える可能性のある同様のものがあります。これらにより、一部の基本的な操作に時間がかかる場合があります(相互に関連する場合も)。また、一部の操作を漸近的に(相互に関連する場合も)スピードアップまたはスローダウンすることさえあります。影響は、実装や環境が異なれば、小さくても大きくてもかまいません。言語やマシンを切り替えて、余分な作業を省きますか?それは他の100の理由(必要性、スキル、同僚、プログラマーの生産性、

上記の問題は、使用するプログラミング言語の選択による影響と同様に、一定の要因の一部と見なされることはほとんどありません(そうである必要もありません)。しかし、時には(まれにですが)物事に影響を与える可能性があるため、それらに注意する必要があります。たとえばcpythonの場合、ネイティブの優先度キューの実装は漸近的に最適O(log(N))ではありO(1)ません(挿入またはfind-minの選択ではありません)。別の実装を使用していますか?おそらくそうではありません。Cの実装はおそらくより高速であり、おそらく他の場所にも同様の問題があるでしょう。トレードオフがあります。時には彼らは重要であり、時にはそうではありません。


編集:「わかりやすい英語」の説明はここで終わります。)

数学の補遺

完全をf(x) ∈ O(g(x))期すために、big-O表記の正確な定義は次のとおりです。つまり、「fはconst * gによって漸近的に上限がある」ことを意味します。xの有限値以下をすべて無視すると、のような定数が存在し|f(x)| ≤ const * |g(x)|ます。(他の記号は次のとおりです:O意味≤、Ω意味≥ と同じです。小文字のバリエーションがあります:o意味<、およびω意味>。)f(x) ∈ Ɵ(g(x))は、両方f(x) ∈ O(g(x))を意味しますf(x) ∈ Ω(g(x))(gの上限と下限):fのようないくつかの定数が存在しますとの間の「バンド」に常にconst1*g(x)ありconst2*g(x)ます。これは、あなたが作ることができる最も強い漸近的なステートメントであり、おおよそ==。(申し訳ありませんが、明確にするために、絶対値記号の説明をこれまで延期することを選択しました。特に、コンピューターサイエンスのコンテキストで負の値が表示されるのを見たことがないためです。)

人々はしばしばを使用します= O(...)。これはおそらくより正確な「comp-sci」表記であり、使用することは完全に正当です。"f = O(...)"は "f is order ... / f is xxx-bounded by ..."と読み、 "fは漸近性が...であるいくつかの式である"と考えられます。私はより厳密なものを使うように教えられました∈ O(...)「の要素」であることを意味します(以前と同じように読みます)。この特定のケースでは、O(N²){ような要素を含む2 N²3 N²1/2 N²2 N² + log(N)- N² + N^1.9、...}と無限大であるが、それはまだセットです。

OとΩは対称ではありません(n = O(n²)ですが、n²はO(n)ではありません)が、Ɵは対称であり、(これらの関係はすべて推移的かつ再帰的であるため)thereforeしたがって、対称的で推移的かつ再帰的です、したがって、すべての関数のセットを等価クラスに分割します。同等クラスとは、私たちが同じと考えるもののセットです。つまり、考えられる任意の関数を指定すると、クラスの正規/一意の「漸近的代表」を見つけることができます(一般に制限を設けることで...と思います)。すべての整数をオッズまたは偶数にグループ化できるのと同じように、Ɵを使用してすべての関数をx-ish、log(x)^ 2-ishなどにグループ化できます。基本的に、小さい項を無視します(ただし、それ自体が別のクラスである、より複雑な関数)。

=表記は、より一般的なものであるかもしれないとさえ世界的に有名なコンピュータ科学者の論文で使用されています。さらに、カジュアルな環境では、人々はO(...)彼らが何を意味するかを言うことがよくありƟ(...)ます。一連の事柄Ɵ(exactlyThis)O(noGreaterThanThis)...のサブセットなので、これは技術的に当てはまります。また、入力も簡単です。;-)


28
優れた数学的な答えですが、OPは単純な英語の答えを求めました。答えを理解するのにこのレベルの数学的記述は必要ありませんが、特に数学を好む人にとっては、「普通の英語」よりも理解する方がはるかに簡単かもしれません。しかしOPは後者を要求しました。
El Zorko 2013

42
おそらく、OP以外の人々がこの質問への回答に関心を持っている可能性があります。それがサイトの基本原則ではありませんか?
ケーシー

6
なぜ人々が私の答えをすくい取り、それがあまりにもまとまりすぎると思うかもしれないのかはおそらくわかりますが(特に、「数学は新しい平易な英語」のスナイスな発言ですが、削除されたため)、元の質問は関数に関するBig-Oについて尋ねているので、明白なことを試み、平易な英語の直感を補足する方法で機能について話します。ここでの数学は、しばしば見過ごされたり、高校の数学の背景で理解されたりすることがあります。私は人々が最後に数学の補遺を見るかもしれないと感じています、そしてそれが答えの一部であると思います、それは本当の数学がどのように見えるかを見るためだけにあるときです。
ninjagecko 2015

5
これは素晴らしい答えです。最も投票数の多いIMOよりもはるかに優れたIMO。必要な「数学」は、「O」の後の括弧内の式を理解するために必要なものを超えないため、例を使用する合理的な説明では回避できません。
Dave Abrahams

1
「f(x)∈O(上限)は、fが単に「上限より速く成長しない」ことを意味します。これらの3つの言葉は単純ですが、大きなOh、Theta、およびOmegaの数学的に適切な説明は黄金です。彼は、複雑な数式を書かないと5つの異なる情報源が私に翻訳されないように思える点を、わかりやすい英語で私に説明しました。ありがとう!:)
timbram 2016

243

編集:クイックノート、これはほぼ確実にBig O表記(上限)とTheta表記(上限と下限の両方)を混同しています。私の経験では、これは実際には非学術的な設定での議論の典型です。混乱を招きましたことをお詫び申し上げます。

一文で:あなたの仕事のサイズが大きくなると、それを完了するのにどれくらい時間がかかりますか?

もちろん、これは入力として「サイズ」を使用し、出力として「所要時間」を使用しているだけです。メモリ使用量などについて話したい場合も同じ考え方が当てはまります。

これは、乾燥させたいN枚のTシャツの例です。それらを乾燥位置に配置するのは信じられないほど迅速であると想定します(つまり、人間の相互作用は無視できます)。もちろん、実際にはそうではありません...

  • 外で洗濯ラインを使用する:無限に大きな裏庭があるとすると、洗濯はO(1)時間で乾燥します。どんなに手に入れても、同じ日差しと新鮮な空気が入るので、サイズは乾燥時間に影響しません。

  • タンブル乾燥機を使用する場合:各荷物に10枚のシャツを入れ、1時間後に完成させます。(ここの実際の数は無視してください—それらは無関係です。)したがって、50枚のシャツを乾燥させると、10枚のシャツを乾燥させる場合の 5倍の時間がかかります。

  • すべてを通気性のある食器棚に入れる:すべてを1つの大きな山に入れて、一般的な暖かさだけをさせると、真ん中のシャツが乾くまでに長い時間がかかります。詳細は推測したくありませんが、これは少なくともO(N ^ 2)だと思います。洗浄負荷を増やすと、乾燥時間が速くなります。

「ビッグO」表記法の重要な側面の1つは、指定されたサイズに対してどのアルゴリズムがより高速になるかが示されていないことです。ハッシュテーブル(文字列キー、整数値)とペア(文字列、整数)の配列を取ります。文字列に基づいて、ハッシュテーブルのキーまたは配列の要素を見つける方が高速ですか?(つまり、配列の場合、「文字列部分が指定されたキーと一致する最初の要素を見つけます。」)ハッシュテーブルは通常、償却されます(〜=「平均して」)O(1)—一度設定すると、約かかります。 100エントリテーブルと1,000,000エントリテーブルのエントリを同時に検索します。(インデックスではなくコンテンツに基づいて)配列内の要素を見つけることは線形です。つまり、O(N)—平均して、エントリの半分を調べる必要があります。

これは、ルックアップ用の配列よりもハッシュテーブルを速くしますか?必ずしも。非常に小さなエントリのコレクションがある場合、配列の方がはるかに高速です。見ているもののハッシュコードを計算するのにかかる時間ですべての文字列をチェックできる場合があります。ただし、データセットが大きくなるにつれて、ハッシュテーブルは最終的に配列を上回ります。


6
ハッシュテーブルは、実際の配列のインデックスを計算するために実行するアルゴリズムを必要とします(実装によって異なります)。そして、配列は単なるアドレスであるため、O(1)を持ちます。しかし、これは質問とは関係なく、単なる観察です:)
Filip Ekberg

7
ジョンの説明は、私が考える質問とは非常に関係があります。それはまさにそれをある母に説明することができる方法であり、彼女は最終的にそれを理解するだろうと私は思う:)私は服の例が好きです(特に最後の例は、複雑さの指数関数的成長を説明しています)
Johannes Schaub-litb

4
フィリップ:インデックスで配列をアドレスすることではなく、配列内の一致するエントリを見つけることです。答えをもう一度読んで、それがまだ不明かどうかを確認できますか?
Jon Skeet、

3
@Filip Ekberg各インデックスがキーに直接マップされる直接アドレステーブルを考えていると思います。したがって、O(1)ですが、Jonは検索する必要があるキー/値のペアの並べ替えられていない配列について話していると思います直線的に。
ljs

2
@RBT:いいえ、バイナリルックアップではありません。ハッシュコードからバケットインデックスへの変換に基づいて、適切なハッシュバケットにすぐに到達できます。その後、バケット内で正しいハッシュコードを見つけることは線形になる場合もあれば、バイナリ検索になる場合もありますが、そのときまでに、辞書の合計サイズのごく一部にまで達しています。
Jon Skeet、2016年

126

Big Oは、入力が大きくなったときの、プログラムのランタイムなど、関数の拡張動作の上限を示します。

例:

  • O(n):入力サイズを2倍にすると、ランタイムは2倍になります

  • O(n 2):入力サイズがランタイムの4倍になる場合

  • O(log n):入力サイズが2倍になると、ランタイムは1増加します

  • O(2 n):入力サイズが1増えると、ランタイムは2倍になります

入力サイズは通常、入力を表すために必要なビット単位のスペースです。


7
不正解です。たとえばO(n):入力サイズを2倍にすると、ランタイムは乗算されて有限の非ゼロ定数になります。つまり、O(n)= O(n + n)
arena-ru

7
私はf(n)= O(g(n))のfについて話しています。
starblue

私は賛成票を投じましたが、最後の文は私が感じるとあまり貢献していません。Big(O)について議論または測定するとき、「ビット」について頻繁に話すことはありません。
cdiggins

5
O(n log n)の例を追加する必要があります。
ChristofferHammarström2011

それはそれほど明確ではありませんが、本質的にはO(n)よりも少し悪い動作をします。ダブルスのNのであれば、ランタイムは2よりも幾分大きなファクターを乗じて
starblue

106

Big O表記は、入力セットのサイズの関数として表される、計算(アルゴリズム)が完了するまでにかかるおおよその時間の目安として、プログラマーによって最も一般的に使用されます。

Big Oは、入力数が増加したときに2つのアルゴリズムがどれだけうまくスケールアップするかを比較するのに役立ちます。

より正確には、関数の漸近的な振る舞いを表すためにBig O表記が使用されます。これは、関数が無限大に近づいたときの動作を意味します。

多くの場合、アルゴリズムの「O」は次のいずれかの場合に該当します。

  • O(1) -入力セットのサイズに関係なく、完了するまでの時間は同じです。例は、インデックスによって配列要素にアクセスすることです。
  • O(Log N) -完了するまでの時間は、log2(n)とほぼ同じように増加します。たとえば、Log2(1024)= 10およびLog2(32)= 5であるため、1024アイテムは32アイテムの約2倍の時間がかかります。例として、バイナリ検索ツリー(BST)でアイテムを検索しています
  • O(N) -入力セットのサイズに線形に比例する、完了までの時間。つまり、入力セットのアイテム数を2倍にすると、アルゴリズムの所要時間は約2倍になります。例は、リンクされたリスト内のアイテムの数を数えることです。
  • O(N Log N) -完了するまでの時間は、アイテム数にLog2(N)の結果を掛けた分だけ増加します。この例として、ヒープソートクイックソートがあります
  • O(N ^ 2) -完了までの時間は、アイテム数の2乗にほぼ等しい。この例は、バブルソートです。
  • O(N!) -完了までの時間は、入力セットの階乗です。この例は、巡回セールスマン問題のブルートフォースソリューションです。

Big Oは、入力サイズが無限大に向かって増加するときに、関数の成長曲線に意味のある方法で寄与しない要素を無視します。つまり、関数に追加または乗算される定数は単に無視されます。


cdiggins、もし私がO(N / 2)の複雑さを持っているとしたら、それがO(N)またはO(N / 2)であるべきか、たとえば、文字列の半分をループする場合の複雑さ。
Melad Basilius

1
@Meladこれは、関数に乗算される定数(0.5)の例です。Nの非常に大きな値に意味のある効果を有すると考えられているように、これは無視される
cdiggins

82

Big Oは、「自分のコードを実行するのにどのくらいの時間/スペースが必要か」という一般的な方法で自分を「表現」する方法にすぎません。

O(n)、O(n 2)、O(nlogn)などがよく表示されますが、これらはすべて表示する方法にすぎません。アルゴリズムはどのように変化しますか?

O(n)は、ビッグOがnであることを意味し、「nとは!」まあ「n」は要素の量です。アレイ内のアイテムを検索するイメージング。あなたは各要素を見て、「あなたは正しい要素/アイテムですか?」最悪の場合、項目は最後のインデックスにあります。つまり、リストに項目があるのと同じくらいの時間がかかったので、一般的に言えば、「ああ、nは与えられた値の量がかなり多いです!」 。

したがって、「n 2」が何を意味するかを理解しているかもしれませんが、さらに具体的に言うと、ソートアルゴリズムの最も単純な単純な考えを試してみてください。バブルソート。このアルゴリズムは、アイテムごとにリスト全体を調べる必要があります。

私のリスト

  1. 1
  2. 6

ここでの流れは次のようになります:

  • 最大の1と6を比較してください。OK 6は正しい位置にあり、前進します!
  • 6と3を比較してください。移動しましょう。リストは変更されました。最初から始める必要があります。

これはO n 2です。「n」個のアイテムがあるリストのすべてのアイテムを見る必要があるためです。各項目について、すべての項目をもう一度見て、比較のために、これも「n」なので、すべての項目について、「n」回見て、n * n = n 2を意味します。

これがあなたが望むように単純であることを願っています。

ただし、Big Oは、時間と空間の方法で自分を飛躍させる方法にすぎないことを覚えておいてください。


logNの場合、0からN / 2で実行されるforループはO(log log N)についてはどうでしょうか?プログラムはどのように見えるのですか?純粋な数学のスキルについてはご容赦ください
Govinda Sakhare

55

Big Oは、アルゴリズムの基本的なスケーリングの性質を説明します。

Big Oが特定のアルゴリズムについて教えてくれない情報はたくさんあります。それは骨を削ぎ、アルゴリズムのスケーリングの性質、特にアルゴリズムのリソース使用(時間またはメモリを考える)が「入力サイズ」に応じてどのようにスケーリングするかについての情報のみを提供します。

蒸気機関とロケットの違いを考えてみましょう。それらは同じものの異なる品種(たとえば、Priusエンジン対Lamborghiniエンジン)であるだけでなく、それらのコアでは劇的に異なる種類の推進システムです。蒸気エンジンはおもちゃのロケットよりも高速かもしれませんが、軌道ロケットの速度を達成できる蒸気ピストンエンジンはありません。これは、これらのシステムが、所定の速度(「入力サイズ」)に到達するために必要な燃料(「リソース使用量」)の関係に関して異なるスケーリング特性を持っているためです。

なぜこれがそれほど重要なのですか?ソフトウェアは、1兆までの要素によってサイズが異なる可能性がある問題を処理するためです。少し考えてみましょう。月への移動に必要な速度と人間の歩行速度の比率は10,000:1未満であり、ソフトウェアが直面する可能性のある入力サイズの範囲と比較すると、それは完全に小さなものです。また、ソフトウェアは入力サイズの天文学的な範囲に直面する可能性があるため、アルゴリズムのBig Oの複雑さの可能性があり、実装の詳細に勝つことは基本的なスケーリングの性質です。

正規のソートの例を考えてみましょう。バブルソートはO(n 2)で、マージソートはO(n log n)です。たとえば、バブルソートを使用するアプリケーションAとマージソートを使用するアプリケーションBの2つの並べ替えアプリケーションがあるとします。約30要素の入力サイズの場合、アプリケーションAはアプリケーションBよりも並べ替えで1,000倍高速です。30を超える要素をソートする必要がない場合は、アプリケーションAを選択する必要があることは明らかです。これは、これらの入力サイズではるかに高速であるためです。ただし、1千万個のアイテムを並べ替える必要がある場合は、各アルゴリズムのスケーリング方法が原因で、アプリケーションBが実際にはアプリケーションAよりも数千倍高速になることが予想されます。


40

Big-Oの一般的な品種を説明するときに私がよく使用するわかりやすい英語の獣医はここにあります

すべての場合において、リストの上位にあるアルゴリズムよりも上位にあるアルゴリズムを優先してください。ただし、より複雑なクラスに移動するコストは大きく異なります。

O(1):

成長無し。問題の大きさに関係なく、同じ時間で解決できます。これは、放送範囲内にいる人の数に関係なく、一定の距離で放送するのに同じ量のエネルギーを必要とする放送にいくらか類似しています。

O(log n):

この複雑さはO(1)と同じですが、少し悪いだけです。すべての実用的な目的で、これは非常に大きな一定のスケーリングと考えることができます。1000と10億のアイテムを処理する作業の違いは、ファクター6にすぎません。

O(n):

問題を解決するためのコストは、問題のサイズに比例します。問題のサイズが2倍になると、ソリューションのコストも2倍になります。ほとんどの問題は、データエントリ、ディスク読み取り、またはネットワークトラフィックとして何らかの方法でコンピュータにスキャンする必要があるため、これは一般的に手頃なスケーリング要素です。

O(n log n):

この複雑さはO(nとよく似ています。実際には、この2つは同等です。このレベルの複雑さは、一般に依然としてスケーラブルと見なされます。仮定を微調整することにより、一部のO(n log nアルゴリズムをO(nアルゴリズムに変換できます。たとえば、キーのサイズを制限すると、ソートがO(n log nからO(n)に減少します

O(n 2):

正方形として成長します。nは正方形の1辺の長さです。これは「ネットワーク効果」と同じ成長率で、ネットワーク内の誰もがネットワーク内の他のすべての人を知っている可能性があります。成長は高価です。ほとんどのスケーラブルなソリューションでは、重要な体操を行わずにこのレベルの複雑さのアルゴリズムを使用することはできません。これは通常、他のすべての多項式の複雑さ-O(n k -にも適用されます。

O(2 n):

スケーリングしません。重要なサイズの問題を解決することはできません。何を避けるべきかを知るのに、そして専門家がO(n k)にある近似アルゴリズムを見つけるのに役立ちます。


2
O(1)の別のアナロジーを検討していただけませんか?私のエンジニアは、障害物によるRFインピーダンスについての議論を引き出したいと思っています。
johnwbyrd 2016年

36

Big Oは、アルゴリズムがその入力のサイズと比較して使用する時間/空間の量の尺度です。

アルゴリズムがO(n)の場合、時間/空間はその入力と同じ割合で増加します。

アルゴリズムがO(n 2)の場合、時間/空間は入力の2乗の割合で増加します。

等々。


2
それは宇宙のことではありません。時間を意味する複雑さについてです。
S.Lott、2009年

13
私は、それが時間または空間についてである可能性があると常に信じていました。同時に両方についてではありません。
ロッコ

9
複雑さは、間違いなくスペースに関連する可能性があります。これを見てください:en.wikipedia.org/wiki/PSPACE
Tom Crockett

4
この答えは、ここで最も「わかりやすい」答えです。以前のものは実際に読者がそれらを理解するのに十分知っていると想定していますが、作家はそれを認識していません。彼らは彼らが彼らの単純で明白であると考えます、しかしそれは絶対にそうではありません。かなりのフォーマットで多くのテキストを書き、CS以外の人々にとって難しい難しい手の込んだ例を作ることは、明白で単純ではなく、主にCSの人々であるstackoverflowersが賛成票を投じるのは魅力的です。平易な英語でCS用語を説明することは、コードと数学についてまったく何も必要としません。まだ十分ではありませんが、この回答の+1。
W.Sun 2013年

この答えは、f = O(g)がfとgが比例していることを意味すると仮定することの(一般的な)エラーを作ります。
ポールハンキン、2015

33

Big Oのわかりやすい英語の説明とは何ですか?可能な限り少ない正式な定義と単純な数学で。

Big-O表記法の必要性に関する簡単な英語の説明:

プログラムするとき、私たちは問題を解決しようとしています。私たちがコーディングしたものをアルゴリズムと呼びます。Big O表記を使用すると、アルゴリズムの悪いケースのパフォーマンスを標準化された方法で比較できます。ハードウェアの仕様は時間とともに変化し、ハードウェアの改善により、アルゴリズムの実行にかかる時間を短縮できます。ただし、ハードウェアを交換しても、アルゴリズムが変わらないため、アルゴリズムが時間の経過とともに改善または向上するわけではありません。したがって、さまざまなアルゴリズムを比較して、どちらが良いかを判断するために、Big O表記法を使用します。

Big O表記とは何かについてのわかりやすい英語の説明:

すべてのアルゴリズムが同じ時間で実行されるわけではなく、入力の項目数に基づいて変化する可能性があります。これをnと呼びます。これに基づいて、最悪のケース分析、またはnが次第に大きくなるときのランタイムの上限を検討します。Big O表記の多くはそれを参照しているため、nが何であるかを認識する必要があります。


32

ソフトウェアプログラムの速度を測定することは非常に困難であり、私たちが試した場合、答えは非常に複雑になり、例外や特別なケースでいっぱいになる可能性があります。これは大きな問題です。2つの異なるプログラムを比較して「最速」を見つけようとすると、これらすべての例外と特殊なケースが邪魔になり役に立たなくなるためです。

この役に立たない複雑さの結果として、人々は可能な限り最小かつ最も複雑でない(数学)式を使用してソフトウェアプログラムの速度を説明しようとします。これらの表現は非常に大雑把な概算です:少し運が良ければ、ソフトウェアの一部が高速か低速かの「本質」を捉えることができます。

これらは近似値であるため、表現に "O"(Big Oh)という文字を使用しています。これは、大幅に簡略化しすぎていることを読者に知らせるための規則です。(そして、表現が何らかの方法で正確であると誰もが誤って考えていないことを確認するため)。

「おお」を「ほぼ」または「おおよそ」という意味で読んだとしても、それほど間違ってはいません。(私はBig-Ohの選択がユーモアの試みであったかもしれないと思います)。

これらの "Big-Oh"式が実行しようとする唯一のことは、ソフトウェアが処理する必要のあるデータの量を増やすときにソフトウェアがどれだけ遅くなるかを説明することです。処理する必要のあるデータ量を2倍にした場合、ソフトウェアは作業を完了するのに2倍の時間を必要としますか?10倍ですか?実際には、遭遇して心配する必要があるBig-Oh式の数は非常に限られています。

いいもの:

  • O(1) 定数:入力の大きさに関係なく、プログラムの実行には同じ時間がかかります。
  • O(log n) 対数:入力のサイズが大幅に増加しても、プログラムの実行時間はゆっくりと増加します。

悪い人:

  • O(n) 線形:プログラムの実行時間は、入力のサイズに比例して増加します。
  • O(n^k) 多項式:-入力のサイズが大きくなるほど、処理時間はますます速くなります-多項式関数として。

...そして醜い:

  • O(k^n) 指数関数プログラムの実行時間は、問題のサイズが少しでも大きくなると、非常に急速に増加します。指数関数アルゴリズムを使用して小さなデータセットを処理することが現実的です。
  • O(n!) 階乗プログラムの実行時間は、非常に小さく、最も簡単なように見えるデータセット以外の何かを待つ余裕があるよりも長くなります。

4
Linearithmicという用語も聞いたことがありO(n log n)ます。
Jason Down

28

簡単な答えは次のとおりです。

ビッグOは、そのアルゴリズムで考えられる最悪の時間/空間を表します。アルゴリズムは、その制限を超えてより多くのスペース/時間を取ることはありません。Big Oは、極端な場合の時間/空間の複雑さを表します。


28

はい、2セントです。

Big-O、プログラムによって消費されるリソースの増加率、wrt problem-instance-size

リソース:合計CPU時間、最大RAM容量の可能性があります。デフォルトでは、CPU時間を指します。

問題は「合計を見つける」であるとしましょう。

int Sum(int*arr,int size){
      int sum=0;
      while(size-->0) 
         sum+=arr[size]; 

      return sum;
}

problem-instance = {5,10,15} ==> problem-instance-size = 3、iterations-in-loop = 3

problem-instance = {5,10,15,20,25} ==> problem-instance-size = 5ループ内の反復= 5

サイズ「n」の入力の場合、プログラムは配列の「n」回の反復の速度で成長しています。したがって、Big-OはO(n)として表されるNです。

問題は「組み合わせを見つける」だとしましょう。

    void Combination(int*arr,int size)
    { int outer=size,inner=size;
      while(outer -->0) {
        inner=size;
        while(inner -->0)
          cout<<arr[outer]<<"-"<<arr[inner]<<endl;
      }
    }

problem-instance = {5,10,15} ==> problem-instance-size = 3、total-iterations = 3 * 3 = 9

problem-instance = {5,10,15,20,25} ==> problem-instance-size = 5、total-iterations = 5 * 5 = 25

サイズ「n」の入力の場合、プログラムは配列の「n * n」回の反復の速度で成長しています。したがってBig-OはO(n 2)として表されるN 2です。


3
while (size-->0)これが再度質問しないことを願っいます。
mr5 2013年

26

ビッグO表記は、空間または実行時間の観点からアルゴリズムの上限を記述する方法です。nは問題の要素の数(つまり、配列のサイズ、ツリー内のノードの数など)です。nが大きくなるときの実行時間について説明します。

あるアルゴリズムがO(f(n))であると言うとき、そのアルゴリズムによる実行時間(または必要なスペース)は常にいくつかの定数時間f(n)よりも低いことを意味します。

バイナリ検索の実行時間がO(logn)であると言うことは、log(n)を乗算できる定数cが存在するということです。これは常にバイナリ検索の実行時間よりも大きくなります。この場合、常にlog(n)比較の定数要素がいくつかあります。

つまり、g(n)がアルゴリズムの実行時間である場合、g(n)<= c * f(n)の場合、g(n)<= c * f(n)のとき、g(n)= O(f(n))となります。 cとkは定数です。


BigO表記を使用して、最悪のケースと平均のケースも測定できます。en.wikipedia.org/wiki/Big_O_notation
cdiggins

25

Big Oのわかりやすい英語の説明とは何ですか?可能な限り形式的な定義を少なくし、単純な数学を使用してください。

このように美しくシンプルで短い質問は、少なくとも生徒が個別指導の際に受け取るような、同じくらい短い回答に値するようです。

Big O表記は、入力データの量のみの観点から、アルゴリズムが実行できる時間*を単純に伝えます。

(*素晴らしい、単位のない時間感覚で!)
(**これは重要なことです。なぜなら、人々は今日または明日を生きるかどうかにかかわらず、常にもっと欲しくなるからです。

さて、それがそうであるならば、Big O記法についてそれほど素晴らしいものは何ですか?

  • 実用的に言えば、Big O はアルゴリズム自体の複雑さに真っ向から焦点を当て、JavaScriptエンジン、CPUの速度、インターネット接続など、単なる比例定数であるものを完全に無視するため、Big O分析は非常に有用かつ重要です。モデルTと同じように、すぐに笑えるほど古くなったものすべて。Big Oは、現在または未来に住んでいる人々と同じくらい重要な方法でのみパフォーマンスに焦点を当てています。

  • Big O表記はまた、コンピュータープログラミング/エンジニアリングの最も重要な原則に直接スポットライトを当てています。これは、優れたプログラマー全員が考え、夢を持ち続けるための刺激となる事実です。アルゴリズム


5
数学を使わずに数学的なことを説明するように求められることは、正真正銘の博士号である私にとって常に個人的な課題です。そのようなことが実際に可能であると信じている数学者と教師。プログラマーでもある私は、数学を使わずにこの特定の質問に答えたことを誰も気にせず、完全に抵抗できない挑戦であることを願っています。
ジョセフ・マイヤーズ

22

アルゴリズムの例(Java):

// Given a list of integers L, and an integer K
public boolean simple_search(List<Integer> L, Integer K)
{
    // for each integer i in list L
    for (Integer i : L)
    {
        // if i is equal to K
        if (i == K)
        {
            return true;
        }
    }

    return false;
}

アルゴリズムの説明:

  • このアルゴリズムは、リストを項目ごとに検索し、キーを探します。

  • リスト内の各アイテムを反復処理し、それがキーである場合はTrueを返します。

  • キーが見つからずにループが終了した場合は、Falseを返します。

Big-O表記は、複雑さの上限(時間、空間など)を表します

The Big-O on Time Complexityを見つけるには:

  • 最悪の場合にかかる時間(入力サイズに関して)を計算します。

  • 最悪の場合:キーがリストに存在しません。

  • 時間(最悪の場合)= 4n + 1

  • 時間:O(4n + 1)= O(n)| Big-Oでは、定数は無視されます

  • O(n)〜線形

Best-Caseの複雑さを表すBig-Omegaもあります。

  • ベストケース:キーが最初の項目です。

  • 時間(ベストケース)= 4

  • 時間:Ω(4)= O(1)〜Instant \ Constant


2
定数4はどこから来たのですか?
ロッド14

1
..私は思う@Rodイテレータのinit、イテレータの比較、反復子は読んで、キーの比較C良いだろう
Khaled.K

18

ビッグオー

f(x)= O(g(x))は、xがa(たとえば、a = +∞)になるとき、次のような関数kがあることを意味します。

  1. f(x)= k(x)g(x)

  2. kはaの近傍に制限されます(a = +∞の場合、これは、すべてのx> Nに対して| k(x)| <MになるようなNおよびMの数があることを意味します)。

つまり、単純な英語では、f(x)= O(g(x))、x→aは、aの近傍で、fgの積に分解されることを意味します。といくつかの有界関数のます。

小さいo

ちなみに、ここでは比較のための小oの定義を示します。

f(x)= o(g(x))は、xがaになるとき、次のような関数kがあることを意味します。

  1. f(x)= k(x)g(x)

  2. xがaになると、k(x)は0になります。

  • x→0の場合、sin x = O(x)。

  • sin x = O(1)(x→+∞の場合)

  • x 2 + x = O(x)、x→0の場合、

  • x 2 + x = O(x 2)(x→+∞の場合)

  • ln(x)= o(x)= O(x)(x→+∞の場合)。

注意!等号「=」の表記は「偽の等価性」を使用します。o(g(x))= O(g(x))はtrueですが、O(g(x))= o(gはfalseです(バツ))。同様に、 "ln(x)= o(x)when x→+∞"と記述しても問題ありませんが、式 "o(x)= ln(x)"は意味がありません。

その他の例

  • O(1)= O(n)= O(n 2)(n→+∞の場合(ただし逆ではない)、等式は「偽」)、

  • O(n)+ O(n 2)= O(n 2)(n→+∞の場合)

  • O(O(n 2))= O(n 2)(n→+∞の場合)

  • O(n 2)O(n 3)= O(n 5)(n→+∞の場合)


ウィキペディアの記事は次のとおりです。https//en.wikipedia.org/wiki/Big_O_notation


3
「Big O」と「Small o」について説明せずに、それらが何であるかを説明せずに、数学的概念をたくさん紹介し、なぜ重要であるかを知らせていません。この場合、ウィキペディアへのリンクは、この種の質問にはあまりにも明白かもしれません。
Adit Saxena 2014

@AditSaxena「それらが何であるかを説明せずに」とはどういう意味ですか?私はそれらが何であるかを正確に説明しました。つまり、「big O」と「small o」はそれ自体では何もない、「f(x)= O(g(x))」のような式のみが意味を持ちます。もちろん、微積分コースから必要なものすべて)。「O(f(x))」は、「g(x)= O(f(x))」のようなすべての関数「g(x)」のクラス(実際にはセット)と見なされることがありますが、これは基本を理解するために必要ではない追加のステップ。
Alexey 2014年

まあ、わかりました、わかりやすい英語ではない単語もありますが、数学分析から必要な定義をすべて含める必要がない限り、それは避けられません。
Alexey

2
こんにちは#Alexey、受け入れられた答えを見てください:長いですが、よく構成され、適切にフォーマットされています。それは、数学的な背景が不要な単純な定義から始まります。そうする間、彼は彼がすぐに説明する3つの「技術的な」言葉を導入します(相対的、表現、複雑さ)。このフィールドを掘り下げながら、これは段階的に進みます。
Adit Saxena 2014

2
Big Oは、関数の漸近的な動作を理解するために使用されるのと同じ理由で、アルゴリズムの漸近的な動作を理解するために使用されます(漸近的な動作は無限に近い動作です)。これは、複雑な関数(アルゴリズムが取る実際の時間または空間)を単純な関数(単純なもの、通常はべき関数)と無限大またはその他のものと比較するための便利な表記法です。私はそれが何であるかを説明しただけです(定義を与えました)。大きなOで計算する方法は別の話です。興味があるので、例をいくつか追加します。
アレクセイ2014年

18

Big O表記は、任意の数の入力パラメーター(「n」と呼ぶ)が与えられた場合に、アルゴリズムがどれだけ速く実行されるかを説明する方法です。さまざまなマシンがさまざまな速度で動作するため、コンピューターサイエンスで役立ちます。4.5ギガヘルツのオクトコアプロセッサーを搭載したシステムを実行している場合でも、私は実行している可能性があるため、アルゴリズムに5秒かかると言ってもあまり意味がありません。 15年前の800 Mhzシステム。アルゴリズムに関係なく、さらに時間がかかる可能性があります。したがって、時間の観点からアルゴリズムの実行速度を指定する代わりに、入力パラメータの数、つまり "n"の観点からアルゴリズムの実行速度を指定します。このようにアルゴリズムを記述することにより、コンピュータ自体の速度を考慮する必要なく、アルゴリズムの速度を比較できます。


11

私はこの主題にさらに貢献しているのかわかりませんが、共有したいと思っていました。このブログの投稿には、Big Oに関する非常に役立つ(非常に基本的ではありますが)説明と例があります。

例を通して、これはべっ甲のようなべっ甲のような頭蓋骨を理解するのに役立ちました。ですから、正しい方向に向かわせるには、10分のかなりの読み物だと思います。


@ウィリアム...そして人々は老齢で死ぬ傾向があり、種は絶滅し、惑星は不毛に変わるなど
Priidu Neemre

11

あなたはビッグオーを知るためにあるすべてを知りたいですか?私もそうです。

したがって、ビッグOについては、1ビートだけの単語を使用します。単語ごとに1つの音。小さな言葉は速いです。あなたはこれらの言葉を知っていますし、私もそうです。1つの音の言葉を使用します。彼らは小さい。私たちが使用するすべての単語を知っていると思います!

さて、あなたと私が仕事について話しましょう。ほとんどの場合、私は仕事が好きではありません。あなたは仕事が好きですか?あなたがそうしているのかもしれませんが、私はそうしていないと確信しています。

私は仕事に行きたくない。私は仕事で時間を過ごすのが好きではありません。自分のやり方ができたら、ただ遊んで、楽しいことをしたいです。私と同じように感じますか?

時々、私は仕事に行かなければなりません。悲しいですが、本当です。だから、私が仕事をしているとき、私にはルールがあります:私はより少ない仕事をしようとします。できる限り仕事に近づかない。その後、遊びに行きます!

だからここに大きなニュースがあります:大きなOは私が仕事をしないように助けることができます!大きなOを知っていれば、もっと多くの時間をプレイできます。それが大きなOのおかげです。

今、仕事があります。私はこのリストを持っています:1、2、3、4、5、6。このリストにすべてのものを追加する必要があります。

うわー、仕事嫌いです。しかし、まあ、私はこれをしなければなりません。だからここに行きます。

1プラス2は3です。プラス3は6です...そして4は...わかりません。道に迷った。頭の中で行うのは難しい。私はこの種の仕事をあまり気にしません。

だから、仕事をしないようにしましょう。あなたと私はそれがどれほど難しいか考えてみましょう。6つの数値を追加するには、どれくらいの作業が必要ですか?

さて、見てみましょう。1と2を追加し、それを3に追加してから、4に追加する必要があります。全体で、6つの追加を数えます。これを解決するには、6つの追加を行う必要があります。

ここに大きなOがあり、この数学がどれほど難しいかを教えてくれます。

Big Oは言う:これを解決するには6つの追加を行う必要があります。1から6まで、それぞれ1つずつ追加します。6つの小さな作業...作業の各ビットは1つの追加です。

さて、今はそれらを追加する作業は行いません。しかし、私はそれがどれほど難しいかを知っています。6回の追加になります。

ああ、いや、今はもっと仕事がある。シーッシュ。誰がこの種のものを作るのですか?

今、彼らは私に1から10まで追加するように頼みます!なぜそれをするのですか?1から6を追加したくありませんでした。1から10まで追加する…ええと…それはさらに難しいでしょう!

それはどれほど難しいでしょうか?どれだけ多くの作業を行う必要がありますか?手順の増減は必要ですか?

ええと、私は10の加算を行う必要があると思います... 1から10まで、それぞれに1つずつ。十は六以上です。1から6ではなく、1から10を追加するには、もっと多くの作業が必要になります。

今は追加したくありません。それだけ追加するのがどれほど難しいか考えたいだけです。そして、できるだけ早くプレイしたいと思っています。

1から6まで追加するのは、それがいくらかの作業です。しかし、1から10を追加すると、それはより多くの作業になると思いますか?

Big Oはあなたの友人であり、私のものです。Big Oは、計画を立てるために、私たちがやらなければならない仕事の量を考えるのに役立ちます。そして、もし私たちがビッグオーの友達なら、彼は私たちがそれほど難しくない仕事を選ぶのを手伝ってくれるでしょう!

今、私たちは新しい仕事をしなければなりません。大野。私はこの仕事が全然好きではありません。

新しい作業は、1からnまでのすべてのものを追加します。

待つ!nとは何ですか?私はそれを見逃しましたか?nが何であるかを教えてくれない場合、どうすれば1からnに追加できますか?

えーと、nが何なのかわかりません。言われなかった。あなたでしたか?番号?しかたがない。だから私たちは仕事をすることができません。ふew。

しかし、今はその仕事をしませんが、nを知っていれば、それがどれほど難しいかを推測できます。n個を合計する必要がありますよね?もちろん!

ここで大きなOが登場し、彼はこの作業がどれほど難しいかを教えてくれます。彼は言う:1からNにすべてのものを1つずつ追加することはO(n)です。これらすべてを追加するには、[n回追加する必要があることはわかっています。] [1]これは大きなOです。彼はある種の仕事をするのがどれほど難しいかを教えてくれます。

私にとって、私はビッグOを大きくてゆっくりとした上司の男のように思います。彼は仕事について考えていますが、しません。彼は「その仕事は速い」と言うかもしれません。または、彼は「その仕事はとても遅くて難しいです!」と言うかもしれません。しかし、彼は仕事をしません。彼はただその仕事を見て、それからどれだけの時間がかかるかを教えてくれます。

私は大きなOをたくさん気にします。なぜですか?働きたくない!誰も仕事が好きではありません。それが、私たち全員が大きなOを愛する理由です。彼は私たちがどれだけ速く働くことができるかを教えてくれます。彼は私たちがどれほど大変な仕事をしているのかを考えるのを助けてくれます。

ああ、もっと仕事。今、仕事をしましょう。しかし、それを段階的に行う計画を立てましょう。

彼らは私たちに10枚のカードのデッキを与えた。それらはすべて混同されています:7、4、2、6 ...まったくまっすぐではありません。そして今...私たちの仕事はそれらを分類することです。

ああ。それは大変な作業のように思えます!

このデッキをどのように分類できますか?私は計画があります。

最初から最後まで、カードの各ペアを、ペアごとに、デッキを通して見ていきます。あるペアの最初のカードが大きく、そのペアの次のカードが小さい場合は、それらを交換します。そうでなければ、私は次のペアに行き、以下同様に続きます...そしてすぐに、デッキは完成しました。

デッキが完了したら、私は尋ねます:そのパスでカードを交換しましたか?もしそうなら、上からもう一度やり直さなければなりません。

いつか、いつかスワップがなくなり、私たちのデッキが完成するでしょう。大変な仕事です!

さて、それらのルールでカードを並べ替えるのにどれだけの作業が必要でしょうか?

私はカードを10枚持っています。そして、ほとんどの場合、つまり、運が悪い場合は、デッキ全体を最大10回通過しなければならず、毎回最大10枚のカードを交換する必要があります。

ビッグオー、助けて!

ビッグOが入って言った:n枚のカードのデッキの場合、この方法でソートするにはO(N二乗)時間で行われます。

なぜ彼はn二乗と言うのですか?

まあ、あなたはnの2乗がnのn倍であることを知っています。さて、私はそれを手に入れました:n枚のカードがチェックされました。これは、それぞれnステップの2つのループです。これは、実行する必要がある多くの作業の2乗です。確かにたくさんの仕事です!

大きなOがO(n二乗)の作業が必要だと言ったとき、彼は鼻の上でn二乗加算を意味するのではありません。場合によっては、少し小さいかもしれません。しかし、最悪の場合、デッキを並べ替えるのにn乗の作業が必要になります。

ここで、ビッグOが私たちの友達です。

Big Oはこれを指摘します。nが大きくなると、カードを並べ替えると、ジョブは古いものを追加するだけのジョブよりもはるかに難しくなります。どうやってこれを知るのですか?

まあ、nが実際に大きくなったとしても、nやnの2乗に何を追加してもかまいません。

大きなnの場合、nの2乗はnよりも大きくなります。

Big Oは、物事を分類することは物事を追加することよりも難しいことを教えてくれます。O(nの2乗)は、大きなnのO(n)よりも大きいです。つまり、nが実際に大きくなった場合、n個の混合されたデッキを並べ替えるには、単にn個の混合されたものを追加するよりも時間がかかる必要があります。

Big Oは私たちの仕事を解決しません。Big Oは、作業がいかに難しいかを教えてくれます。

カードの山があります。私はそれらを分類しました。あなたは助けた。ありがとう。

カードをソートするより速い方法はありますか?ビッグオーは私たちを助けることができますか?

はい、もっと速い方法があります!学ぶには少し時間がかかりますが、うまくいきます...そしてそれはかなり速く働きます。あなたもそれを試すことができますが、各ステップで時間をかけ、あなたの場所を失うことはありません。

デッキを並べ替えるこの新しい方法では、以前のようにカードのペアをチェックしません。このデッキを並べ替えるための新しいルールは次のとおりです。

1:今取り組んでいるデッキの部分で1枚のカードを選びます。必要に応じて、1つを選択できます。(これを初めて行うときは、「現在取り組んでいるデッキの一部」はもちろん、デッキ全体です。)

二:私はあなたが選んだそのカードのデッキをプレイする。このスプレイは何ですか。どうすればスプレーできますか?さて、スタートカードから順に1枚ずつ行き、スプレイカードよりも高いカードを探します。

3つ目:最後のカードから上に行き、スプレイカードよりも低いカードを探します。

これらの2枚のカードを見つけたら、それらを交換し、さらに交換するカードを探します。つまり、ステップ2に戻り、選択したカードをさらに広げます。

ある時点で、このループ(2から3へ)は終了します。この探索の両半分がスプレイカードで出会うと終了します。次に、ステップ1で選択したカードでデッキを展開しました。さて、スタート近くのすべてのカードは、スプレイカードよりも低くなっています。終わり近くのカードは、スプレイカードよりも高いです。クールなトリック!

4つ(そしてこれは面白い部分です):私は2つの小さなデッキを持っています。次に、各小さなデッキでステップ1に進みます。つまり、最初の小さなデッキのステップ1から開始し、その作業が完了すると、次の小さなデッキのステップ1から開始します。

デッキをいくつかの部分に分けて、各部分をより小さく、より小さくソートし、時にはやらなければならない仕事はもうありません。今、これはすべてのルールで遅く見えるかもしれません。しかし、私を信じてください、それはまったく遅くありません。それは物事を分類する最初の方法よりもはるかに少ない作業です!

この種の名前は何ですか?クイックソートと呼ばれています!その並べ替えはCAR Hoareと呼ばれる男によって行われ、彼はそれをQuick Sortと呼びました。現在、クイックソートは常に使用されています。

クイックソートは大きなデッキを小さなものに分割します。つまり、大きなタスクを小さなタスクに分割します。

うーん。そこにはルールがあるのではないでしょうか。大きなタスクを小さくするには、それらを分割します。

この種は非常に迅速です。どれくらい速い?Big Oは私たちに言っています:この場合、この場合、O(n log n)の作業が必要です。

それは最初の種類よりも多少速いですか?ビッグオー、助けてください!

最初のソートはO(n二乗)でした。ただし、クイックソートはO(n log n)です。n log nがnの2乗よりも小さいことを知っていますか?さて、クイックソートが高速であることは、そのためです。

デッキを並べ替える必要がある場合、最良の方法は何ですか?まあ、あなたはあなたがやりたいことをすることができますが、私はクイックソートを選びます。

なぜクイックソートを選択するのですか?もちろん仕事は嫌いです!できる限り早く仕事を終わらせたい。

クイックソートの作業が少ないことをどのように確認できますか?O(n log n)がO(nの2乗)よりも小さいことを知っています。Oの方が小さいので、クイックソートの作業は少なくなります。

さて、あなたは私の友人、ビッグオーを知っています。彼は私たちがより少ない仕事をするのを助けます。ビッグOを知っていれば、仕事も減ります!

あなたは私と一緒にすべてを学びました!あなたはとても賢いです!どうもありがとうございます!

これで作業は完了です。遊びに行きましょう!


[1]:1からnまでのすべてのものを一度にすべてカンニングして追加する方法があります。ガウスという名前の子供は、8歳のときにこれを見つけました。私はそれほど賢くないので、彼がどうやってそれをしたのか私に尋ねないでください


9

時間の複雑さを理解するためのより簡単な方法があります。時間の複雑さを計算するための最も一般的なメトリックはBig O表記です。これにより、すべての定数係数が削除されるため、Nが無限に近づくときに、Nに関連して実行時間を推定できます。一般的には、次のように考えることができます。

statement;

一定です。ステートメントの実行時間はNに関連して変化しません

for ( i = 0; i < N; i++ )
  statement;

線形です。ループの実行時間はNに正比例します。Nが2倍になると、実行時間も2倍になります。

for ( i = 0; i < N; i++ ) 
{
for ( j = 0; j < N; j++ )
  statement;
}

二次式です。2つのループの実行時間はNの2乗に比例します。Nが2倍になると、実行時間はN * N増加します。

while ( low <= high ) 
{
 mid = ( low + high ) / 2;
 if ( target < list[mid] )
 high = mid - 1;
 else if ( target > list[mid] )
  low = mid + 1;
else break;
}

対数です。アルゴリズムの実行時間は、Nを2で除算できる回数に比例します。これは、アルゴリズムが各反復で作業領域を半分に分割するためです。

void quicksort ( int list[], int left, int right )
{
  int pivot = partition ( list, left, right );
  quicksort ( list, left, pivot - 1 );
  quicksort ( list, pivot + 1, right );
}

N *ログ(N)です。実行時間は対数であるNループ(反復または再帰)で構成されているため、アルゴリズムは線形と対数の組み合わせです。

一般に、1次元のすべてのアイテムで何かを行うことは線形であり、2次元のすべてのアイテムで何かを行うことは2次であり、作業領域を半分に分割することは対数です。立方、指数、平方根などの他のBig O測度もありますが、それほど一般的ではありません。ビッグO表記はO()として記述されます。ここで、はメジャーです。クイックソートアルゴリズムはO(N * log(N))として記述されます。

注:これは、最良、平均、および最悪のケースの測定値を考慮していません。それぞれに独自のBig O表記があります。また、これは非常に単純化した説明です。Big Oが最も一般的ですが、これまでに示したよりも複雑です。ビッグオメガ、リトルオー、ビッグシータなどの他の表記法もあります。おそらく、アルゴリズム分析コース以外ではこれらに遭遇しないでしょう。

  • もっとで参照してください。ここで

9

あなたがハリー・ポッター:アマゾンから完全な8フィルムコレクション[ブルーレイ]を注文し、同時に同じフィルムコレクションをオンラインでダウンロードするとします。あなたはどちらの方法がより速いかをテストしたいです。配信には約1日かかり、ダウンロードは約30分早く完了しました。すごい!ですからタイトなレースです。

ロードオブザリング、トワイライト、ダークナイトトリロジーなどのブルーレイ映画を注文して、すべての映画を同時にオンラインでダウンロードするとどうなりますか?今回は、配信が完了するまでに1日かかりますが、オンラインダウンロードが完了するまでに3日かかります。オンラインショッピングの場合、購入数(投入数)は配達時間に影響しません。出力は一定です。これをO(1)と呼びます。

オンラインダウンロードの場合、ダウンロード時間は映画のファイルサイズ(入力)に正比例します。これをO(n)と呼びます。

実験から、オンラインショッピングはオンラインダウンロードよりも優れていることがわかります。ビッグO表記は、アルゴリズムのスケーラビリティ効率を分析するのに役立つため、理解することは非常に重要です。

注: Big O表記は、アルゴリズムの最悪のシナリオを表しています。O(1)O(n)が上記の例の最悪のシナリオであると仮定しましょう。

リファレンスhttp : //carlcheo.com/compsci


9

サイズnのデータセットで何かを行うアルゴリズムAについて話していると仮定します。

次にO( <some expression X involving n> )、簡単な英語で:

Aの実行時に運が悪ければ、完了するまでにX(n)回の演算が必要になる可能性があります。

偶然にも、特定の機能(と考えるがあるの実装X(n)はかなり頻繁に発生する傾向があります)。これらは周知であり、容易に比較される(例:1Log NNN^2N!、など。)

話をするとき、これらを比較することによってAと他のアルゴリズム、それは操作の回数に応じてアルゴリズムをランク付けすることが容易であることができる(最悪の場合)を完了する必要があります。

一般的に、私たちの目標は、アルゴリズムAX(n)をできるだけ少ない数で返す関数を持つような方法で、アルゴリズムAを見つけるか、構造化することです。


8

あなたの頭に無限の適切な概念がある場合、非常に簡単な説明があります:

Big O表記は、無限に大きな問題を解決するためのコストを示します。

そしてさらに

一定の要因は無視できる

アルゴリズムを2倍の速さで実行できるコンピューターにアップグレードした場合、大きなO表記はそれに気付きません。定数係数の改善は小さすぎて、ビッグO表記が機能するスケールでは気付かれないほどです。これは、ビッグO表記の設計の意図的な部分であることに注意してください。

ただし、一定の要因よりも「大きい」ものはすべて検出できます。

サイズが「無限大」であり、ほぼ無限大と見なされる計算を行うことに関心がある場合、大きなO表記法はおおよそ問題を解決するためのコストです。


上記が意味をなさない場合、頭に無限の互換性のある直感的な概念がないため、おそらく上記のすべてを無視する必要があります。これらのアイデアを厳密にするため、またはまだ直感的に役に立たない場合に説明するために私が知っている唯一の方法は、最初に大きなO表記または類似のものを教えることです。(ただし、将来的に大きなO表記法をよく理解したら、これらのアイデアを再検討する価値があるかもしれません)


7

「Big O」表記のわかりやすい英語の説明とは何ですか?

非常に簡単なメモ:

「ビッグO」のOは「順序」(または正確には「順序」)と
呼ばれるため、比較するために何かを順序付けるために使用されるという文字通りの考えを得ることができます。

  • 「Big O」は2つのことを行います。

    1. コンピューターがタスクを実行するために適用するメソッドのステップ数を見積もります。
    2. それが良いかどうかを判断するために他の人と比較するプロセスを促進しますか?
    3. 「Big O 'は、上記の2つを標準化されたで実現しますNotations
  • 最もよく使用される表記は7つあります

    1. O(1)は、コンピューターが1ステップでタスクを実行することを意味します。優れています。注文番号1です。
    2. O(logN)は、コンピューターがlogNステップでタスクを完了することを意味します。
    3. O(N)、Nステップ、そのフェア、注文番号3でタスクを完了
    4. O(NlogN)、O(NlogN)ステップでタスクを終了します、それは良くありません、注文番号4
    5. O(N ^ 2)、N^2ステップでタスクを実行する、それは悪い、注文番号5
    6. O(2 ^ N)、2^Nステップでタスクを実行する、それは恐ろしい、注文番号6
    7. O(N!)、N!ステップでタスクを完了する、ひどい、注文番号7

ここに画像の説明を入力してください

表記法を使用するとします。O(N^2)メソッドがタスクを実行するためにN * Nステップを実行することが明確であるだけでなくO(NlogN)、ランク付けからも良くないことがわかります。

理解を深めるために、行末の順序に注意してください。すべての可能性を考慮すると、7つを超える表記があります。

CSでは、タスクを実行する一連のステップはアルゴリズムと呼ばれます。
用語では、Big O表記は、アルゴリズムのパフォーマンスまたは複雑さを表すために使用されます。

さらに、Big Oは最悪のケースを確立するか、上限ステップを測定します。
最良の場合については、Big-Ω(Big-Omega)を参照してください。

Big-Ω(Big-Omega)表記(記事)| カーンアカデミー

  • まとめ
    「Big O」は、アルゴリズムのパフォーマンスを説明し、評価します。

    またはそれを正式に扱う場合、「Big O」はアルゴリズムを分類し、比較プロセスを標準化します。


6

それを見る最も簡単な方法(平易な英語)

入力パラメーターの数がアルゴリズムの実行時間にどのように影響するかを確認しようとしています。アプリケーションの実行時間が入力パラメーターの数に比例する場合、それはBig O of nであると言われます。

上記のステートメントは良いスタートですが、完全に真実ではありません。

より正確な説明(数学)

と思います

n =入力パラメーターの数

T(n)=アルゴリズムの実行時間をnの関数として表す実際の関数

c =定数

f(n)=アルゴリズムの実行時間をnの関数として表す近似関数

次に、Big Oに関する限り、次の条件が満たされる限り、近似f(n)は十分に良いと見なされます。

lim     T(n) ≤ c×f(n)
n→∞

方程式は、nが無限大に近づくときに読み取られます。nのTは、nのfのc倍以下です。

大きなO表記では、これは

T(n)∈O(n)

これは、n of Tがn of big Oにあるため読み取られます。

英語に戻る

上記の数学的な定義に基づいて、アルゴリズムがnのBig Oであると言う場合、それはn(入力パラメーターの数)以上の関数であることを意味します。アルゴリズムがnのビッグOの場合、それは自動的にnのビッグOの正方形になります。

nの大きなOは、私のアルゴリズムが少なくともこれと同じ速度で実行されることを意味します。アルゴリズムのBig O表記を見て、遅いとは言えません。あなたはその速く言うことができます。

チェックこれを UCバークレーからビッグOのビデオチュートリアルのために。それは実際には単純な概念です。Shewchuck教授(別名神レベルの教師)が説明しているのを聞くと、「ああ、それだけです!」と言うでしょう。


5

特に数学にあまり詳しくない人のために、大きなO表記について本当に素晴らしい説明を見つけました。

https://rob-bell.net/2009/06/a-beginners-guide-to-big-o-notation/

ビッグO表記は、コンピューターサイエンスでアルゴリズムのパフォーマンスや複雑さを表すために使用されます。Big Oは最悪のシナリオを具体的に説明し、アルゴリズムによって必要な実行時間または使用されるスペース(メモリやディスクなど)を説明するために使用できます。

プログラミングパールやその他のコンピュータサイエンスの本を読んでいて、数学の基礎がない人は、O(N log N)やその他の奇妙な構文に言及している章に達したときに壁にぶつかるでしょう。うまくいけば、この記事がBig Oと対数の基本を理解するのに役立つことを願っています。

プログラマーとして最初に、そして数学者として2番目(多分3番目または4番目)に、私はBig Oを完全に理解する最良の方法は、コードでいくつかの例を作成することであると考えました。したがって、以下は、可能な場合の説明と例とともに、いくつかの一般的な成長の順序です。

O(1)

O(1)は、入力データセットのサイズに関係なく、常に同じ時間(またはスペース)で実行されるアルゴリズムを記述します。

bool IsFirstElementNull(IList<string> elements) {
    return elements[0] == null;
}

オン)

O(N)は、パフォーマンスが線形に、入力データセットのサイズに正比例して成長するアルゴリズムを表します。以下の例は、Big Oが最悪の場合のパフォーマンスシナリオをどのように優先するかも示しています。forループの反復中に一致する文字列が見つかると、関数は早く戻りますが、Big O表記では、アルゴリズムが最大反復回数を実行する上限が常に想定されます。

bool ContainsValue(IList<string> elements, string value) {
    foreach (var element in elements)
    {
        if (element == value) return true;
    }

    return false;
} 

O(N 2

O(N 2)は、パフォーマンスが入力データセットのサイズの2乗に正比例するアルゴリズムを表します。これは、データセットのネストされた反復を含むアルゴリズムで一般的です。より深くネストされた反復はO(N 3)、O(N 4)などになります。

bool ContainsDuplicates(IList<string> elements) {
    for (var outer = 0; outer < elements.Count; outer++)
    {
        for (var inner = 0; inner < elements.Count; inner++)
        {
            // Don't compare with self
            if (outer == inner) continue;

            if (elements[outer] == elements[inner]) return true;
        }
    }

    return false;
}

O(2 N

O(2 N)は、入力データセットへの各追加で成長が倍になるアルゴリズムを示します。O(2 N)関数の成長曲線は指数関数的です-非常に浅いところから始まり、その後気象的に上昇します。O(2 N)関数の例は、フィボナッチ数列の再帰的な計算です。

int Fibonacci(int number) {
    if (number <= 1) return number;

    return Fibonacci(number - 2) + Fibonacci(number - 1);
}

対数

対数の説明は少し難しいので、一般的な例を使用します。

バイナリ検索は、ソートされたデータセットを検索するために使用される手法です。これは、データセットの中央の要素、基本的には中央値を選択することで機能し、それをターゲット値と比較します。値が一致する場合、成功を返します。ターゲット値がプローブ要素の値よりも高い場合は、データセットの上半分を取得し、それに対して同じ操作を実行します。同様に、ターゲット値がプローブ要素の値よりも低い場合は、下半分に対して操作を実行します。値が見つかるまで、またはデータセットを分割できなくなるまで、反復ごとにデータセットを半分にします。

このタイプのアルゴリズムは、O(log N)として記述されます。バイナリサーチの例で説明されているデータセットの反復的な半減は、最初にピークに達し、データセットのサイズが増加するにつれてゆっくりと平らになる成長曲線を生成します。 100アイテムを含む場合は2秒かかり、1000アイテムを含むデータセットは3秒かかります。入力データセットのサイズを2倍にしても、アルゴリズムの1回の反復後にデータセットが半分になり、したがって、入力データセットのサイズの半分と同等になるため、その成長にはほとんど影響しません。これにより、大規模なデータセットを処理するときに、バイナリ検索などのアルゴリズムが非常に効率的になります。


4

これは非常に単純化した説明ですが、最も重要な詳細について説明したいと思います。

問題を処理するアルゴリズムがいくつかの「要因」に依存しているとしましょう。たとえば、NとXにしましょう。

NとXに応じて、アルゴリズムにはいくつかの演算が必要になります3(N^2) + log(X)。たとえば、WORSTの場合は演算です。

Big-Oは定数係数(別名3)をあまり気にしないので、アルゴリズムのBig-OはO(N^2 + log(X))です。これは基本的に「最悪の場合にアルゴリズムが必要とする演算量をこれでスケーリングする」と解釈されます。


4

序文

アルゴリズム:問題を解決するための手順/式


アルゴリズムをどのように分析し、アルゴリズムを相互に比較することができますか?

例:あなたと友人は、0からNまでの数を合計する関数を作成するよう求められます。あなたはf(x)を思い付き、あなたの友人はg(x)を思い付きます。両方の関数の結果は同じですが、アルゴリズムが異なります。アルゴリズムの効率を客観的に比較するために、Big-O表記法を使用しています。

ビッグO記法:説明ランタイムは、任意の大き得る入力として入力に対して大きくなりますどのように迅速に。

3つの重要なポイント:

  1. 比較育つどのように迅速に実行 しないで 正確な実行時間を比較する(ハードウェアに依存します)
  2. 実行時間のみが入力(n)に関連して増加します
  3. nが任意に大きくなる(無限大だと思います)AKA大きくなるnと、用語上の焦点は、それは、最速成長する漸近解析

スペースの複雑さ:時間の複雑さの他に、スペースの複雑さ(アルゴリズムが使用するメモリ/スペースの量)も考慮します。操作時間をチェックする代わりに、メモリ割り当てのサイズをチェックします。

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