Big n(n ^ 2 + n)/ 2成長率のアルゴリズムに関する質問


16

この質問をしているのは、大きなO表記に関する1つの側面について混乱しているためです。

Frank Carrano 著の「Data Structures and Abstractions with Java」という本を使用しています。「アルゴリズムの効率」に関する章では、次のアルゴリズムを示しています。

int sum = 0, i = 1, j = 1
for (i = 1 to n) {
    for (j = 1 to i)
        sum = sum + 1
}

彼は最初、このアルゴリズムを(n 2  + n) / 2の成長率を持つと説明しています。どちらを見るかは直感的に思えます。

ただし、nが大きい場合、(n 2  + n) / 2n 2のように振る舞うと述べられています。同じ段落では、彼は述べて(N 2  + N) / 2はまた、多くのと同じように動作し、N 2 / 2。彼はこれを使用して、上記のアルゴリズムをO(n 2として分類します。

私はそれを取得します(N 2  + N) / 2が に似てN 2 / 2パーセント賢明なので、nは少し違いになります。私が得られないのは、nが大きいときに(n 2  + n) / 2n 2が似ている理由です。

たとえば、n = 1,000,000の場合:

(n^2 + n) / 2 =  500000500000 (5.000005e+11)
(n^2) / 2     =  500000000000 (5e+11)
(n^2)         = 1000000000000 (1e+12)

最後の1つはまったく似ていません。実際、明らかに、真ん中の2倍です。それで、フランク・カラーノはどうやってそれらが似ていると言えるのでしょうか?また、アルゴリズムはどのようにO(n 2として分類されますか。その内側のループを見ると、n 2 + n / 2だったと言えます。


興味のある方は、私は、実行ツリー図をチェックして、ネストされた3つのループのための答え与えていたネストされたループに関連したAパズル
Grijesh Chauhan



1
基本的には、n成長するにつれて、関数 'n ^ 2`と関数の両方が同様に動作し、成長率が一定の差になるという考えです。複雑な式がある場合、より速く成長する関数が優先されます。
AK_

1
@MichaelT:これはその質問の複製だとは思わない。他の質問は単に数を数えるだけの問題だからだ。これは、より低い項(具体的には、定数乗数と低次の多項式)が無視される理由に関する、より微妙な質問です。ここの質問者は、他の質問で提起された問題をすでに理解しているようであり、その質問に十分な答えはこの質問には答えません。
-sdenham

回答:


38

アルゴリズムのBig-Oの複雑さを計算するとき、示されているのは、アルゴリズムを実行する要素の数が増加した場合に実行時間の増加に最も大きく寄与する要因です。

アルゴリズムが複雑で(n^2 + n)/2要素数が2倍の場合、定数2は実行時間の増加に影響せず、この用語nは実行時間の2倍を引き起こし、この用語は実行をn^24倍増加させます時間。
このn^2用語の寄与が最も大きいため、Big-Oの複雑度はO(n^2)です。


2
私はそれが好きです、それは少し明確になっています。
アンドリューS

7
これは非常に手の波状です。真または偽である可能性があります。少しの計算ができる場合は、以下の回答のいずれかを参照してください。
usr

2
この推論はあまりにも曖昧O(n * log n) = O(n)です。それは、それが真実ではないことを結論付けることができることを意味するでしょう。
cfh

それは最も正確な答えでも意味的に正しいものでもないかもしれませんが、ここで重要なのは、私が中心点を理解し始めたことであり、それが著者の目的だと思います。詳細はしばしば中核となる原則から逸れることがあるため、意図的に曖昧です。木のために木を見ることは重要です。
アンドリューS

バートは本当に要因ではなく用語について話していました。それを理解して、それを結論付けることはできませんO(n * log n) = O(n)。これは、定義の背後にある理論的根拠の良い説明を与えると思います。
マークフォスキー

10

定義は

f(n) = O(g(n))

いくつかの定数C> 0が存在し、すべてのnが何らかのn_0より大きい場合、

|f(n)| <= C * |g(n)|

これは明らかに、f(n)= n ^ 2およびg(n)= 1/2 n ^ 2に当てはまります。ここで、定数Cは2でなければなりません。f(n)= n ^に当てはまることも簡単にわかります2およびg(n)= 1/2(n ^ 2 + n)。


4
「ある一定のCが存在する場合> 0このような全てのn forr、こと」は「いくつかの定数Cが終了した場合、N_0例えば、その全てのn> N_0は、」
Taemyr

@Taemyr:関数gがゼロでない限り、定数Cを常に増やして、有限の最初のn_0値に対してステートメントを真にすることができるので、それは実際には必要ありません。
cfh

いいえ、関数を見ている限り、有限数の潜在的なn_0値はありません。
Taemyr

@Taemyr:n_0は有限数です。C = max {f(i)/ g(i):i = 1、...、n_0}を選択すると、簡単に確認できるように、ステートメントは常に最初のn_0値を保持します。
cfh

CSでは、nは通常入力サイズであり、したがって控えめであるため、これはそれほど重要ではありません。この場合、n_0 = 1が機能するようにCを選択できます。ただし、正式な定義は、あるしきい値よりも大きいnであるため、定義を適用する際の多くの細かい作業が削除されます。
Taemyr

6

複雑さについて話すときは、要素の数に基づいた時間係数の変化(n)にのみ関心があります。

そのため、(2ここのような)定数要素を削除できます。

これはあなたに残しますO(n^2 + n)

さて、合理的な大規模のnために、製品は、すなわちn * n、ちょうどよりも大幅に大きくなりますnます。これは、その部分もスキップすることが許可されている理由ですO(n^2)

確かに、小さな数字には大きな違いがありますが、これはあなたnが大きくなればなるほどわずかになります。


差が限界になるためには、nはどれくらい大きくなければなりませんか?また、なぜ/ 2が削除され、その存在は値を​​半分にしますか?
アンドリューS

6
@AndrewS Big O Notationは成長について語るからです。2で除算することは、最終的に成長率が変わらないため、ベンチマークとタイムスタンプのコンテキストの外では無関係です。ただし、最大のコンポーネントはそうであるため、これで十分です。
ニール

2
@ニール、とても素晴らしい。本がそのようになることを願っています。時々、著者は、単なる人間は機能的な知識を持たず、したがって重要なポイントを明確にしないことを忘れていることをあまりにも多く知っていると思いますが、代わりにそれを何らかの数学的な記述に埋めるか、または暗示されると信じて一緒に省略します。
アンドリューS

この答えを何度も表明できたらと思います!@ニール、あなたはビッグオー本を書くべきです。
テルソサウルス

3

「(n²+ n)/ 2は、nが大きい場合にn²のように動作する」ということではなく、nが増加するにつれて(n²+ n)/ 2 n²のように成長することです。です。

たとえば、nが1,000から1,000,000に増加すると

(n² + n) / 2  increases from  500500 to  500000500000
(n²) / 2      increases from  500000 to  500000000000
(n²)          increases from 1000000 to 1000000000000

同様に、nが1,000,000から1,000,000,000に増加すると

(n² + n) / 2  increases from  500000500000 to  500000000500000000
(n²) / 2      increases from  500000000000 to  500000000000000000
(n²)          increases from 1000000000000 to 1000000000000000000

それらは同様に成長します。これがBig O Notationの目的です。

Wolfram Alpha(n²+ n)/ 2とn²/ 2プロットすると、それらは非常に似ているため、n = 100で区別するのは困難です。Wolfram Alpha3つすべてプロットすると、2の定数係数で区切られた2本の線が表示されます。


これは良いことです、それは私にとって非常に明確になります。返信いただきありがとうございます。
アンドリューS

2

あなたは大きなOを解決する必要があるように見えます表記をもう少し解決。この表記法の便利さは、等号を使用しているため非常に誤解を招きますが、ここでは関数の等号を示すために使用していません。

ご存じのように、この表記は関数の漸近的比較を表し、f = O(g)と記述すると、nが無限大になるにつれて、f(n)g(n)と同じくらい速く成長することを意味します。これを翻訳する簡単な方法は、関数f / gが有界であると言うことです。しかし、もちろん、gが0 である場所に注意する必要があり、ほぼどこでも読むことができるより堅牢な定義になります。

この表記法は、計算に非常に便利であることがわかりました-これが広く普及している理由です-しかし、ここで見られる等号は関数の等価性を示していないため、注意して扱う必要があります。これは、2 = 5 mod 32 = 5を意味するわけではなく、代数に熱心であれば、実際には大きなO表記が何かを法とする等式として理解できると言っているようなものです。

さて、あなたの特定の質問に戻るために、いくつかの数値を計算してそれらを比較することはまったく役に立たない:100万という大きな値であっても、漸近的な振る舞いは考慮しない。関数f(n)= n(n-1)/ 2g(n)=n²の比率をプロットするとより便利ですが、この特別なケースでは、f(n)/ g(n)がすぐにわかります。n> 0の場合、f = O(g)を意味する1/2より小さい

表記法の理解を深めるために、

  • 似たようなものに基づいた曖昧な印象ではなく、きれいな定義で作業します-あなたが経験したように、そのような曖昧な印象はうまく機能しません。

  • 例を使って詳細に作業してください。1週間以内に5つの例で解決できれば、自信を高めるのに十分です。これは間違いなく価値のある努力です。


代数サイドノート場合Aは、すべての関数の代数あるΝ→Ν及びC有界関数の部分代数関数が与えられると、Fに属する関数の組O(F)があるC用の-submodule A大きい上、および計算ルールO表記は、これらのサブモジュールでAがどのように動作するかを示しています。したがって、私たちが見る平等はACサブモジュールの平等であり、これは単なる別の種類のモジュラスです。


1
このウィキペディアの記事は、最初の小額の記事を追いかけるのは困難です。熟練した数学者によって熟練した数学者向けに書かれたものであり、百科事典の記事に期待するような入門テキストではありません。あなたの洞察力に感謝します。
アンドリューS

ウィキペディアのテキストのレベルを過大評価しています!:)それは確かによく書かれていません。Graham、Knuth、Patashnikは、CSの学生向けの素敵な本「Concrete Mathematics」を執筆しました。また、「コンピュータプログラミングの芸術」または50年代に書かれた数論の本(Hardy&Wright、Rose)を試してみることができます。通常、彼らは高校生レベルを対象としています。完全な本を読む必要はありません。1つを選んだ場合、漸近に関する部分だけを読んでください。しかし、理解する必要がある量を決定する必要がある前に。:)
マイケルルバルビエグリューネヴァルド

1

大きなO表記の意味を誤解していると思います。

O(N ^ 2)が表示される場合、基本的には、問題が10倍になった場合、それを解決する時間は10 ^ 2 = 100倍になります。

式で1000と10000をパンチしましょう:1000:(1000 ^ 2 + 1000)/ 2 = 500500 10000:(10000 ^ 2 + 10000)/ 2 = 50005000

50005000/500500 = 99,91

したがって、Nは10倍大きくなりましたが、ソリューションは100倍大きくなりました。したがって、動作します:O(N ^ 2)


1

nが1,000,000そのとき

(n^2 + n) / 2  =  500000500000  (5.00001E+11)
(n^2) / 2      =  500000000000  (5E+11)
(n^2)          = 1000000000000  (1E+12)

1000000000000.00何?

複雑さは実際のコスト(時間の複雑さまたはスペースの複雑さについて話しているかどうかに応じて秒またはバイト)を予測する方法を提供しますが、数秒または他の特定の単位を提供しません。

それは私たちにある程度の割合を与えます。

アルゴリズムがn²回何かしなければならない場合、cの値に対してn²×cが必要になります。これは、各反復にかかる時間です。

アルゴリズムがn²÷2の処理を行わなければならない場合、各反復の2倍の長さのcの値に対してn²×cが必要になります。

いずれにしても、かかる時間は依然としてn²に比例します。

現在、これらの一定の要因は、単に無視できるものではありません。確かに、O(n²)複雑度のアルゴリズムがO(n)複雑度のアルゴリズムよりも優れている場合があります。少数のアイテムに取り組んでいる場合、一定の要因の影響が大きく、他の懸念を圧倒する可能性があるためです。 。(実際、O(n!)でさえ、nの値が十分に低い場合はO(1)と同じです)。

しかし、それらは複雑さが私たちに語るものではありません。

実際には、アルゴリズムのパフォーマンスを改善する方法はいくつかあります。

  1. 各反復の効率を改善します。O(n²)はn²×c秒で実行されますが、cは小さくなります。
  2. 表示されるケースの数を減らします。O(n²)はn²×c秒で実行されますが、nは小さくなります。
  3. アルゴリズムを同じ結果で複雑さの低いアルゴリズムに置き換えます。たとえば、何かO(n²)を何かO(n log n)に置き換えて、n²×c₀秒から(n log n)×c₁秒に変更できる場合。

または、別の方法で見ると、f(n)×c数秒かかります。特定ののリターンを減らすc、減らす、nまたは減らすことでパフォーマンスを向上させることができfますn

最初の方法は、ループ内でいくつかのマイクロオプトを実行するか、より優れたハードウェアを使用して実行できます。常に改善されます。

2番目の方法は、おそらくすべてを検査する前にアルゴリズムから抜け出すことができるケースを特定するか、重要ではないデータをフィルターで除外することで可能です。これを行うコストがゲインを上回る場合は改善されませんが、一般に、特に大きなnの場合、最初のケースよりも大きな改善になります。

3つ目は、まったく異なるアルゴリズムを使用して行うことができます。典型的な例は、バブルソートをクイックソートに置き換えることです。要素の数が少ないと、事態が悪化する可能性があります(c₁がcifより大きい場合)が、特にnが非常に大きい場合、通常は最大のゲインが得られます。

実際の使用では、複雑さの尺度により、nまたはcの削減がどのように役立つかという問題を無視するため、アルゴリズム間の違いについて正確に推論することができます。 f()


「nの値が十分に低い場合、O(n!)はO(1)と同じです」は間違っています。「n十分に低く保たれていれば、Big-Oは問題にならない」と説明するためのより良い方法が必要です。
ベンフォークト

@BenVoigt最初に読んだときと同じ修辞的な影響を与えるものに出会ったことはありません。元々は私のものではありません。私はEric Lippertからそれを盗みました。もちろん、それは「πの小さな値と3の大きな値に対して3は等しい」などのジョークを参照していますが、これはまだ古いものです。
ジョンハンナ

0

定数因子

大きなO表記のポイントは、O(function(n))が常にC * function(n)より大きくなるように、任意の大きな定数係数を選択できることです。アルゴリズムAがアルゴリズムBよりも10億倍遅い場合、nがarbitrarily意的に大きくなってもその差が大きくならない限り、アルゴリズムAは同じO複雑度を持ちます。

概念を説明するために1000000の定数ファクターを想定してみましょう-それは必要なものより百万倍大きいですが、それはそれらが無関係であると考えられる点を示しています。

(n ^ 2 + n)/ 2 "内部に収まる" O(n ^ 2)は、nがどれだけ大きくても、(n ^ 2 + n)/ 2 <1000000 * n ^ 2であるためです。

(n ^ 2 + n)/ 2は、一部の値(n ^ 2 + n)/ 2> 1000000 * nであるため、より小さいセット、たとえばO(n)に「適合しません」。

定数係数は任意に大きくすることができます-実行時間がn年のアルゴリズムは、実行時間がn * log(n)マイクロ秒のアルゴリズムよりも「優れた」O(n)複雑度を持ちます。


0

Big-Oは、アルゴリズムの「複雑さ」に関するものです。あなたは2つのアルゴリズムを持って、そして1がかかる場合はn^2*k実行するために秒を、他方がかかるn^2*j実行するために秒を、あなたは1つが優れているかについて議論することができ、あなたが影響を与えるためにしようとするいくつかの興味深いの最適化を行うことができるかもしれませんkj、しかし、両方のこれらのアルゴリズムはn*m、実行にかかるアルゴリズムに比べて非常に遅いです。定数kやをどれだけ小さくしてもかまいませんがj、入力が十分に大きいn*m場合は、アルゴリズムが常に勝ちます。m大きいは、非常に大きくます。

したがって、最初の2つのアルゴリズムO(n^2)を呼び出し、2番目のアルゴリズムを呼び出しますO(n)。世界をアルゴリズムのクラスにうまく分割します。これがbig-Oのすべてです。車を車、トラック、バスなどに分割するようなものです。車にはさまざまなバリエーションがあり、プリウスがシボレーボルトよりも優れているかどうかを議論するために一日中過ごすことができますが、 12人を1人にまとめる必要がありますが、これはかなり無意味な議論です。:)

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