Я вирішую питання щодо алгоритму, і мій аналіз полягає в тому, що він би працював на O (2 ^ sqrt (n)). Наскільки це велике? Чи дорівнює це О (2 ^ n)? Це все-таки неполіномічний час?
Я вирішую питання щодо алгоритму, і мій аналіз полягає в тому, що він би працював на O (2 ^ sqrt (n)). Наскільки це велике? Чи дорівнює це О (2 ^ n)? Це все-таки неполіномічний час?
Відповіді:
Це цікаве питання. На щастя, раз ви знаєте, як це вирішити, це не особливо важко.
Для функцій F : N → R + і г : N → R + , ми маємо ф ∈ O ( г ) тоді і тільки тоді , коли Нт вир п → ∞ ф ( п ) / г ( п ) ∈ R .
Функція f : N → R + має максимум поліноміального зростання тоді і тільки тоді, коли існує константа k ∈ N така, що f ∈ O ( n ↦ n k ). Давайте працювати це для довільного , але фіксованого до ∈ N .
lim sup n → ∞ 2 ( n 1/2 ) / n k =
lim n → ∞ 2 ( n 1/2 ) / n k =
lim n → ∞ e log (2) n 1/2 / e log ( n ) k =
lim n → ∞ e log (2) n 1/2 - log ( n ) k = ∞ ∉ R
Перша рівність справедлива тому, що обидва, іменник, і знаменник, монотонно зростають стійкими функціями. У другій рівності використовується тотожність x y = e log ( x ) y . Межа не є кінцевою, тому що показник у кінцевому виразі не обмежений вище. Не надаючи формального доказу, можна припустити, що відомо, що n 1/2 домінує над log ( n ) асимптотично. Тому функція, про яку йдеться, перевершує зростання поліномів.
Однак його ріст суворо менший, ніж експонентний, де експоненція визначається (для мене для цієї мети) як O ( n ↦ 2 c n ) для c > 0. Показати це ще більше прямо.
lim sup n → ∞ 2 c n / 2 ( n 1/2 ) = lim n → ∞ 2 c n - n 1/2 = ∞ ∉ R
для будь-якого фіксованого c > 0. Отже, складність функції десь справді знаходиться між поліном і експоненціалом.
Наскільки це велике? Що ж, O (2 ^ sqrt (n)) - саме те, наскільки він великий :-(
Щоб зрозуміти, що це означає, уявіть, що ваш алгоритм буде не просто O (2 ^ sqrt (n)), а тим, що він фактично займає саме 2 ^ sqrt (n) наносекунди на вашому комп’ютері:
n = 100: 2 ^ 10 = 1024 наносекунд. Немає часу взагалі. n = 1000: 2 ^ 31.xxx = 2 мільярди наносекунд. Дві секунди, це помітно. n = 10000: 2 ^ 100 ≈ 10 ^ 30 наносекунд = 10 ^ 21 секунди = 30 трильйонів років.
Це набагато краще, ніж 2 ^ n наносекунд, де n = 100 займе 30 трильйонів років, але все ж розмір проблем, які ви можете вирішити, досить обмежений. Якщо ви вважаєте проблему "вирішуваною", якщо ваш комп'ютер може її вирішити за один тиждень, це приблизно 6 x 10 ^ 14 наносекунд, це приблизно n = 2400. З іншого боку, до n = 400 можна вирішити в мілісекундах.
(На практиці для n = 10000 і O (2 ^ sqrt (n)), і O (2 ^ n) займають рівно однаковий час: Занадто довго чекати на нього.)
Він перевершує будь-який многочлен. Візьміть інший алгоритм, який займає n ^ 1000 секунд. Що практично нерозв’язно для n = 2. Цей алгоритм займає більше часу, поки n не стане приблизно 885 мільйонів. Але справді, кого це хвилює? У цей момент кількість років, які беруть обидва алгоритми, - це 9000-значний номер.