編集:リビジョン3のメジャーリビジョン。
私はクラスを教えたことがないので、私たちが教えるべきことについて納得のいくように主張できるとは思いません。それにもかかわらず、ここに私がそれについて考えたことがあります。
書かれている「制限トリック」を適用できない自然な例があります。たとえば、サイズが2倍になる固定長配列を使用して(つまり、配列のサイズを超えようとするたびに、「可変長ベクトル」(C ++のvector <T>など)を実装するとします。配列を現在の2倍に再割り当てし、すべての要素をコピーします)。サイズS(nはアレイの)我々が格納Nベクトルの要素は、2より大きな最小の力であるかに等しいN。S(n)= O(n)と言いたいのですが、定義として書かれている「制限トリック」を使用すると、S(n)/ nは、範囲[1,2)で密に振動します。同じことがΩ()とΘ()にも当てはまります。
多少別の問題として、これらの表記を使用してアルゴリズムの複雑さを説明する場合、Ω()の定義は時々不便であると思います(その定義は一般的だと思いますが)。limsup f(n)/ g(n)> 0の場合に限り、f(n)=Ω(g(n))と定義する方が便利です。これは、n(頂点の数nが奇数のグラフ上の完全な加工問題など)。同じことがΘ()とω()にも当てはまります。
したがって、私は個人的に、次の定義がアルゴリズムの複雑さを説明するために使用するのに最も便利であることを見つけます:関数f、gについて:ℕ→ℝ > 0、
- f(n)= o(g(n))limsup f(n)/ g(n)= 0の場合にのみ(これはlim f(n)/ g(n)= 0 と同等です。)
- limsup f(n)/ g(n)<∞の場合にのみ、f(n)= O(g(n))
- f(n)=Θ(g(n))0 <limsup f(n)/ g(n)<∞の場合のみ。
- limsup f(n)/ g(n)> 0の場合に限り、f(n)=Ω(g(n))(これは、f(n)がo(g(n))ではないことに相当します
- f(n)=ω(g(n))limsup f(n)/ g(n)=∞の場合のみ。(これは、f(n)がO(g(n))ではないことに相当します。)
または同等に、
- F(N)= O(G(N))とのみすべてのための場合であれば、C > 0、十分に大きいため、N、F(N)≤ C ⋅ G(N)。
- F(N)= O(G(N))と一部のみのためであればならC > 0、十分に大きいため、N、F(N)≤ C ⋅ G(N)。
- f(n)=Θ(g(n))f(n)= O(g(n))およびf(n)=Ω(g(n))の場合にのみ
- F(N)=Ω(G(N))場合にのみ、いくつかのためであれば、D無限に多くのために> 0、N、F(N)≥ D ⋅ G(N)。
- F(N)=ω(G(N))毎および場合だけ、D > 0、無限に多くのためのN、F(N)≥ D ⋅ G(N)。
しかし、これが一般的な慣行であるかどうかはわかりません。また、教育に適しているかどうかもわかりません。問題は、代わりにliminfでΩ()を定義したい場合があることです(最初の定義で行ったように)。たとえば、「このランダム化されたアルゴリズムのエラーの確率は2 -Ω(n)」と言うとき、エラーの確率が無限に多く nに対してのみ指数関数的に小さいことを意味しません!