Що таке О (…) і як я його обчислюю?


31

Довідка! У мене виникає питання, де мені потрібно проаналізувати Big-O алгоритму чи якогось коду.

  • Я не впевнений, що таке Big-O або як це стосується Big-Theta або інших засобів аналізу складності алгоритму.

  • Я не впевнений, чи відноситься Big-O до часу запуску коду, або до потрібного обсягу пам'яті (компроміси простору / часу).

  • У мене є домашнє завдання з інформатики, де мені потрібно взяти певні петлі, можливо, рекурсивний алгоритм, і придумати для нього Big-O.

  • Я працюю над програмою, де у мене є вибір між двома структурами даних або алгоритмами з відомим Big-O, і я не впевнений, яку вибрати.

Як я розумію, як обчислити та застосувати Big-O до своєї програми, домашнього завдання чи загальних знань з інформатики?

Примітка. Це питання є канонічною цілью для інших , що визначаються громадою . Навмисно широка можливість мати велику кількість корисної інформації для багатьох питань Big-O. Будь ласка, не використовуйте той факт, що він є таким широким, як ознаку того, що подібні питання є прийнятними.


1
Лише зауважте, це питання обговорюється тут на мета .
Ендерленд

2
Чудовим ресурсом для початку став курс ханської академії (Томас Кормен з CLRS - один з письменників). Це був чудовий ресурс і для мене, як для CS. khanacademy.org/computing/computer-science/algorithms
Sudip Bhandari

3
Для людей, які відзначають це питання: будь ласка, прочитайте підтекст у нижній частині питання та перейдіть за цим посиланням, перш ніж позначити або голосувати, щоб закрити.

Відповіді:


22

O (...) відноситься до позначень Big-O, що є простим способом опису, скільки операцій алгоритму потрібно зробити, щоб зробити щось. Це відомо як складність у часі .

У нотації Big-O вартість алгоритму представлена ​​найдорожчою його роботою у великій кількості. Якби алгоритм робив кроки, він буде представлений O (n 3 ). Алгоритм, який підраховував кожен елемент у списку, буде працювати в O (n) час, який називається лінійним часом.n3 + n2 + n

Список імен та класичні приклади у Вікіпедії: Порядки загальних функцій

Схожі матеріали:


6
Примітка: великий O не по суті не вимірює час або простір чи якусь конкретну річ. Це просто верхній межі асимптотичного зростання функції (до постійної). Ця функція може бути часом, простором і т. Д. Алгоритму як функції його вхідної довжини, і найчастіше в контексті CS - це час, але це не обов'язково.
Відновіть Моніку

23

Що таке асимптотичні функції? Що таке асимптота?

Враховуючи функцію f (n), яка описує кількість ресурсів (час процесора, оперативна пам'ять, дисковий простір тощо), що споживається алгоритмом при застосуванні до вводу розміром n , ми визначаємо до трьох асимптотичних позначень для опису його продуктивності для великий н .

Асимптота (або асимптотична функція) - це просто якась інша функція (або відношення) g (n), до якої f (n) стає все ближче, коли n росте більше і більше, але ніколи не досягає цього. Перевага розмови про асимптотичні функції полягає в тому, що вони, як правило, набагато простіше говорити, навіть якщо вираз для f (n) надзвичайно складний. Асимптотичні функції використовуються як частина обмежувальних позначень, що обмежують f (n) вище чи нижче.

(Примітка: у сенсі, застосованому тут, асимптотичні функції близькі лише до вихідної функції після виправлення деякого постійного ненульового коефіцієнта, оскільки всі три нотації великого O / Θ / Ω не враховують цей постійний чинник від їх врахування.)

Що таке три асимптотичні обмежувальні позначення та чим вони відрізняються?

Усі три позначення використовуються так:

f (n) = O (g (n))

де f (n) - функція, що цікавить, а g (n) - якась інша асимптотична функція, з якою ви намагаєтесь наблизити f (n) . Це не слід сприймати як рівність у жорсткому розумінні, а формальне твердження між тим, як швидко f (n) зростає відносно n порівняно з g (n) , оскільки n стає великим. Пуристи часто використовують альтернативне позначення f (n) ∈ O (g (n)), щоб підкреслити, що символ O (g (n)) - це справді ціле сімейство функцій, які мають загальний темп зростання.

Позначення Big-ϴ (Theta) визначають рівність зростання f (n) до постійного коефіцієнта (докладніше про це пізніше). Він поводиться аналогічно =оператору за темпами зростання.

Позначення Big-O описує верхнє обмеження на ріст f (n) . Він поводиться аналогічно оператору за темпами зростання.

Позначення Big-Ω (Omega) описують нижчу границю на зростанні f (n) . Він поводиться аналогічно оператору за темпами зростання.

Існує багато інших асимптотичних позначень , але вони зустрічаються майже не так часто в літературі з інформатики.

Нотації Big-O та його заклики часто є способом порівняння складності часу .

Яка складність у часі?

Часова складність є фантазійним терміном за кількість часу T (n), яке потрібно алгоритму для виконання як функції його вхідного розміру n . Це можна виміряти у кількості реального часу (наприклад, секунд), кількості інструкцій процесора тощо. Зазвичай передбачається, що алгоритм буде працювати на вашому щоденному комп'ютері архітектури фон Неймана . Але звичайно, ви можете використовувати складний час, щоб поговорити про більш екзотичні обчислювальні системи, де все може бути інакше!

Також звичайно говорити про складність простору, використовуючи позначення Big-O. Космічна складність - це обсяг пам'яті (сховища), необхідний для завершення алгоритму, яким може бути оперативна пам'ять, диск тощо.

Можливо, один алгоритм повільніше, але використовує менше пам'яті, а інший - швидший, але використовує більше пам'яті. Кожен може бути більш доцільним при різних обставинах, якщо ресурси обмежені по-різному. Наприклад, вбудований процесор може мати обмежену пам'ять і надавати перевагу повільнішому алгоритму, тоді як сервер у центрі обробки даних може мати великий об'єм пам'яті та сприяти більш швидкому алгоритму.

Обчислення Big-ϴ

Обчислення алгоритму Big-ϴ - це тема, яка може заповнити невеликий підручник або приблизно півсеместру бакалаврського класу: цей розділ буде висвітлювати основи.

Дана функція f (n) у псевдокоді:

int f(n) {
  int x = 0;
  for (int i = 1 to n) {
    for (int j = 1 to n) {
      ++x;
    }
  }
  return x;
}

Яка складність у часі?

Зовнішня петля проходить n разів. Кожен раз, коли працює зовнішня петля, внутрішня петля працює n разів. Це ставить час роботи на T (n) = n 2 .

Розглянемо другу функцію:

int g(n) {
  int x = 0;
  for (int k = 1 to 2) {
    for (int i = 1 to n) {
      for (int j = 1 to n) {
        ++x;
      }
    }
  }
  return x;
}

Зовнішня петля проходить двічі. Середня петля проходить n разів. Кожен раз, коли проходить середня петля, внутрішня петля працює n разів. Це ставить час роботи на T (n) = 2n 2 .

Тепер питання полягає в тому, який асимптотичний час роботи обох функцій?

Щоб обчислити це, ми виконуємо два етапи:

  • Видаліть константи. Коли алгоритми збільшуються в часі за рахунок вхідних даних, інші умови домінують у процесі виконання, роблячи їх невагомими.
  • Видаліть усі, крім найбільшого терміну. Коли n переходить до нескінченності, n 2 швидко випереджає n .

Тут головне - зосередити увагу на домінуючих термінах та спростити їх .

T (n) = n 2 ∈ ϴ (n 2 )
T (n) = 2n 2 ∈ ϴ (n 2 )

Якщо у нас є інший алгоритм з декількома термінами, ми б спростили його, використовуючи ті самі правила:

T (n) = 2n 2 + 4n + 7 ∈ ϴ (n 2 )

Ключовим з усіх цих алгоритмів є те, що ми орієнтуємося на найбільші терміни та видаляємо константи . Ми дивимось не на фактичний час роботи, а на відносну складність .

Обчислення Big-Ω та Big-O

По-перше, слід попередити, що в неофіційній літературі "Big-O" часто трактується як синонім Big-Θ, можливо, тому, що грецькі літери є складними для введення. Тож якщо хтось із синіх тонів запитує у вас алгоритму Big-O, він, ймовірно, хоче його Big-Θ.

Тепер, якщо ви дійсно хочете обчислити Big-Ω та Big-O у формальних сенсах, визначених раніше, у вас є основна проблема: існує безліч безлічі описів Big-Ω та Big-O для будь-якої заданої функції! Це як запитати, якими є числа, менші або рівні 42. Є багато можливостей.

Для алгоритму з T (n) ∈ ϴ (n 2 ) будь-яке з перелічених нижче є формально допустимими твердженнями:

  • T (n) ∈ O (n 2 )
  • T (n) ∈ O (n 3 )
  • T (n) ∈ O (n 5 )
  • T (n) ∈ O (n 12345 × e n )
  • T (n) ∈ Ω (n 2 )
  • T (n) ∈ Ω (n)
  • T (n) ∈ Ω (log (n))
  • T (n) ∈ Ω (log (log (n)))
  • T (n) ∈ Ω (1)

Але неправильно твердити T (n) ∈ O (n) або T (n) ∈ Ω (n 3 ) .

Що таке відносна складність? Які класи алгоритмів існують?

Якщо ми порівняємо два різних алгоритми, то їх складність із входом до нескінченності зазвичай зростатиме. Якщо ми подивимось на різні типи алгоритмів, вони можуть залишитися відносно однаковими (скажімо, відрізнятися постійним фактором) або можуть сильно розходитися. Це причина для аналізу Big-O: щоб визначити, чи буде алгоритм працювати з великими входами.

Класи алгоритмів розбиваються так:

  • Θ (1) - константа. Наприклад, вибір першого номера у списку завжди займе стільки ж часу.

  • Θ (n) - лінійний. Наприклад, повторення списку завжди займе час, пропорційний розміру списку, n .

  • Θ (log (n)) - логарифмічний (основа зазвичай не має значення). Алгоритми, що розділяють вхідний простір на кожному кроці, наприклад, двійковий пошук, є прикладами.

  • Θ (n × log (n)) - лінійні часові логарифмічні («лінійні). Ці алгоритми, як правило, ділять і підкоряють ( log (n) ), зберігаючи ( n ) весь вхід. Багато популярних алгоритмів сортування (сортування злиття, Timsort) потрапляють до цієї категорії.

  • Θ (n m ) - многочлен ( n піднятий до будь-якої постійної m ). Це дуже поширений клас складності, часто зустрічається в вкладених петлях.

  • Θ (m n ) - експоненціальна (будь-яка константа m, піднята до n ). Багато рекурсивних та графічних алгоритмів підпадають під цю категорію.

  • Θ (п!) - факторіал. Певні графічні та комбінаторні алгоритми є факторною складністю.

Чи має це щось спільне з найкращим / середнім / гіршим випадком?

Ні. Big-O та його сімейство позначень говорять про конкретну математичну функцію . Вони є математичними інструментами, які допомагають охарактеризувати ефективність алгоритмів, але поняття найкращого / середнього / гіршого випадку не пов'язане з теорією темпів зростання, описаною тут.

Щоб говорити про алгоритм Big-O, потрібно взяти на себе конкретну математичну модель алгоритму з точно одним параметром n, який повинен описувати "розмір" вхідного сигналу в будь-якому сенсі, який є корисним. Але в реальному світі матеріали мають набагато більшу структуру, ніж просто їх тривалість. Якби це був алгоритм сортування, я міг би харчуватися в рядках "abcdef", "fedcba"або "dbafce". Всі вони мають довжину 6, але одна з них вже сортована, одна перевернута, а остання - лише випадкова перемичка. Деякі алгоритми сортування (наприклад, Timsort) працюють краще, якщо вхід вже відсортований. Але як можна включити цю неоднорідність у математичну модель?

Типовий підхід полягає у тому, щоб просто припустити, що вхід походить від якогось випадкового, ймовірнісного розподілу. Потім ви оцінюєте складність алгоритму за всіма входами з довжиною n. Це дає модель середнього випадку складності алгоритму. Звідси ви можете використовувати нотації Big-O / Θ / Ω як зазвичай для опису середньої поведінки у випадку.

Але якщо ви стурбовані атаками відмови у наданні послуг, можливо, вам доведеться бути песимістичнішими. У цьому випадку безпечніше припустити, що єдиними входами є ті, які викликають найбільше горя за вашим алгоритмом. Це дає вам найгірший варіант складності алгоритму. Згодом ви можете поговорити про Big-O / Θ / Ω тощо з найгіршої моделі.

Аналогічно, ви також можете зосередити свою зацікавленість виключно на входах, з якими ваш алгоритм має найменшу кількість проблем, щоб знайти найкращу модель, а потім подивитись на Big-O / Θ / Ω тощо.


Це хороша відповідь, але Big-O та Big-Ω мало спільного з найгіршими та найкращими випадками. Вони є верхньою та нижньою рамками, але вони можуть застосовуватись до будь-якого випадку, наприклад, сортування вставки має, в кращому випадку, часову складність ϴ(n)(як Big-O, так і Big-Ω), маючи в гіршому випадку, часова складність ϴ(n²)(як Big-O, так і Big-Ω).
Павло

Також будь-який алгоритм, за винятком порожнього алгоритму, є Ω(1)в кращому, гіршому та середньому випадках, але це тому, що це нижня межа і не має нічого спільного з реальним найкращим випадком алгоритму.
Павло

Великі - все, що не має нічого спільного з найкращим чи гіршим випадком - це поширена помилка. Вони є лише способами констатувати, чи детерміновані функції ростуть швидше, повільніше або з такою ж швидкістю порівняно з іншими. Поняття найкращого / гіршого випадку існує лише після того, як ви починаєте говорити про часову / просторову складність реальних алгоритмів, і в цьому випадку виникають недетерміновані фактори, і вам потрібно враховувати розподіл ймовірності ваших вкладів. Вже тоді найкращий / найгірший випадок лежить на осі, ортогональній великій О-Омега.
Rufflewind

@Rufflewind, якщо ви думаєте, що можете описати це краще, тоді продовжуйте. Ви розумієте, що це відповідь у вікі спільноти, правда?

"По-перше, слід попередити, що в неофіційній літературі" Big-O "часто трактується як синонім Big-Θ" -> Не тільки в неформальній літературі. Мій перший семестр з питань складності, ще в коледжі, навчив нас визначенню Big-O, як ніби це Big-Θ. (Наш підручник використав це визначення!) Це сплутало пекло з мене, коли я перейшов до складності II, і я виявив, що вони не однакові.
Т. Сар - Відновлення Моніки
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.