Thetaと[〜#〜] o [〜#〜]表記の違いを理解しようとすると、次の文に出くわしました:
The Theta-notation asymptotically bounds a function from above and below. When
we have only an asymptotic upper bound, we use O-notation.
しかし、私はこれを理解していません。本は数学的にそれを説明していますが、あまりにも複雑で、私が本当に理解していないときに読むのは本当に退屈になります。
シンプルでありながら強力な例を使用して、2つの違いを誰でも説明できますか?.
Big Oは漸近上界のみを与え、Big Thetaは下界を与えます。
Theta(f(n))
であるものはすべてO(f(n))
でもありますが、その逆ではありません。T(n)
は、Theta(f(n))
とO(f(n))
の両方である場合、Omega(f(n))
と呼ばれます
このため、big-Thetaはbig-O表記よりも情報量が多いため、何かがbig-Thetaであると言えれば、通常はこれが好まれます。しかし、何かが大きいことを証明することは、それが大きいことを証明することよりも難しいです。
exampleの場合、 merge sort はO(n*log(n))
とTheta(n*log(n))
の両方ですが、O(n2)、n2 それより漸近的に「大きい」。ただし、シータ(n2)、アルゴリズムはOmega(n2)。
Omega(n)
は漸近的下限です。 T(n)
がOmega(f(n))
である場合、特定のn0
から、T(n) >= C1 * f(n)
などの定数C1
があることを意味します。 big-Oは、T(n) <= C2 * f(n))
のような定数C2
があると言います。
3つすべて(Omega、O、Theta)は、漸近情報(「大きな入力用」)のみを提供します。
この表記は、アルゴリズムの最良、最悪、および平均のケース分析に関連するnotであることに注意してください。これらのそれぞれを各分析に適用できます。
Knuth's TAOCP Volume 1-110ページ(インド版を持っています)から引用します。 107-110ページを読むことをお勧めします(セクション1.2.11漸近表現)
人々はしばしば、正確な成長の順序を与えると仮定してO表記を混同します。上限と同様に下限も指定するかのように使用します。たとえば、実行時間はO(n ^ 2)であるため、アルゴリズムは非効率と呼ばれる場合があります。ただし、O(n ^ 2)の実行時間は、実行時間がO(n)でもないことを必ずしも意味しません
107ページで、
1 ^ 2 + 2 ^ 2 + 3 ^ 2 + ... + n ^ 2 = O(n ^ 4)および
1 ^ 2 + 2 ^ 2 + 3 ^ 2 + ... + n ^ 2 = O(n ^ 3)および
1 ^ 2 + 2 ^ 2 + 3 ^ 2 + ... + n ^ 2 =(1/3)n ^ 3 + O(n ^ 2)
Big-Ohは近似用です。 〜を等号=記号に置き換えることができます。上記の例では、nが非常に大きい場合、量がn ^ 4およびn ^ 3および(1/3)n ^ 3 + n ^ 2 [および単にn ^ 2ではない]を下回らないことが保証されます。
Big Omegaは下限用です-Omega(n ^ 2)を使用したアルゴリズムは、Nが大きい場合のO(N logN)を使用したアルゴリズムほど効率的ではありません。ただし、Nの値はわかりません(その意味では、約)
ビッグシータは、下限と上限の両方の正確な成長順序です。
実行時間がbig-O表記で表されている場合、実行時間が指定の式より遅くならないことがわかります。最悪のシナリオを表します。
しかし、シータ表記を使用すると、高速化されないこともわかっています。つまり、アルゴリズムがより速く再調整される最良のシナリオはありません。
これにより、予想される実行時間がより正確に制限されます。ただし、ほとんどの場合、下限(実行の高速化の可能性)を無視する方が簡単ですが、一般的には最悪のシナリオのみに関心があります。
これが私の試みです:
関数f(n)
は、O(n)
のような定数c
が存在する場合にのみ、f(n) <= c*g(n)
です。
この定義を使用して、関数f(2^(n+1))
はO(2^n)
であると言えますか?
つまり、_2^(n+1) <= c*(2^n)
のような定数_'c'
_は存在しますか? 2番目の関数(_2^n
_)は、上記の問題のBig Oの後の関数です。これは最初私を混乱させました。
したがって、基本的な代数スキルを使用して、その方程式を単純化します。 2^(n+1)
は、_2 * 2^n
_に分類されます。そうすることで、次のことができます。
2 * 2^n <= c(2^n)
簡単になったので、式はc
の任意の値を保持します。ここで_c >= 2
_したがって、はい、f(2^(n+1))
はO(2^n)
であると言えます。
Big Omegaは、いくつかの定数_'c'
_に対してf(n)
> =c*g(n)
を評価することを除いて、同じように機能します。
したがって、上記の関数を同じように単純化すると、次のようになります(> =になりました)。
2 * 2^n >= c(2^n)
したがって、方程式は_0 <= c <= 2
_の範囲で機能します。したがって、f(2^(n+1))
は_(2^n)
_のBig Omegaと言うことができます。
さて、これらの両方が成り立つので、関数はBig Theta(_2^n
_)であると言えます。それらのいずれかが_'c'
_の定数に対して機能しない場合、Big Thetaではありません。
上記の例は、素晴らしい本であるSkienaのAlgorithm Design Manualから引用したものです。
お役に立てば幸いです。これは本当に単純化するのが難しい概念です。 _'c'
_が何であるかということにこだわるのではなく、単純な用語に分解して基本的な代数スキルを使用するだけです。
違いを説明するために例を使用します。
関数f(n)を次のように定義します
if n is odd f(n) = n^3
if n is even f(n) = n^2
CLRSから
関数f(n)は、正の定数c1およびc2が存在し、c1g(n)とc2g( n)、十分に大きいnの場合。
そして
O(g(n))= {f(n):正の定数cおよびn0が存在し、0≤f(n)=≤cg(n)すべてのn≥n0}に対して存在します。
そして
Ω(g(n))= {f(n):正の定数cおよびn0が存在し、0≤cg(n)≤f(n)すべてのn≥n0}に対して存在します。
f(n)の上限はn ^ 3です。したがって、関数f(n)は明らかにO(n ^ 3)です。
しかし、それはΘ(n ^ 3)ですか?
f(n)がΘ(n ^ 3)になるには、一方が下限を形成し、他方が上限を形成する2つの関数の間に挟まれなければなりません。 ^ 3。上限は明らかですが、下限はn ^ 3にはできません。下限は実際にはn ^ 2です; f(n)はΩ(n ^ 2)
CLRSから
任意の2つの関数f(n)およびg(n)に対して、f(n) =Θ(g(n))はf(n) = O(g(n)) and f(n) =Ω(g(n ))。
したがって、f(n)はΘ(n ^ 3)ではなく、O(n ^ 3)およびΩ(n ^ 2)にあります
非常に簡単な言語の違いは次のようになります。
Big O表記は、アルゴリズムの最悪の場合の分析に使用されます。 Big Omegaは、アルゴリズムのベストケース分析に使用されます。 Big Thetaは、最良のケースと最悪のケースの分析が同じ場合に、アルゴリズムの分析に使用されます。
バイナリ検索アルゴリズムを使用して、ソートされた配列で数値を探しているとしましょう。
[1 2 3 4 5 6 7]
最悪の場合、ターゲットが1の場合など、log(n)スプリットチェックを実行する必要があります。これは、この例ではlog(7)です。 O(n)と表現できます。
最適なケースでは、ターゲットが3の場合、1つの操作のみを実行します。 Ω(1)で表すことができます