計算量の表現 (O|Θ|Ω)記法まとめ

アルゴリズムの計算量を表現する方法として、O記法や\Theta記法、\Omega記法があります。
それらの定義と違いについてまとめていきます。

定義

何らかのアルゴリズムの計算量が自然数から自然数への関数f(n)で表されるとするとき それぞれの定義はこのようになっています $$ O(g(n))=\lbrace f:\mathbb{N} \rightarrow \mathbb{N}|\exists{c}>0\exists{n_0}\forall{n}>n_0[f(n)\leq cg(n)]\rbrace $$ $$ \Theta (g(n))=\lbrace f:\mathbb{N} \rightarrow \mathbb{N}|\exists{c_1}>0\exists{c_2}>0\exists{n_0}\forall{n}>n_0[c_1g(n)\leq f(n)\leq c_2g(n)]\rbrace $$ $$ \Omega (g(n))=\lbrace f:\mathbb{N} \rightarrow \mathbb{N}|\exists{c}>0\exists{n_0}\forall{n}>n_0[cg(n)\leq f(n)]\rbrace $$ ここで、f(n)\in O(g(n))であるときに、そのアルゴリズムの計算量はO(g(n))であるといいます。\Thetaおよび\Omegaについても同様です。

解説

上の定義をみて「なるほど」ってなった人はここより先は読む必要はありません。

まず、\Thetaについて解説していきます。それ以外のものはこれを少し変化したものだからです。 $$ \Theta (g(n))=\lbrace f:\mathbb{N} \rightarrow \mathbb{N}|\exists{c_1}>0\exists{c_2}>0\exists{n_0}\forall{n}>n_0[c_1g(n)\leq f(n)\leq c_2g(n)]\rbrace $$ 定義を再掲しておきます。
まず、 $$ \Theta(g(n))=\lbrace f:\mathbb{N} \rightarrow \mathbb{N}|\cdots \rbrace $$ この部分は、\Theta(g(n))f:\mathbb{N}\rightarrow \mathbb{N} (自然数から自然数への関数)からなる集合だといっています。この部分は正直無視してもいいと思います。
|よりも右側ではその関数の条件を指定しています。 $$ \exists{c_0}>0\exists{c_1}>0\exists{n_0}\forall{n}>n_0[c_1g(n)\leq f(n)\leq c_2g(n)] $$ 日本語で表記するなら「c_0(>0)c_1(>0)n_0が存在してそれらはすべてのn(>n_0)に対してc_1g(n)\leq f(n)\leq c_2g(n)が成立する」というところでしょうか
左側から順に表記しているので日本語と記号の対応関係は探してください
つまり、f(n)の増加をg(n)の定数倍で挟めるということです
直感的には、計算量が\Theta(g(n))というのはnが大きいとき計算量をg(n)の定数倍でだいたい近似できると思えばいいと思います

Oおよび\Omegaについては、\Thetaの式からc_1c_2のどちらかが無いものなので、
f\in O(g(n))であるとき、f(n)nが十分大きいとき、g(n)の定数倍より大きくない
f\in \Omega(g(n))であるとき、f(n)nが十分大きいとき、g(n)の定数倍より小さくない
ということを表すのでOは計算量の上限を、\Omegaは計算量の下限を表してるといえます。

上限と下限しか表さないので、計算量がf(n)=5n^3+2n^2+3n+1のとき、この計算量はO(n^3)ですが、O(n^5)であるともいえます。なんならO(n!)と書いても間違いではありません。\Omegaについても同様で、\Omega(n)とか\Omega(\log n)\Omega(1)と書いても間違いではありません。

例えば、計算量がf(n)=5n^3+2n^2+3n+1で表されるとき、この計算量は\Theta(n^3)であるといえます。

\Theta(n^3)の定義より、あるn_0よりも大きいすべてのnに対して $$ c_1n^3\leq 5n^3+2n^2+3n+1 \leq c_2n^3 $$ が成立するc_1c_2が存在します。
これを各辺n^3で割ると $$ c_1\leq5+\frac{2}{n}+\frac{3}{n^2}+\frac{1}{n^3} \leq c_2 $$ nが十分大きいとき、\frac{2}{n}+\frac{3}{n^2}+\frac{1}{n^3}は0に収束するので、これを満たすcc_1c_2は存在します

逆に、計算量がf(n)=2n^2+3n+1で表されるとき、この計算量は\Theta(n^3)ではありません。

f\in \Theta(n^3)であるなら\Theta(n^3)の定義より、あるn_0よりも大きいすべてのnに対して $$ c_1n^3\leq 2n^2+3n+1 \leq c_2n^3 $$ が成立するc_1c_2が存在するはずです。
これを各辺n^3で割ると $$ c_1\leq \frac{2}{n}+\frac{3}{n^2}+\frac{1}{n^3} \leq c_2 $$ nが十分大きいとき、\frac{2}{n}+\frac{3}{n^2}+\frac{1}{n^3}は0に収束するので、どんな大きなnに対してもこの式が成立するc_1(>0)は存在しません。

実用上簡単な方法として、計算量の式のうち、1番発散が早い項から係数を外してg(n)としてO(g(n))にするとOKだったりします
アルゴリズムの計算量で扱うのは最悪計算量であることが多いのでOのみわかれば十分な場合も多いです(競プロだとだいたいこれ)
(\Theta及び\Omegaについては必ずしも成立しません(例:インサートソートは\Omega(n)O(n^2)なので\Omegaは発散が早い項を入れるだけではだめで、\Thetaを定義できません))

ちなみに、発散が早い項というのは、早い順に
n!> 2^n > \cdots > n^3>n^2> n\log n>n >\log n>1 といった感じです(\sqrt{n}がどこに入るのかいまいち把握してないけど\log nと同じかちょっと大きいぐらいと思っている)

まとめ

O\Thetaでの表記は深く考えずにだいたい同じだと思ってもそんなに問題ない(自分で書くときには書き分ける)
\Omegaはほとんど使わない