Спершу розберемося, що таке велика О, велика Тета та велика Омега. Вони всі набори функцій.
Великий O дає верхню асимптотичну межу , а великий Omega - нижню. Велика Тета дає і те, і інше.
Все, що є Ө(f(n))
, також є O(f(n))
, але не навпаки.
T(n)
кажуть, що Ө(f(n))
він є, якщо він є і в, O(f(n))
і в Omega(f(n))
.
У термінології множин, Ө(f(n))
є перетином з O(f(n))
іOmega(f(n))
Наприклад, найгірший випадок злиття є O(n*log(n))
і Omega(n*log(n))
- і, таким чином, також є Ө(n*log(n))
, але він також є O(n^2)
, оскільки n^2
асимптотично "більший", ніж він. Однак це не так Ө(n^2)
, оскільки алгоритм ні Omega(n^2)
.
Трохи глибше математичне пояснення
O(n)
є асимптотичною верхньою межею. Якщо T(n)
є O(f(n))
, це означає, що з певного n0
є константа C
така T(n) <= C * f(n)
. З іншого боку, великий Omega каже , що існує постійна C2
така , що T(n) >= C2 * f(n))
).
Не плутайте!
Не плутати з аналізом найгірших, найкращих та середніх випадків: усі три позначення (Omega, O, Theta) не пов'язані з аналізом алгоритмів найкращих, найгірших та середніх випадків. Кожен з них може бути застосований до кожного аналізу.
Зазвичай ми його використовуємо для аналізу складності алгоритмів (як приклад сортування злиття вище). Коли ми говоримо "Алгоритм A є O(f(n))
", то, що ми насправді маємо на увазі, "складність алгоритмів під найгіршим аналізом 1 випадку O(f(n))
" - це означає - він масштабує "аналогічну" (або формально, не гіршу) функцію f(n)
.
Чому ми піклуємося про асимптотичну зв’язаність алгоритму?
Ну, причин для цього багато, але я вважаю, що найважливіші з них:
- Набагато складніше визначити точну функцію складності, тому ми "робимо компроміс" щодо нотацій big-O / big-Theta, які є теоретично досить інформативними.
- Точна кількість операцій також залежить від платформи . Наприклад, якщо у нас є вектор (список) з 16 чисел. Скільки операцій знадобиться? Відповідь: це залежить. Деякі процесори дозволяють додавати векторні доповнення, а інші - ні, тому відповідь відрізняється між різними реалізаціями та різними машинами, що є небажаною властивістю. Однак позначення big-O набагато більш постійні між машинами та реалізаціями.
Щоб продемонструвати це питання, подивіться наступні графіки:
Зрозуміло, що f(n) = 2*n
"гірше", ніж f(n) = n
. Але різниця не така вже й драматична, як від інших функцій. Ми можемо бачити, що f(n)=logn
швидко стає значно нижчим, ніж інші функції, і f(n) = n^2
швидко стає набагато вище, ніж інші.
Отже - із наведених вище причин ми «ігноруємо» постійні фактори (2 * у прикладі графіків) та приймаємо лише позначення big-O.
У наведеному вище прикладі f(n)=n, f(n)=2*n
буде і в, O(n)
і в Omega(n)
- і, таким чином, також буде в Theta(n)
.
З іншого боку - f(n)=logn
буде в O(n)
(це "краще", ніж f(n)=n
), але НЕ буде в Omega(n)
- і, таким чином, також НЕ буде в Theta(n)
.
Симетрично, f(n)=n^2
буде в Omega(n)
, але НЕ в O(n)
, і, таким чином, - також НЕ Theta(n)
.
1 Зазвичай, хоча і не завжди. коли клас аналізу (найгірший, середній та найкращий) відсутній, ми дійсно маємо на увазі найгірший випадок.