Сначала давайте разберемся, что такое большой О, большая Тета и большая Омега. Они все наборы функций.
Большой О дает верхнюю асимптотику , в то время как большая Омега дает нижнюю границу. Большая Тета дает оба.
Все , что есть Ө(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) не связаны с анализом алгоритмов на основе лучшего, наихудшего и среднего случаев. Каждый из них может быть применен к каждому анализу.
Мы обычно используем его для анализа сложности алгоритмов (как пример сортировки слиянием выше). Когда мы говорим «Алгоритм А есть O(f(n))
», мы на самом деле имеем в виду «сложность алгоритмов при анализе наихудшего 1 случая O(f(n))
» - это означает - он масштабирует «похожую» (или формально, не хуже) функциюf(n)
.
Почему мы заботимся об асимптотической границе алгоритма?
Ну, есть много причин для этого, но я считаю, что наиболее важными из них являются:
- Определить точную функцию сложности гораздо сложнее , поэтому мы «идем на компромисс» с нотациями большого-большого-большого-тета, которые теоретически достаточно информативны.
- Точное количество операций также зависит от платформы . Например, если у нас есть вектор (список) из 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 Обычно, правда, не всегда. когда класс анализа (худший, средний и лучший) отсутствует, мы действительно имеем в виду худший случай.