У чому різниця між Big-O нотації O(n)
і Little-O нотації o(n)
?
У чому різниця між Big-O нотації O(n)
і Little-O нотації o(n)
?
Відповіді:
f ∈ O (g) говорить, по суті
За принаймні , один вибір постійної до > 0, можна знайти константу , що <має місце для всіх х = е (х) <= кг (х)> а нерівність 0.
Зауважте, що O (g) - це сукупність усіх функцій, щодо яких ця умова виконується.
f ∈ o (g) говорить, по суті
Для кожного вибору константи k > 0 можна знайти константу a таку, що нерівність 0 <= f (x) <kg (x) виконується для всіх x> a.
Ще раз зауважте, що o (g) - це множина.
У Big-O необхідно лише знайти конкретний множник k, для якого нерівність перевищує деякий мінімум x .
У Little-o має бути так, що існує мінімум x, після якого нерівність виконується незалежно від того, наскільки малим ви будете робити k , доки він не від'ємний чи нульовий.
Обидва вони описують верхні межі, хоча дещо протиінтуїтивно, Little-o є сильнішим твердженням. Існує набагато більший розрив між темпами зростання f і g, якщо f ∈ o (g), ніж якщо f ∈ O (g).
Однією з ілюстрацій невідповідності є така: f ∈ O (f) вірно, але f ∈ o (f) помилково. Тому Big-O можна читати як "f ∈ O (g) означає, що асимптотичний ріст f не швидший ніж g", тоді як "f ∈ o (g) означає, що асимптотичний ріст f суворо повільніше, ніж g". Це як <=
проти <
.
Більш конкретно, якщо значення g (x) є постійним кратним значенням f (x), то f ∈ O (g) вірно. Ось чому ви можете скидати константи під час роботи з нотацією big-O.
Однак, щоб f ∈ o (g) було істинним, тоді g повинна включати у свою формулу більшу потужність x, і тому відносне розділення між f (x) та g (x) повинно насправді збільшуватися, коли x стає більшим.
Щоб використовувати суто математичні приклади (а не посилатися на алгоритми):
Наступне стосується Big-O, але не було б правдою, якби ви використовували little-o:
Наступне стосується Little-o:
Зауважимо, що якщо f ∈ o (g), то це означає f ∈ O (g). наприклад, x² ∈ o (x³), тож правда також, що x² ∈ O (x³), (знову ж таки, думайте про O як <=
і o як <
)
a
є k
те, що: ...", це "для кожного k
є a
те, що: ..."
Big-O - це мало-o, як ≤
це робити <
. Big-O - це верхня межа, що включає, а little-o - це сувора верхня межа.
Наприклад, функція f(n) = 3n
:
O(n²)
, o(n²)
іO(n)
O(lg n)
, o(lg n)
абоo(n)
Аналогічно, це число 1
:
≤ 2
, < 2
І≤ 1
≤ 0
, < 0
або< 1
Ось таблиця із загальною ідеєю:
(Примітка: таблиця є хорошим керівництвом, але її граничне визначення повинно бути в порівнянні з верхньою межею замість нормальної межі. Наприклад, 3 + (n mod 2)
вічно коливається між 3 і 4. Це O(1)
незважаючи на відсутність нормальної межі, оскільки вона все ще має a lim sup
: 4.)
Я рекомендую запам'ятати, як позначення Big-O перетворюється на асимптотичні порівняння. Порівняння легше запам’ятати, але менш гнучкі, тому що ви не можете сказати такі речі, як n O (1) = P.
Я вважаю, що коли я не можу концептуально зрозуміти щось, думка про те, чому можна використовувати X , корисно зрозуміти X. (Не кажучи, що ви цього не пробували, я просто встановлюю сцену.)
[речі, які ви знаєте] Поширений спосіб класифікації алгоритмів - це час виконання, і, цитуючи алгоритм великої-ой складності, можна отримати досить хорошу оцінку того, хто з них "кращий" - залежно від того, хто має "найменшу" функцію в О! Навіть у реальному світі O (N) "кращий", ніж O (N²), забороняючи дурні речі, такі як надмасивні константи тощо. [/ Речі, які ви знаєте]
Скажімо, існує деякий алгоритм, який працює в O (N). Дуже добре, так? Але скажімо, ви (геніальна людина, ви) придумали алгоритм, який працює в O ( N ⁄ loglogloglogN ). ТАК! Це швидше! Але ви будете почувати себе нерозумно, коли це пишете дисертацію. Отже, ви пишете це один раз, і ви можете сказати "У цій роботі я довів, що алгоритм X, раніше обчислюваний за часом O (N), насправді обчислюється в o (n)".
Таким чином, всі знають, що ваш алгоритм швидший --- на скільки незрозумілий, але вони знають його швидше. Теоретично. :)