O(1 / n)アルゴリズムはありますか?


335

O(1 / n)アルゴリズムはありますか?

または、O(1)よりも小さいものは何ですか?


ほとんどの質問は、「時間の複雑さがO(1 / n)のアルゴリズムはありますか?」これが事実であると仮定しましょうか?Big-O(およびBig-Thetaなど)は、アルゴリズムではなく関数を表します。(私は関数とアルゴリズムの間に同等性がないことを知っています。)
jyoungdev

4
これは、コンピュータサイエンスで一般に理解されている「O(X)アルゴリズム」の定義です。時間の複雑度がO(X)であるアルゴリズムです(式Xの場合)。
David Z

2
バッファツリーを使用したI / O効率の高い優先度キューアルゴリズムの場合、このような制限があると聞いています。バッファツリーでは、各操作にO(1 / B)I / Oが必要です。ここで、Bはブロックサイズです。また、n個の操作の合計I / O はO(n / B.log(base M / B)(n / B))です。ここで、ログの部分はバッファーツリーの高さです。
CODError

O(1 / n)エラー確率のアルゴリズムはたくさんあります。たとえば、O(n log n)バケットを持つブルームフィルター。
Thomas Ahle、

ニワトリを追加して卵を早く産むことはできません。
Wyck、

回答:


310

この質問は、見かけほど馬鹿ではありません。少なくとも理論的には、Big O表記の数学的定義をとると、O(1 / n)などは完全に賢明です。

これで、簡単にgx)を1 / xに置き換えることができます。上記の定義が一部のfにも当てはまることは明らかです。

漸近的な実行時の増加を推定する目的では、これは実行可能性が低くなります。意味のあるアルゴリズムは、入力が増加するにつれて速くなりません。もちろん、これを実現する任意のアルゴリズムを構築できます。たとえば、次のようなものです。

def get_faster(list):
    how_long = (1 / len(list)) * 100000
    sleep(how_long)

明らかに、この関数は、入力サイズが大きくなるにつれて、ハードウェアによって強制される少なくとも数回の制限(数値の精度、sleep待機できる最小時間、引数の処理時間など)までに費やす時間が短くなります。この制限は、定数の下限なので、実際には上記の関数にはまだランタイムO(1)があります。

しかし、そこにある入力のサイズが大きくランタイムは(少なくとも部分的に)減少させることができ、実際、現実世界のアルゴリズムに。ただし、これらのアルゴリズムはO(1)以下では実行時の動作を示さないことに注意してください。それでも、彼らは興味深いです。たとえば、Horspoolによる非常に単純なテキスト検索アルゴリズムを見てみましょう。ここで、予想される実行時間は、検索パターンの長さが増加するにつれて減少します(ただし、干し草の山の長さが増加すると、実行時間が再び増加します)。


22
「ハードウェアによる強制」は、チューリングマシンにも適用されます。O(1 / n)の場合、アルゴリズムが操作を実行することを想定していない入力サイズが常に存在します。したがって、O(1 / n)時間の複雑さを実現することは実際には不可能だと思います。
Roland Ewald、

28
Mehrdad、あなたは理解していません。O表記は、n->∞としての制限(技術的にはlim sup)に関するものです。アルゴリズム/プログラムの実行時間は、一部のマシンのステップ数であり、したがって離散的です。アルゴリズムが取ることができる時間(「1ステップ」)にはゼロ以外の下限があります。ある有限のNまで、プログラムはnとともに減少するいくつかのステップをとること可能ですが、アルゴリズムがO(1 / n)、または実際にo(1)になる唯一の方法は、すべてに十分に時間がかかる場合です大きなn-不可能です。
ShreevatsaR

28
O(1 / n)関数が(数学的な意味で)存在することに異論はありません。明らかにそうです。しかし、計算は本質的に離散的です。フォンノイマンアーキテクチャまたは純粋に抽象的なチューリングマシンでのプログラムの実行時間など、下限のあるものはO(1 / n)にはできません。同様に、O(1 / n)の値には下限を設定できません。(「スリープ」関数を呼び出すか、変数「リスト」を調べる必要があります。または、チューリングマシンで入力テープを調べる必要があります。そのため、かかる時間は、nがε+ 1 / n、O(1 / n)ではない)
ShreevatsaR

16
T(0)=∞の場合、停止しません。「T(0)=∞」というようなものはありませんが、それでも停止します。さらに、R∪{∞}で作業し、T(0)=∞、およびT(n + 1)= T(n)/ 2を定義した場合でも、すべてのnに対してT(n)=∞になります。繰り返します。離散値関数がO(1 / n)の場合、すべての十分に大きいnの場合は0です。[証明:T(n)= O(1 / n)は、次のような定数cが存在することを意味しますn> N0の場合、T(n)<c(1 / n)、つまり、n> max(N0,1 / c)の場合、T(n)<1は、T(n)= 0を意味します。]本当か抽象ませマシンは、0時間がかかることができません:それは持っている入力を見て。まあ、何もしないマシンのほか、すべてのnに対してT(n)= 0です。
ShreevatsaR

43
「この質問は、見かけほど馬鹿ではない」で始まるすべての回答を気に入ってください。
テレマコス

138

はい。

実行時O(1 / n)には、「空の」アルゴリズムという正確に1つのアルゴリズムがあります。

アルゴリズムがO(1 / n)であることは、単一の命令で構成されるアルゴリズムよりも少ないステップで漸近的に実行されることを意味します。すべてのn> n0について、1ステップ未満で実行する場合は、それらのnに対してまったく命令を含まないようにする必要があります。「if n> n0」のチェックには少なくとも1つの命令がかかるため、すべてのnに対して命令を含めないでください。

まとめ:O(1 / n)である唯一のアルゴリズムは、命令なしで構成される空のアルゴリズムです。


2
だから誰かが空のアルゴリズムの時間の複雑さは何であるか尋ねた場合、あなたはO(1 / n)で答えるでしょう?どういうわけか私はそれを疑う。
phkahler、2010

24
これはこのスレッドでの唯一の正解です。(私の投票にもかかわらず)投票はゼロです。これはStackOverflowであり、「正しい見た目」の回答が実際に正しい回答よりも高く投票されます。
ShreevatsaR 2010

5
いいえ、正しくないため0と評価されています。Nに依存しないbig-Oh値をNとは無関係に表現することは正しくありません。次に、プログラムが存在する場合でも、実行には少なくとも一定の時間O(1)がかかります。そうでない場合でも、O(1 / n)ではなくO(0)になります。
kenj0418

32
O(0)である関数はすべてO(1 / n)でもあり、O(n)、O(n ^ 2)、O(2 ^ n)でもあります。ため息、簡単な定義を誰も理解していませんか?O()は上限です。
ShreevatsaR 2010

16
@ kenj0418すべての文で間違いを犯しました。「Nに依存しないBig-Oh値をNから独立して表現することは正しくありません。」定数関数は完全に間抜けな関数です。「2番目に、プログラムが存在する場合でも、実行には少なくとも一定の時間がかかりますO(1)。」複雑さの定義は、実際にプログラムを実行することについては何も述べていません。「O(1 / n)ではなくO(0)になります」。@ShreevatsaRのコメントを参照してください。
Alexey Romanov

25

sharptoothは正しく、O(1)が可能な限り最高のパフォーマンスです。ただし、これは高速ソリューションを意味するのではなく、固定時間ソリューションを意味します。

興味深い変種、そしておそらく実際に提案されているのは、人口が増えるにつれて問題が簡単になることです。私は1と考えることができます。

セット内の2人の人の誕生日が同じですか?nが365を超える場合、trueを返します。365未満の場合でも、これはO(n ln n)です。問題は徐々に簡単になるわけではなく、n> 365の場合はO(1)になるため、おそらく良い答えではありません。


7
366.うるう年を忘れないでください!
ニックジョンソン

1
あなたは正しいです。コンピュータと同様に、丸め誤差が時々発生します:-)
エイドリアン

10
+1。nが増加するにつれて「相転移」を起こすNP完全な問題がいくつかあります。つまり、nの特定のしきい値を超えると、すぐに問題が簡単になったり困難になったりします。1つの例は、数値分割問題です。n個の非負整数のセットが与えられた場合、それらを2つの部分に分割して、各部分の合計が等しくなるようにします。これは、特定のしきい値nで劇的に簡単になります。
j_random_hacker 2009年

23

それは可能ではありません。ビッグOの定義は以下の不等式:

A(n) = O(B(n))
<=>
exists constants C and n0, C > 0, n0 > 0 such that
for all n > n0, A(n) <= C * B(n)

したがって、B(n)は実際には最大値であるため、nが増加するにつれてB(n)が減少しても、推定値は変化しません。


42
この答えは「正しい答え」だと思いますが、残念ながら理解する力がありません。
空き領域

12
私の知る限り、この条件はすべてのnに対して真である必要はありませんが、すべてのn> n_0に対して真である必要があります(つまり、入力のサイズが特定のしきい値に達したときのみ)。
Roland Ewald、

30
定義が(修正されていても)OPの問題とどのように矛盾しているかはわかりません。定義は完全に任意の関数に適用されます!1 / nはBにとって完全に賢明な関数であり、実際、方程式はそれと矛盾しません(計算を行うだけです)。したがって、いいえ、多くのコンセンサスにもかかわらず、この答えは実際には間違っています。ごめんなさい。
Konrad Rudolph、

10
違う!私はダウン投票は好きではありませんが、明確なコンセンサスがない場合、これは不可能であるとあなたは述べています。実際には正しいです。1/ nランタイムで関数を構築する場合(簡単)、最終的には最小時間に達し、実装時にO(1)アルゴリズムになります。アルゴリズムが紙の上でO(1 / n)になるのを止めるものは何もありません。
jheriko 2009年

3
@ジェイソン:うん、あなたはそれを言ったので... :) @jheriko:O(1 / n)の時間の複雑さは紙の私見では機能しません。チューリングマシンの成長関数f(入力サイズ)= #opsを特徴付けています。xステップ後に長さn = 1の入力で停止する場合は、入力サイズn >> xを選択します。つまり、アルゴリズムが実際にO(1 / n)である場合、演算は行われません。完了しました。チューリングマシンはこれにどのように気づくべきでしょうか(テープから一度だけ読み取ることはできません)?
Roland Ewald、

16

以前の大きなO表記の学習から、1つのステップ(変数のチェック、代入の実行など)が必要な場合でも、それはO(1)です。

「定数」は関係ないため、O(1)はO(6)と同じであることに注意してください。そのため、O(n)はO(3n)と同じです。

したがって、1ステップも必要な場合はO(1)です。プログラムでは少なくとも1ステップが必要なので、アルゴリズムが実行できる最小値はO(1)です。私たちがそれを行わない限り、それはO(0)だと思いますか?何もしなければ、それはO(1)であり、それが最低限必要なことです。

(私たちがそれをしないことを選択した場合、それはZenまたはTaoの質問になる可能性があります...プログラミングの領域では、O(1)は依然として最小です)。

またはこれはどうですか:

プログラマー:ボス、O(1)時間でそれを行う方法を見つけました!
ボス:それをする必要はありません、私たちは今朝破産しました。
プログラマー:ああ、それでO(0)になります。


あなたのジョークは、プログラミングのタオから何かを思い出させました:canonical.org/~kragen/tao-of-programming.html#book8(8.3)
kenj0418

ゼロステップで構成されるアルゴリズムはO(0)です。これは非常に遅延したアルゴリズムです。
nalply

8

いいえ、これは不可能です:

nは1 / nで無限大になる傾向があるため、最終的には1 /(inf)を達成します。これは事実上0です。

したがって、問題のbig-ohクラスは、nが大きい場合はO(0)になりますが、nが小さい場合は一定時間に近づきます。一定時間よりも速く実行できる唯一のことは次のとおりであるため、これは賢明ではありません。

void nothing() {};

そしてこれも議論の余地があります!

コマンドを実行するとすぐに、少なくともO(1)にいるので、いや、O(1 / n)のbig-ohクラスを持つことはできません!


7

関数をまったく実行しない(NOOP)のはどうですか?または固定値を使用します。それは重要ですか?


16
それはまだO(1)ランタイムです。
Konrad Rudolph、

2
そう、それはまだO(1)です。誰かがこれをどのように理解できるかはわかりませんが、NO-OP以外の可能性があると別の回答で主張しています。
ShreevatsaR

4
ShreevatsaR:全く矛盾はありません。大きなO表記は、関数で費やされた時間とは関係ないことを理解できていないようです。むしろ、入力の変化(特定の値より上)によってその時間どのように変化するかを示しています。詳細については、他のコメントスレッドを参照してください。
Konrad Rudolph、

しっかり掴んでくれてありがとうございます。ポイントは、私が他のスレッドで数回行ったように、入力とともに時間がO(1 / n)で減少した場合、最終的にはNOOPが費やした時間を下回る必要があるということです。これは、アルゴリズムが漸近的にO(1 / n)になることはないことを示していますが、実行時間は限界まで減少する可能性があります。
ShreevatsaR 2010

1
はい...他の場所で述べたように、O(1 / n)のアルゴリズムもすべての入力に対してゼロ時間を取る必要があるため、nullアルゴリズムが0時間かかると考えるかどうかに応じて、O(1 / n)アルゴリズム。そうならば、あなたはNOOPはO(1)であると考え、その後、何のO(1 / n)のアルゴリズムではありません。
ShreevatsaR 2010

7

私はO(1 / n)を使用して、入力が大きくなるにつれて小さくなる確率を記述します-たとえば、公正なコインがlog2(n)フリップでテールになる確率はO(1 / n)です。


6
それは大きなOではありません。質問に答えるためにそれを再定義することはできません。
Zifre 2009年

11
それはまさに大きなO.の定義だ、再定義はありません
ShreevatsaR

10
私は貿易による理論的なコンピューター科学者です。それは関数の漸近的順序についてです。
デイブ、

4
Big Oは、任意の実関数のプロパティです。時間の複雑さは、可能なアプリケーションの1つにすぎません。スペースの複雑さ(アルゴリズムが使用する作業メモリの量)は別です。質問がO(1 / n)アルゴリズムについてであるということは、それがこれらの1つであることを意味します(私が知らないアルゴリズムに適用される別のものがない限り)。その他のアプリケーションには、たとえばConway's Lifeでの人口増加の順序が含まれます。en.wikipedia.org/wiki/Big_O_notation
Stewart、

5
@Dave:問題は、明らかに存在するO(1 / n)関数が存在するかどうかではありませんでした。むしろ、(null関数の可能性のある例外を除いて)存在できないO(1 / n)アルゴリズムが存在するかどうかでした
Casebash

6

O(1)は単に「一定の時間」を意味します。

ループに早期終了を追加すると[1]、(big-O表記で)O(1)アルゴリズムがO(n)に変換されますが、より高速になります。

トリックは、一般的に一定時間アルゴリズムが最良であり、線形は指数関数よりも優れていますが、nの量が少ない場合、指数アルゴリズムは実際には高速になる可能性があります。

1:この例では静的リストの長さを想定


6

この質問を読んでいて、会話が何であるかを理解したい人にとって、これは役立つかもしれません:

|    |constant |logarithmic |linear|  N-log-N |quadratic|  cubic  |  exponential  |
|  n |  O(1)   | O(log n)   | O(n) |O(n log n)|  O(n^2) |  O(n^3) |     O(2^n)    |
|  1 |       1 |          1 |     1|         1|        1|       1 |             2 |
|  2 |       1 |          1 |     2|         2|        4|       8 |             4 |
|  4 |       1 |          2 |     4|         8|       16|      64 |            16 |
|  8 |       1 |          3 |     8|        24|       64|     512 |           256 |
| 16 |       1 |          4 |    16|        64|      256|   4,096 |         65536 |
| 32 |       1 |          5 |    32|       160|    1,024|  32,768 | 4,294,967,296 |
| 64 |       1 |          6 |    64|       384|    4,069| 262,144 |   1.8 x 10^19 |

5

量子アルゴリズムは重ね合わせによって「一度に」複数の計算を実行できると思います...

これは有用な答えではないかと思います。


それはまだ一定の時間になり、すなわちO(1)、それはサイズのデータのために実行するために同じ時間を要するという意味のnそれはサイズ1のデータの場合と同様に
空き領域

2
しかし、問題が薄いエールであった場合はどうなりますか?(ああ、あははは。)
ジェフミートボールヤン

7
それはであることには、スーパーポジションだろう。
ダニエルエリカー

1
量子アルゴリズムは複数の計算を実行できますが、1つの計算の結果しか取得できず、取得する結果を選択することはできません。ありがたいことに、量子レジスタ全体(たとえば、QFT)を操作することもできるので、何かを見つけるのがより簡単です:)
Gracenotes

2
おそらく役に立たないかもしれませんが、真実であるという利点があり、投票数の多い回答のいくつかを上回っていますB
Brian Postow

4

多くの人が正しい答えを持っています(いいえ)これを証明する別の方法を次に示します。関数を使用するには、関数を呼び出し、答えを返す必要があります。これには一定の時間がかかります。大規模な入力の場合、残りの処理にかかる時間が短くても、回答(1ビットであると想定できます)の出力には少なくとも一定の時間がかかります。


2

ソリューションが存在する場合、一定の時間=すぐに準備してアクセスできます。たとえば、並べ替えクエリが逆順であることがわかっている場合は、LIFOデータ構造を使用します。適切なモデル(LIFO)が選択されていれば、データはすでにソートされています。


2

人口が増えるにつれて、どの問題が簡単になりますか?1つの答えは、ダウンロード速度がノード数の逆関数であるビットトレントのようなものです。ロードするほど速度が低下する車とは異なり、bittorrentのようなファイル共有ネットワークは、接続するノードの数を増やします。


はい。ただし、ビットトレントノードの数は、並列コンピュータのプロセッサの数と同じです。この場合の「N」は、ダウンロードしようとしているファイルのサイズになります。コンピューターがN台ある場合、長さNの並べ替えられていない配列の要素を一定の時間で見つけることができるのと同様に、コンピューターがN台ある場合にデータを送信しようとすると、サイズNのファイルを一定の時間でダウンロードできます。
キブビー2009年

2

O(1)を下回ることはできませんが、kがNより小さいO(k)は可能です。それらをサブリニア時間アルゴリズムと呼びました。一部の問題では、サブリニア時間アルゴリズムは特定の問題の近似解しか提供できません。ただし、データセットが大きすぎるか、すべてを計算するには計算コストが高すぎるために、近似解が適切な場合もあります。


1
わかりません。Log(N)はN未満です。それは、Log(N)がサブリニアアルゴリズムであることを意味しますか?そして、多くのLog(N)アルゴリズムが存在します。そのような例の1つは、バイナリツリーで値を見つけることです。ただし、これらは依然として1 / Nとは異なります。Log(N)は常に増加するため、1 / nは減少する関数です。
Kibbee 2009年

定義を見ると、サブリニア時間アルゴリズムは、サイズがNよりも遅くなるアルゴリズムです。そのため、Log(N)という対数時間アルゴリズムが含まれます。
Hao Wooi Lim、

2
ええと、サブリニア時間アルゴリズムは正確な答えを与えることができます。たとえば、RAMマシン上の順序付けられた配列でのバイナリ検索です。
A.レックス

@A。レックス:ハオ・ウーイ・リムは「いくつかの問題で」と言いました。
LarsH

1

これはどうですか:

void FindRandomInList(list l)
{
    while(1)
    {
        int rand = Random.next();
        if (l.contains(rand))
            return;
    }
}

リストのサイズが大きくなると、プログラムの予想される実行時間が減少します。


私はあなたがO(n)の意味を理解していないと思います
Markus Lausberg

ただし、リストではなく、配列またはハッシュでconstainsO(1)を使用
vava 2009年

ランダム関数は遅延配列と考えることができるので、基本的には「遅延ランダムリスト」の各要素を検索し、それが入力リストに含まれているかどうかを確認します。これは線形よりも悪く、良くはないと思います。
09年

intの値のセットが限られていることに気づいたら、彼はある点を理解しています。したがって、lに2 <sup> 64 </ sup>の値が含まれる場合、それはすべて瞬間的に発生します。とにかくO(1)よりも悪くなります:)
vava

1

O(1 / n)はO(1)よりも小さくありません。つまり、基本的には、データが多いほど、アルゴリズムが高速になります。たとえば、配列を取得し、それよりも少ない場合は常に最大10 100の要素を入力し、それ以上の場合は何もしないとします。これはもちろんO(1 / n)ではなく、O(-n)のようなものです:) O-bigの表記が小さすぎると、負の値は許可されません。


1
「O(1 / n)はO(1)よりも小さくありません」-関数fがO(1 / n)の場合、それはO(1)でもあります。そして、big-ohは「より小」の関係のように感じられます。それは再帰的、推移的であり、fとgの間に対称性がある場合、2つは同等です。ここで、big-thetaは等価関係です。ただし、a <= bおよびb <= aがa = bを意味することを必要とするISTRの「実際の」順序関係では、netcraft ^ Wウィキペディアが確認しています。したがって、ある意味では、確かにO(1 / n)はO(1)より「小さい」と言えます。
JonasKölker、2009年

1

指摘したように、null関数の例外の可能性があることを除いO(1/n)て、所要時間が0に近づく必要があるため、関数がない場合があります。

もちろん、Konradによって定義されたようなアルゴリズムがいくつかありますが、それらはO(1)少なくともある意味では少なくなるはずです。

def get_faster(list):
    how_long = 1/len(list)
    sleep(how_long)

これらのアルゴリズムを調査する場合は、独自の漸近測定または独自の時間の概念を定義する必要があります。たとえば、上記のアルゴリズムでは、いくつかの「無料」操作を設定された回数だけ使用できるようにすることができます。上記のアルゴリズムで、睡眠以外のすべての時間を除外してt 'を定義すると、t' = 1 / n、つまりO(1 / n)になります。漸近的な振る舞いはささいなことなので、おそらくより良い例があります。事実、誰かが重要な結果をもたらす感覚を思い付くことができると私は確信しています。


1

残りの回答のほとんどは、big-Oがアルゴリズムの実行時間のみに関するものであると解釈しています。しかし、質問にはそれが言及されていなかったので、数値分析におけるbig-Oの他のアプリケーション、つまりエラーについて言及する価値があると思いました。

多くのアルゴリズムは、ステップサイズ(h)と分割数(n)のどちらを話しているかに応じて、O(h ^ p)またはO(n ^ {-p})になります。たとえば、オイラー法では、y(0)とdy / dx(yの導関数)がわかっていれば、y(h)の推定値を探します。y(h)の推定値は、hが0に近いほど正確です。したがって、任意のxのy(x)を見つけるには、0からxまでの間隔をとり、n個になるまで分割し、オイラー法を実行します。各ポイントで、y(0)からy(x / n)からy(2x / n)などに取得します。

したがって、オイラー法はO(h)またはO(1 / n)アルゴリズムになります。ここで、hは通常ステップサイズとして解釈され、nは区間を分割する回数として解釈されます。

また、浮動小数点の丸め誤差のため、実際の数値解析アプリケーションでO(1 / h)を使用することもできます。間隔を小さくすると、特定のアルゴリズムの実装で発生するキャンセルが多くなり、有効数字の損失が増えるため、エラーがアルゴリズムを通じて伝搬されます。

オイラー法の場合、浮動小数点を使用している場合は、十分に小さなステップとキャンセルを使用して、大きな数に小さな数を追加し、大きな数は変更しないままにします。滑らかな関数yで、y '(x)を(y(x + h)-y(x)/ h)で近似して、2つの非常に近い位置で評価された関数から互いに2つの数値を減算して導関数を計算するアルゴリズムの場合(x + h)はy(x)に近づき、大きなキャンセルとより少ない有効桁数での導関数の推定をもたらします。これは、派生物を必要とするアルゴリズム(たとえば、境界値問題)に伝播します。


0

OK、私はそれについて少し考えました、そしておそらくこの一般的な形式に従うことができるアルゴリズムが存在します:

1000ノードグラフの巡回セールスマン問題を計算する必要がありますが、訪問できないノードのリストも与えられます。訪問でき​​ないノードのリストが大きくなるにつれて、問題の解決が容易になります。


4
O(n)のnの種類は異なります。このトリックを使用すると、すべてのアルゴリズムにO(q)があると言えます。ここで、qは、たとえば中国に住んでいる人の数です。
ヴァバ2009年

2
Boyer-Mooreは同様の種類(O(n / m))ですが、n> = mであるため、実際には「O(1)より優れている」とは言えません。あなたの「訪問不可能なTSP」についても同じことが言えると思います。
ニキ

この場合でも、TSPのランタイムはNP-Completeであり、グラフからノードを削除するだけなので、nを効果的に減らします。
エドジェームス

0

確かに上限にO(1 / n)であるアルゴリズムが表示されます。

ルーチンの外部の何かが原因で変化している一連の大量の入力があり(ハードウェアを反映しているか、それを実行しているプロセッサの他のコアである可能性もあります)、ランダムで有効なものを選択する必要があります。

さて、それが変化していなければ、アイテムのリストを作成し、ランダムに1つ選択してO(1)時間を取得します。ただし、データの動的な性質により、リストを作成することはできません。単にランダムにプローブして、プローブの有効性をテストする必要があります。(そして、本質的に返答が返されたときに答えがまだ有効である保証はありません。これにはまだ用途がある可能性があります。たとえば、ゲーム内のユニットのAIです。トリガーを引く。)

これは、ワーストケースのパフォーマンスが無限大ですが、データスペースがいっぱいになると、平均ケースのパフォーマンスが低下します。


0

数値解析では、近似アルゴリズムは近似許容誤差において準一定の漸近的な複雑さを持っている必要があります。

class Function
{
    public double[] ApproximateSolution(double tolerance)
    {
        // if this isn't sub-constant on the parameter, it's rather useless
    }
}

あなたは本当にサブ定数、またはサブリニアを意味しますか?なぜ近似アルゴリズムは定数以下でなければならないのですか?そしてそれはどういう意味ですか?
LarsH

@LarsH、近似アルゴリズムのエラーはステップサイズ(またはその正の累乗)に比例するため、ステップサイズが小さいほどエラーは小さくなります。しかし、近似問題を調べる別の一般的な方法は、間隔が分割された回数と比較したエラーです。間隔のパーティション数はステップサイズに反比例するため、エラーはパーティション数の正のパワーに反比例します。パーティション数を増やすと、エラーは減少します。
Andrew Lei

@AndrewLei:うわー、ほぼ7年後の答え!私は今よりもサムの答えをよく理解しています。ご返信いただきありがとうございます。
LarsH 2017

0

O(1)未満は不可能だと思います。アルゴが取った時間はすべてO(1)と呼ばれます。しかし、O(1 / n)の場合、以下の関数はどうでしょう。(私はこのソリューションですでに提示された多くのバリアントがあることを知っていますが、それらはすべていくつかの欠陥があると思います(メジャーではなく、それらはコンセプトをよく説明しています)。

def 1_by_n(n, C = 10):   #n could be float. C could be any positive number
  if n <= 0.0:           #If input is actually 0, infinite loop.
    while True:
      sleep(1)           #or pass
    return               #This line is not needed and is unreachable
  delta = 0.0001
  itr = delta
  while delta < C/n:
    itr += delta

したがって、nが増加するにつれて、関数の所要時間はますます短くなります。また、入力が実際に0の場合、関数が戻るまでに時間がかかることが保証されます。

機械の精度によって制限されると主張する人もいるでしょう。したがって、sinc eitには上限があり、O(1)です。しかし、文字列でnとCの入力を取得することで、これをバイパスすることもできます。そして、追加と比較は文字列で行われます。これにより、nを任意に小さくすることができます。したがって、n = 0を無視しても、関数の上限は制限されません。

また、ランタイムがO(1 / n)であるとは言えないと私は信じています。しかし、O(1 + 1 / n)のようなものを言う必要があります


-1

O(1 / n)であるアルゴリズムを構築することは可能かもしれません。1つの例は、f(n)がnよりも大きいことが保証されている関数であるf(n)-nの倍数を反復するループであり、nが無限大に近づくときのf(n)-nの制限は、ゼロ。f(n)の計算も、すべてのnに対して一定である必要があります。私はf(n)がどのように見えるのか、またはそのようなアルゴリズムがどのようなアプリケーションを持っているのかわからないが、私の意見ではそのような関数が存在する可能性はあるが、結果のアルゴリズムはアルゴリズムの可能性を証明する以外に目的はないO(1 / n)。


ループは少なくとも一定の時間を要するチェックを必要とするため、結果のアルゴリズムは少なくとも複雑度O(1)を持ちます。
ステファンライヒ

-1

アルゴリズムについては知りませんが、ランダム化されたアルゴリズムでは、O(1)未満の複雑さが現れます。実際、o(1)(少しo)はO(1)よりも小さいです。この種の複雑さは通常、ランダム化されたアルゴリズムに現れます。たとえば、あなたが言ったように、あるイベントの確率が1 / nのオーダーであるとき、それらはo(1)でそれを示します。または、何かが高い確率で発生することを言いたい場合(例:1-1 / n)、1-o(1)でそれを示します。


-2

入力データに関係なく答えが同じ場合は、O(0)アルゴリズムがあります。

または言い換えると、入力データが送信される前に答えがわかる-関数を最適化できる-O(0)


本当に?あなたはまだ値を返す必要があるでしょう、それでそれはまだO(1)ではないでしょうか?
ヨアヒムザウアー

7
いいえ、O(0)はすべての入力に対して時間がかからないことを意味します。O(1)は一定時間です。
ピートカーカム

-2

Big-O表記は、アルゴリズムの最悪のシナリオを表しています。これは、通常のランタイムとは異なります。O(1 / n)アルゴリズムがO(1)アルゴリズムであることを証明するのは簡単です。定義により、
O(1 / n)-> T(n)<= 1 / n、すべてのn> = C> 0に対して
O(1 / n)-> T(n)<= 1 / C、 1 / n <= 1 / C for all n> = C
O(1 / n)-> O(1)、Big-O表記は定数を無視するため(つまり、Cの値は関係ありません)


いいえ:Big O表記は、平均ケースおよび予想時間(さらにはベストケース)のシナリオについても説明するために使用されます。残りは続く。
Konrad Rudolph、

「O」表記は確かに上限を定義します(アルゴリズムの複雑さの点では、これが最悪のケースになります)。オメガとシータは、それぞれ最良のケースと平均的なケースを示すために使用されます。
Roland Ewald、

2
ローランド:それは誤解です。上限は最悪の場合と同じではなく、2つは独立した概念です。hashtable-containsO(1)として表すことができるアルゴリズムの予想される(および平均の)実行時間を考慮してください。最悪の場合は、Theta(n)として非常に正確に指定できます。オメガとシータは単に他の境界を示すために使用されるかもしれませんが、もう一度言います。それらは平均または最良のケースとは何の関係もありません。
Konrad Rudolph、

コンラッド:そうだ。それでも、オメガ、シーアタ、Oは通常、境界を表すために使用されます。可能な入力がすべて考慮される場合、Oは上限を表します。など
Roland Ewald

1
O(1 / n)がO(1)のサブセットであるという事実は自明であり、定義から直接従います。実際、関数gがO(h)の場合、O(g)である関数fもすべてO(h)です。
トビアス

-2

O(1)よりも小さいものはありませんBig-O表記は、アルゴリズムの最大の複雑さを意味します

アルゴリズムの実行時間がn ^ 3 + n ^ 2 + n + 5の場合、それはO(n ^ 3)です。n-> Infであるため、n ^ 2は、 n ^ 3

同様に、n-> Infと同様に、O(1 / n)はO(1)と比較して無関係であるため、3 + O(1 / n)はO(1)と同じになるため、O(1)は可能な限り最小の計算になります複雑


-2
inline void O0Algorithm() {}

1
それはO(1)アルゴリズムです。
Lasse V. Karlsen、2010年

2
それも同じですが、ポイントはΩ(1)ではないということです。そして、なぜ私の答えは低くなっているのですか?私が間違っていると思うなら、説明してみませんか?
スチュワート

:私は基本的に、この非常に答えが正しいかどうか、他の場所であれば尋ね、そしてそれが係争しているようだstackoverflow.com/questions/3209139/...
jyoungdev

それはインラインなので、O(0)と見なすことができます。ただし、すべてのO(0)アルゴリズムは取るに足らない(何もしない)ので、非常に興味深い答えではありません。
ステファンライヒ

@StefanReich確かに、これはそれほど興味深い答えではありませんが答えです。
スチュワート

-2

簡単なO(1 / n)アルゴリズムを次に示します。そしてそれは面白いことさえします!

function foo(list input) {
  int m;
  double output;

  m = (1/ input.size) * max_value;  
  output = 0;
  for (int i = 0; i < m; i++)
    output+= random(0,1);

  return output;
}

O(1 / n)は、入力のサイズが大きくなると関数の出力がどのように変化するかを説明するため、可能です。関数1 / nを使用して関数が実行する命令の数を記述している場合、関数が任意の入力サイズで命令を0にする必要はありません。むしろ、すべての入力サイズについて、あるしきい値を超えるnの場合、必要な命令の数は、1 / nを掛けた正の定数によって制限されます。1 / nが0である実際の数はなく、定数は正なので、関数が0以下の命令を取るように制約される理由はありません。


1
O(1 / n)は水平線= 1を下回るので、nが無限大に達しても、コードは引き続き指定された数のステップを実行するため、このアルゴリズムはO(1)アルゴリズムです。Big-O表記は、アルゴリズムのさまざまな部分の関数であり、最大のものを選択します。メソッドは常にいくつかの命令を実行するので、nが無限に達すると、同じ命令が毎回実行されたままになり、メソッドは一定の時間で実行されます。確かに、それほど時間はかかりませんが、Big-O表記とは関係ありません。
Lasse V. Karlsen、2010年
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.