Najpierw zrozumiemy, czym są duże O, duże Theta i duże Omega. Wszystkie są zbiorami funkcji.
Duże O daje górną asymptotyczną granicę , podczas gdy duża Omega daje dolną granicę. Big Theta daje jedno i drugie.
Wszystko, co jest, Ө(f(n))
jest także O(f(n))
, ale nie na odwrót.
T(n)
mówi się, że jest w Ө(f(n))
środku, jeśli jest zarówno wewnątrz, jak O(f(n))
i wewnątrz Omega(f(n))
.
W zestawach terminologii Ө(f(n))
jest przecięcie z O(f(n))
aOmega(f(n))
Na przykład, w przypadku scalania sortowania najgorszym przypadkiem jest zarówno O(n*log(n))
i Omega(n*log(n))
- i tak też jest Ө(n*log(n))
, ale jest też O(n^2)
, ponieważ n^2
jest asymptotycznie „większe” od niego. Jednak tak nie jest Ө(n^2)
, ponieważ algorytm nie jest Omega(n^2)
.
Nieco głębsze wyjaśnienie matematyczne
O(n)
jest asymptotyczną górną granicą. Jeśli T(n)
tak O(f(n))
, to znaczy, że od pewnego n0
istnieje stała C
taka, że T(n) <= C * f(n)
. Z drugiej strony, big-Omega mówi, że nie jest stała C2
, tak żeT(n) >= C2 * f(n))
).
Nie myl!
Nie mylić z analizą przypadków najgorszych, najlepszych i średnich: wszystkie trzy notacje (Omega, O, Theta) nie są związane z analizą najlepszych, najgorszych i średnich przypadków algorytmów. Każdy z nich można zastosować do każdej analizy.
Zwykle używamy go do analizy złożoności algorytmów (jak powyższy przykład sortowania przez scalanie). Kiedy mówimy „Algorytm A jest O(f(n))
”, tak naprawdę mamy na myśli to, że „Złożoność algorytmów w analizie najgorszego 1 przypadku jest O(f(n))
” - co oznacza - skaluje „podobny” (lub formalnie nie gorszy niż) funkcję f(n)
.
Dlaczego zależy nam na asymptotycznej granicy algorytmu?
Cóż, jest wiele powodów, ale uważam, że najważniejsze z nich to:
- Znacznie trudniej jest określić dokładną funkcję złożoności, dlatego „idziemy na kompromis” w notacjach duże-O / duże-Theta, które są wystarczająco pouczające teoretycznie.
- Dokładna liczba operacji zależy również od platformy . Na przykład, jeśli mamy wektor (listę) 16 liczb. Ile operacji to zajmie? Odpowiedź brzmi: to zależy. Niektóre procesory pozwalają na dodawanie wektorów, podczas gdy inne nie, więc odpowiedź różni się w zależności od różnych implementacji i różnych maszyn, co jest niepożądaną właściwością. Jednak notacja duże-O jest znacznie bardziej stała między maszynami i implementacjami.
Aby zademonstrować ten problem, spójrz na poniższe wykresy:
Oczywiste jest, że f(n) = 2*n
jest „gorszy” niż f(n) = n
. Ale różnica nie jest tak drastyczna, jak w przypadku innej funkcji. Widzimy, że f(n)=logn
szybko staje się znacznie niższy niż inne funkcje i f(n) = n^2
szybko staje się znacznie wyższy niż inne.
Tak więc - z powyższych powodów „ignorujemy” współczynniki stałe (2 * w przykładzie wykresów) i przyjmujemy tylko notację duże-O.
W powyższym przykładzie, f(n)=n, f(n)=2*n
będzie zarówno w, jak O(n)
i w Omega(n)
- a zatem również będzie w Theta(n)
.
Z drugiej strony - f(n)=logn
będzie w O(n)
(jest "lepszy" niż f(n)=n
), ale NIE będzie w Omega(n)
- a więc też NIE będzie Theta(n)
.
Symetrycznie f(n)=n^2
będzie w Omega(n)
, ale NIE O(n)
, a zatem - też NIE Theta(n)
.
1 Zwykle, choć nie zawsze. kiedy brakuje klasy analizy (najgorsza, średnia i najlepsza), tak naprawdę mamy na myśli najgorszy przypadek.