Чи існують алгоритми O (1 / n)?


335

Чи існують алгоритми O (1 / n)?

Або що-небудь інше, що менше O (1)?


Більшість питань передбачає, що ви маєте на увазі "Чи існують алгоритми зі складністю часу O (1 / n)?" Чи слід вважати, що це так? Big-O (і Big-Theta тощо) описують функції, а не алгоритми. (Я не знаю еквівалентності між функціями та алгоритмами.)
jyoungdev

4
Це загальнозрозуміле визначення алгоритму "O (X)" в інформатиці: алгоритм, складність у часі якого O (X) (для деякого виразу X).
Девід Z

2
Я чув таке обмеження у випадку ефективного алгоритму черги пріоритетів вводу / виводу за допомогою буферного дерева. У буферному дереві кожна операція приймає введення / вивід O (1 / B); де B - розмір блоку. І сумарний введення / вивід для n операцій становить O (n / B.log (база M / B) (n / B)), де частина журналу - висота дерева буфера.
CODError

Існує безліч алгоритмів з ймовірністю помилок O (1 / n). Наприклад фільтр цвітіння з відрами O (n log n).
Томас Ейл

Не можна швидше відкладати яйце, додаючи курчат.
Уїк

Відповіді:


310

Це питання не настільки дурне, як може здатися. Принаймні теоретично щось таке, як O (1 / n ), є цілком розумним, коли ми беремо математичне визначення нотації Big O :

Тепер ви можете легко замінити g ( x ) на 1 / x ... очевидно, що вищевказане визначення все ще має місце для деякого f .

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

def get_faster(list):
    how_long = (1 / len(list)) * 100000
    sleep(how_long)

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

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


22
"Закріплене обладнанням" також стосується машини Тьюрінга. У випадку O (1 / n) завжди буде розмір вводу, для якого алгоритм не повинен виконувати жодної операції. І тому я думаю, що O (1 / n) часової складності досягти справді неможливо.
Роланд Евальд,

28
Мехрдад, ти не розумієш. Позначення O - це щось про обмеження (технічно обмежене суп) як n -> ∞. Час запуску алгоритму / програми - це кількість кроків на деякій машині, і тому дискретно - існує ненульова нижня межа часу, який може пройти алгоритм ("один крок"). Це є можливим , що ДО деяких кінцевої N програми приймає ряд кроків відбувають з п, але єдиний спосіб алгоритм може бути O (1 / п), або на самому справі про (1), якщо це потрібен час 0 для всіх досить великий n - що неможливо.
ShreevatsaR

28
Ми не погоджуючись , що O (1 / п) функцій (в математичному сенсі) існує. Очевидно, що вони так і роблять. Але обчислення за своєю суттю дискретні. Те, що має нижню межу, наприклад, час роботи програми - або архітектура фон Неймана, або суто абстрактна машина Тьюрінга - не може бути O (1 / n). Що рівно, те, що є O (1 / n), не може мати нижню межу. (Ваша функція "сну" повинна бути викликана, або змінна "список" повинна бути вивчена - або вхідна стрічка повинна бути вивчена на машині Тьюрінга. Таким чином, витрачений час буде змінюватися з n як деякий ε + 1 / n, що не є O (1 / n))
ShreevatsaR

16
Якщо T (0) = ∞, це не зупиняється. Немає такого поняття, як "T (0) = ∞, але все одно зупиняється". Далі, навіть якщо ви працюєте в R∪ {∞} і визначаєте T (0) = ∞, а T (n + 1) = T (n) / 2, то T (n) = ∞ для всіх n. Повторю: якщо функція дискретного значення O (1 / n), то для всіх досить великих n вона дорівнює 0. [Доказ: T (n) = O (1 / n) означає, що існує константа c така, що для n> N0, T (n) <c (1 / n), що означає, що для будь-якого n> max (N0,1 / c), T (n) <1, що означає T (n) = 0.] ні одна машина, реальний або абстрактний, не може приймати 0 раз: він повинен дивитися на вході. Ну, окрім машини, яка ніколи нічого не робить, і для якої T (n) = 0 для всіх n.
ShreevatsaR

43
Ви повинні сподобатися будь-якій відповіді, яка починається "Це питання не таке дурне, як може здатися".
Телемах

138

Так.

Існує точно один алгоритм з режимом виконання O (1 / n), "порожній" алгоритм.

Якщо алгоритм є O (1 / n), це означає, що він виконує асимптотично за менші кроки, ніж алгоритм, що складається з однієї інструкції. Якщо він виконується менш, ніж один крок для всіх n> n0, він не повинен точно складатися з інструкцій для цих n. Оскільки перевірка "якщо n> n0" коштує щонайменше 1 інструкція, вона не повинна містити інструкцій для всіх n.

Підведення підсумків: Єдиним алгоритмом, який є O (1 / n), є порожній алгоритм, що не складається з інструкцій.


2
Тож якби хтось запитав, яка часова складність порожнього алгоритму, ти відповів би з O (1 / n) ??? Якось у цьому сумніваюся.
phkahler

24
Це єдина правильна відповідь у цій темі, і вона, незважаючи на мою підсумкову заявку, має нульовий рівень голосів. Такий StackOverflow, де відповіді за "правильний вигляд" голосуються вище, ніж фактично правильні.
ShreevatsaR

5
Ні, його оцінка 0, тому що вона неправильна. Виражати величину великого-Oh стосовно N, коли вона не залежить від N, невірно. По-друге, запуск будь-якої програми, навіть тієї, яка щойно існує, займає принаймні постійну кількість часу, O (1). Навіть якщо це не так, це було б O (0), а не O (1 / n).
kenj0418

32
Будь-яка функція, яка є O (0), також є O (1 / n), а також O (n), також O (n ^ 2), також O (2 ^ n). Зітхайте, чи ніхто не розуміє простих визначень? O () - верхня межа.
ShreevatsaR

16
@ kenj0418 Вам вдалося помилитися в кожному реченні. "Висловлення великого значення О-по відношенню до N, коли воно не залежить від N, невірно." Постійна функція - це абсолютно ідеальна функція. "По-друге, запуск будь-якої програми, навіть тієї, яка щойно існує, займає принаймні постійну кількість часу, O (1)." Визначення складності нічого не говорить про те, що насправді працює будь-яка програма. "це було б O (0), а не O (1 / n)". Дивіться коментар @ ShreevatsaR
Олексій Романов

25

shartooth є правильним, O (1) - найкраща можлива ефективність. Однак це не означає швидке рішення, а лише фіксований час.

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

У кого-небудь двоє людей в наборі один і той же день народження? Коли n перевищує 365, поверніть true. Хоча для менш ніж 365, це O (n ln n). Можливо, це не чудова відповідь, оскільки проблема не стає повільніше, а просто стає O (1) для n> 365.


7
366. Не забувайте про високосні роки!
Нік Джонсон

1
Ви праві. Як і комп’ютери, я час від часу зазнаю помилок округлення :-)
Адріан,

10
+1. Існує ряд проблем, повних NP, які зазнають "фазового переходу" в міру збільшення n, тобто вони швидко стають набагато простішими або набагато складнішими, коли ви перевищуєте певне порогове значення n. Одним із прикладів є проблема розділення чисел: задавши набір n невід’ємних цілих чисел, розділіть їх на дві частини так, щоб сума кожної частини була рівною. Це стає значно простіше при певному пороговому значенні n.
j_random_hacker

23

Це неможливо. Визначення Big-O є не більше ніж нерівність:

A(n) = O(B(n))
<=>
exists constants C and n0, C > 0, n0 > 0 such that
for all n > n0, A(n) <= C * B(n)

Таким чином, B (n) насправді є максимальним значенням, тому, якщо воно зменшується в міру збільшення n, оцінка не зміниться.


42
Я підозрюю, що ця відповідь є "правильною", але, на жаль, мені не вистачає інтелекту, щоб її зрозуміти.
простір

12
AFAIK ця умова має бути неправдивою для всіх n, але для всіх n> n_0 (тобто лише тоді, коли розмір вводу досягає певного порогу).
Роланд Евальд,

30
Я не бачу, як визначення (навіть виправлене) суперечить питанню про ОП. Визначення справедливо для абсолютно довільних функцій! 1 / n - цілком розумна функція для B, і насправді ваше рівняння не суперечить цьому (просто зробіть математику). Тому ні, незважаючи на багато консенсусу, ця відповідь насправді неправильна . Вибачте.
Конрад Рудольф

10
Неправильно! Мені не подобається забороняти участь, але ви заявляєте, що це неможливо, коли немає чіткого консенсусу. На практиці ви маєте рацію, якщо ви будуєте функцію з 1 / n час виконання (просто), вона в кінцевому підсумку досягне деякого мінімального часу, що фактично робить її алгоритмом O (1) при реалізації. Але ніщо не заважає алгоритму бути O (1 / n) на папері.
jheriko

3
@Jason: Так, тепер, коли ти це кажеш ... :) @jheriko: Часова складність O (1 / n) не працює на папері IMHO. Ми характеризуємо функцію росту f (розмір вводу) = #ops для машини Тьюрінга. Якщо вона зупиняється на введенні довжини n = 1 після x кроків, то я виберу вхідний розмір n >> x, тобто достатньо великий, що, якщо алгоритм дійсно знаходиться в O (1 / n), жодна операція не повинна бути зроблено. Як машина Тьюрінга навіть це помітить (не можна читати один раз зі стрічки)?
Роланд Евальд,

16

З мого попереднього вивчення великої нотації O, навіть якщо вам потрібен 1 крок (наприклад, перевірка змінної, виконання завдання), тобто O (1).

Зауважте, що O (1) - це те саме, що O (6), оскільки "константа" не має значення. Тому ми кажемо, що O (n) - це те саме, що O (3n).

Отже, якщо вам потрібен навіть 1 крок, це O (1) ... а оскільки вашій програмі потрібно щонайменше 1 крок, мінімальним алгоритмом може бути O (1). Якщо ми цього не зробимо, я думаю, це О (0)? Якщо ми взагалі щось робимо, то це O (1), і це мінімум, який він може досягти.

(Якщо ми вирішимо не робити цього, то це може стати питанням дзен або дао ... у царині програмування O (1) все ще є мінімумом).

А як щодо цього:

програміст : бос, я знайшов спосіб це зробити в O (1) час!
бос : не потрібно цього робити, ми сьогодні вранці збанкрутуємо.
програміст : о, тоді він стає O (0).


Ваш жарт нагадав мені щось із Дао програмування: canonical.org/~kragen/tao-of-programming.html#book8 (8.3)
kenj0418

Алгоритм, що складається з нульових кроків, є O (0). Це дуже ледачий алгоритм.
nalply

8

Ні, це неможливо:

Оскільки n має тенденцію до нескінченності в 1 / n, ми в кінцевому підсумку досягаємо 1 / (inf), що ефективно дорівнює 0.

Таким чином, великим класом задачі буде O (0) з масивним n, але ближчим до постійного часу з низьким n. Це нерозумно, оскільки єдине, що можна зробити швидше, ніж постійний час, це:

void nothing() {};

І навіть це сперечається!

Як тільки ви виконуєте команду, ви принаймні O (1), так що ні, ми не можемо мати клас великого-O (1 / n)!


7

А як щодо взагалі не запустити функцію (NOOP)? або за допомогою фіксованого значення. Це враховує?


16
Це все ще O (1) час виконання.
Конрад Рудольф

2
Так, це все-таки O (1). Я не бачу, як хтось може це зрозуміти, але в іншій відповіді стверджую, що можливо щось менше, ніж NO-OP.
ShreevatsaR

4
ShreevatsaR: Суперечності абсолютно немає. Вам здається, що ви не можете зрозуміти, що велика нотація O не має нічого спільного з часом, проведеним у функції, швидше, вона описує, як цей час змінюється при зміні вхідних даних (вище певного значення). Дивіться іншу тему коментарів для отримання додаткової інформації.
Конрад Рудольф

Я розумію це чудово, дякую. Справа - як я кілька разів робила в іншій нитці - полягає в тому, що якщо час зменшується з введенням, зі швидкістю O (1 / n), то він з часом повинен зменшитися нижче часу, який займає NOOP. Це показує, що жоден алгоритм не може бути O (1 / n) асимптотичним, хоча, безумовно, його час виконання може скоротитися до межі.
ShreevatsaR

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

7

Я часто використовую O (1 / n), щоб описати ймовірності, які зменшуються, коли входи збільшуються - наприклад, ймовірність того, що справедлива монета з’являється хвостиками на перекидах log2 (n), є O (1 / n).


6
Це не те, що великий О є. Ви не можете просто переглянути їх для того, щоб відповісти на питання.
Зіфре

11
Це не переосмислення, це саме визначення великого О.
ShreevatsaR

10
Я теоретик з питань торгівлі. Йдеться про асимптотичний порядок функції.
Дейв

4
Big O - властивість довільної реальної функції. Часова складність - лише одне з можливих застосувань. Інша складність простору (кількість робочої пам'яті, яку використовує алгоритм) - інша. Що питання про алгоритми O (1 / n) означає, що це один із них (якщо тільки інший не стосується алгоритмів, про які я не знаю). Інші додатки включають порядки зростання населення, наприклад, у житті Конвейя. Дивіться також en.wikipedia.org/wiki/Big_O_notation
Стюарт

5
@Dave: Питання було не в тому, чи існують функції O (1 / n), які, очевидно, існують. Швидше, це було чи існують алгоритми O (1 / n), які (за винятком нульової функції) не можуть існувати
Casebash

6

O (1) просто означає "постійний час".

Додаючи ранній вихід до циклу [1], ви (у великій нотації O) перетворюєте алгоритм O (1) на O (n), але робите його швидшим.

Трюк, як правило, алгоритм постійного часу найкращий, а лінійний - краще, ніж експоненціальний, але для малих кількостей n алгоритм експоненції може бути фактично швидшим.

1: Припустимо статичну довжину списку для цього прикладу


6

Для тих, хто читає це питання і хоче зрозуміти, про що йдеться, це може допомогти:

|    |constant |logarithmic |linear|  N-log-N |quadratic|  cubic  |  exponential  |
|  n |  O(1)   | O(log n)   | O(n) |O(n log n)|  O(n^2) |  O(n^3) |     O(2^n)    |
|  1 |       1 |          1 |     1|         1|        1|       1 |             2 |
|  2 |       1 |          1 |     2|         2|        4|       8 |             4 |
|  4 |       1 |          2 |     4|         8|       16|      64 |            16 |
|  8 |       1 |          3 |     8|        24|       64|     512 |           256 |
| 16 |       1 |          4 |    16|        64|      256|   4,096 |         65536 |
| 32 |       1 |          5 |    32|       160|    1,024|  32,768 | 4,294,967,296 |
| 64 |       1 |          6 |    64|       384|    4,069| 262,144 |   1.8 x 10^19 |

5

Я вважаю, що квантові алгоритми можуть робити кілька обчислень "відразу" за допомогою суперпозиції ...

Сумніваюсь, це корисна відповідь.


Це все-таки буде постійним часом, тобто O (1), тобто для запуску даних розміру n потрібно стільки ж часу, скільки і для даних розміру 1.
простір

2
Але що робити, якщо проблемою був блідий ель? (ах. ха-ха.)
Jeff Meatball Yang,

7
Це було б супер позицією.
Даніель Ервікер

1
Квантові алгоритми можуть робити кілька обчислень, але ви можете отримати результат лише одного обчислення, і ви не можете вибрати, який результат отримати. На щастя, ви також можете робити операції над квантовим реєстром в цілому (наприклад, QFT), тож вам набагато більше захочеться знайти щось :)
Gracenotes

2
це, мабуть, не корисно, але це має перевагу в тому, що це правда, що ставить його вище за деякі більш голосовані відповіді B-)
Brian Postow

4

багато людей мали правильну відповідь (Ні) Ось ще один спосіб довести це: Щоб мати функцію, вам потрібно викликати функцію, і ви повинні повернути відповідь. Це займає певну постійну кількість часу. НАДІЛЬКО, якщо на іншу обробку знадобиться менше часу для більшого введення, друк відповіді (що ми можемо вважати одним бітом) займає щонайменше постійний час.


2

Якщо рішення існує, його можна підготувати та отримати доступ до нього в постійний час = негайно. Наприклад, використовуючи структуру даних LIFO, якщо ви знаєте, що запит сортування призначений у зворотному порядку. Потім дані вже сортуються, враховуючи, що обрана відповідна модель (LIFO).


2

Які проблеми стають легшими у міру зростання населення? Одна відповідь - така річ, як bittorrent, де швидкість завантаження - це зворотна функція кількості вузлів. На відміну від автомобіля, який сповільнює, чим більше ви завантажуєте його, мережа для обміну файлами, як битторент, прискорює більше підключених вузлів.


Так, але кількість вузлів bittorrent більше схожа на кількість процесорів у паралельному комп'ютері. "N" у цьому випадку буде розміром файлу, який намагається завантажити. Так само, як ви могли знайти елемент у несортованому масиві довжиною N за постійний час, якщо у вас було N комп’ютерів, ви можете завантажувати файл розміру N за постійний час, якщо у вас було N комп'ютерів, які намагаються надіслати вам дані.
Кіббі

2

Ви не можете піти нижче O (1), проте O (k) там, де k менше, ніж N. Ми називали їх підлінійними алгоритмами часу . У деяких проблемах алгоритм підлінійного часу може дати лише приблизні рішення певної проблеми. Однак іноді приблизні рішення є просто чудовими, ймовірно, тому, що набір даних занадто великий, або що це занадто обчислювально дорого для обчислення всіх.


1
Не впевнений, що розумію. Журнал (N) менший за N. Чи означає це, що Log (N) є підлінійним алгоритмом? І існує багато алгоритмів Log (N). Один із таких прикладів - знаходження значення у двійковому дереві. Однак вони все ще відрізняються, ніж 1 / N, оскільки Log (N) завжди збільшується, тоді як 1 / n - це функція, що спадає.
Кіббі

Дивлячись на визначення, підлінійний алгоритм часу - це будь-який алгоритм, час якого зростає повільніше, ніж розмір N. Отже, що включає логарифмічний алгоритм часу, який є Log (N).
Hao Wooi Lim

2
Так, алгоритми підлінійного часу можуть дати точні відповіді, наприклад, двійковий пошук в упорядкованому масиві на машині оперативної пам'яті.
А. Рекс

@A. Рекс: Хао Вуй Лім сказав "У деяких проблемах".
LarsH

1

Як що до цього:

void FindRandomInList(list l)
{
    while(1)
    {
        int rand = Random.next();
        if (l.contains(rand))
            return;
    }
}

зі збільшенням розміру списку очікувана тривалість виконання програми зменшується.


я думаю, ти не розумієш значення O (n)
Маркус Лаусберг,

Не зі списком, хоч із масивом чи хешем, де constainsO (1)
vava

ОК, випадкова функція може розглядатися як ледачий масив, тому ви в основному шукаєте кожен елемент у "лінивому випадковому списку" і перевіряєте, чи міститься він у вхідному списку. Я думаю, це гірше, ніж лінійне, не краще.
hasen

У нього є певний момент, якщо ви помітили, що int має обмежений набір значень. Отже, коли я містив би 2 <sup> 64 </sup> значень, це буде миттєвим на весь шлях. Що робить це гірше, ніж O (1) у будь-якому випадку :)
vava

1

O (1 / n) не менше O (1), це в основному означає, що чим більше у вас даних, тим швидше йде алгоритм. Скажімо, ви отримуєте масив і завжди заповнюєте його до 10 100 елементів, якщо в ньому менше, ніж нічого, і нічого не робити, якщо є більше. Це, звичайно, не O (1 / n), але щось на зразок O (-n) :) Занадто поганий O-великий позначення не дозволяє негативних значень.


1
"O (1 / n) не менше O (1)" - якщо функцією f є O (1 / n), це також O (1). І big-oh дуже схоже на відношення "менший ніж": воно рефлексивне, транзитивне, і якщо у нас є симетрія між f і g, то два еквівалентні, де big-theta - наше відношення еквівалентності. ISTR "реальні" впорядковані відносини, що вимагають, щоб <= b і b <= a означали a = b, хоча, і netcraft ^ W wikipedia це підтверджує. Тож у певному сенсі справедливо сказати, що дійсно O (1 / n) "менше, ніж" O (1).
Йонас Келькер

1

Як було зазначено, окрім можливого виключення нульової функції, функцій не може бути O(1/n), оскільки час, який потрібно, повинен наблизитися до 0.

Звичайно, є деякі алгоритми, такі, як визначений Конрадом, які, здається, мають бути меншими, ніж O(1)хоча б у якомусь сенсі.

def get_faster(list):
    how_long = 1/len(list)
    sleep(how_long)

Якщо ви хочете дослідити ці алгоритми, вам слід визначити власне асимптотичне вимірювання, або власне уявлення про час. Наприклад, у вищенаведеному алгоритмі я міг дозволити використання декількох "вільних" операцій у встановлену кількість разів. У наведеному вище алгоритмі, якщо я визначаю t ', виключаючи час на все, крім сну, то t' = 1 / n, що є O (1 / n). Напевно, є кращі приклади, оскільки асимптотична поведінка тривіальна. Насправді я впевнений, що хтось там може придумати відчуття, які дають нетривіальні результати.


1

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

Багато алгоритмів можуть бути O (h ^ p) або O (n ^ {- p}), залежно від того, йдеться про розмір кроку (h) або кількість поділів (n). Наприклад, у методі Ейлера ви шукаєте оцінку y (h), враховуючи, що ви знаєте y (0) і dy / dx (похідна від y). Ваша оцінка y (h) точніша, тим ближче h до 0. Отже, щоб знайти y (x) для деякого довільного x, потрібно взяти інтервал від 0 до x, розбити його до n частин і запустити метод Ейлера в кожній точці дістати від y (0) до y (x / n) до y (2x / n) тощо.

Тож метод Ейлера - це алгоритм O (h) або O (1 / n), де h, як правило, інтерпретується як розмір кроку, а n інтерпретується як кількість раз ділення інтервалу.

Ви також можете мати O (1 / год) у реальних програмах чисельного аналізу через помилки округлення з плаваючою комою . Чим менше ви робите свій інтервал, тим більше відбувається скасування впровадження певних алгоритмів, тим більше втрата значущих цифр, а отже, і більше помилок, які поширюються через алгоритм.

Для методу Ейлера, якщо ви використовуєте плаваючі точки, використовуйте досить невеликий крок і скасування, і ви додаєте невелике число до великого числа, залишаючи велике число незмінним. Для алгоритмів, які обчислюють похідну шляхом віднімання один від одного двох чисел з функції, оціненої у двох дуже близьких положеннях, наближаючи y '(x) до (y (x + h) - y (x) / h), в гладких функціях y (x + h) наближається до y (x), що призводить до великої відміни та оцінки похідної з меншою кількістю значущих цифр. Це, в свою чергу, пошириться на той алгоритм, для якого вам потрібна похідна (наприклад, проблема граничного значення).


0

Гаразд, я трохи подумав над цим, і, можливо, існує алгоритм, який би міг відповідати цій загальній формі:

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


4
Це різний вид n в O (n) тоді. За допомогою цього фокусу ви можете сказати, що кожен алгоритм має O (q), де q - це кількість людей, які живуть, наприклад, у Китаї.
vava

2
Бойер-Мур має подібний вид (O (n / m)), але це насправді не "краще, ніж O (1)", тому що n> = m. Я думаю, те саме стосується і вашого «невідомого ЦСП».
Нікі

Навіть у цьому випадку час виконання TSP не завершено, ви просто видаляєте вузли з графіка, і, отже, ефективно зменшуєте n.
Ед Джеймс

0

Я бачу алгоритм, який O (1 / n) належить до верхньої межі:

У вас є велика серія входів, які змінюються через щось, що не відповідає рутинному (можливо, вони відображають обладнання або це може бути навіть якесь інше ядро ​​в процесорі, що це робить.), І ви повинні вибрати випадковий, але дійсний.

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

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


0

У числовому аналізі алгоритми апроксимації повинні мати субстантную асимптотичну складність у допущенні наближення.

class Function
{
    public double[] ApproximateSolution(double tolerance)
    {
        // if this isn't sub-constant on the parameter, it's rather useless
    }
}

ти справді маєш на увазі субконстанцію чи підлінійну? Чому алгоритми наближення повинні бути субстантними? І що це навіть означає ??
LarsH

@LarsH, помилка алгоритмів наближення пропорційна розміру кроку (або його позитивній потужності), тому чим менший розмір вашого кроку, тим менша помилка. Але ще один поширений спосіб вивчення проблеми наближення - це помилка порівняно з тим, скільки разів ділиться інтервал. Кількість розділів інтервалу обернено пропорційна розміру кроку, тому помилка обернено пропорційна деякій позитивній потужності кількості розділів - у міру збільшення кількості розділів ваша помилка зменшується.
Ендрю Лей

@AndrewLei: Вау, відповідь майже через 7 років! Я зараз розумію відповідь Сема краще, ніж я тоді. Дякуємо за відгук.
LarsH

0

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

def 1_by_n(n, C = 10):   #n could be float. C could be any positive number
  if n <= 0.0:           #If input is actually 0, infinite loop.
    while True:
      sleep(1)           #or pass
    return               #This line is not needed and is unreachable
  delta = 0.0001
  itr = delta
  while delta < C/n:
    itr += delta

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

Можна стверджувати, що це буде обмежено точністю машини. таким чином, sinc eit має верхню межу - це O (1). Але ми можемо обійти це також, взявши введення n та C в рядку. І додавання та порівняння робиться на рядок. Ідея полягає в тому, що за допомогою цього ми можемо скоротити n довільно малих. Таким чином, верхня межа функції не обмежена, навіть якщо ми ігноруємо n = 0.

Я також вважаю, що ми не можемо просто сказати, що час виконання - O (1 / n). Але ми повинні сказати щось на зразок O (1 + 1 / n)


-1

Можливо, можливо побудувати алгоритм, який є O (1 / n). Одним із прикладів може бути цикл, який повторює деякий кратний f (n) -n разів, коли f (n) - деяка функція, значення якої гарантовано перевищує n, а межа f (n) -n, коли n наближається до нескінченності, нуль. Розрахунок f (n) також повинен бути постійним для всіх n. Я не знаю з іншого боку, як виглядатиме f (n) або яким би було застосування такого алгоритму, на мою думку, однак така функція могла б існувати, але отриманий алгоритм не мав би іншого призначення, як довести можливість алгоритму з O (1 / n).


Ваш цикл вимагає перевірки, яка займає хоча б постійний час, тому отриманий алгоритм має принаймні складність O (1).
Стефан Рейх

-1

Я не знаю про алгоритми, але складності менше O (1) з'являються у рандомізованих алгоритмах. Власне, o (1) (мало o) менше O (1). Така складність зазвичай з'являється в рандомізованих алгоритмах. Наприклад, як ви сказали, коли ймовірність якоїсь події є порядку 1 / n, вони позначають її о (1). Або коли вони хочуть сказати, що щось відбувається з великою часткою ймовірності (наприклад, 1 - 1 / n), вони позначають це з 1 - o (1).


-2

Якщо відповідь однакова незалежно від вхідних даних, то у вас є алгоритм O (0).

або іншими словами - відповідь відома до подачі вхідних даних - функція може бути оптимізована - так O (0)


Дійсно? Вам все одно потрібно буде повернути значення, так чи не все-таки це буде O (1)?
Йоахім Зауер

7
ні, O (0) означає, що для всіх входів потрібен нульовий час. O (1) - постійний час.
Піт Кіркхем,

-2

Позначення Big-O являє собою найгірший сценарій для алгоритму, який не є тим самим, що його типовий час виконання. Довести, що алгоритм O (1 / n) є алгоритмом O (1), просто. За визначенням,
O (1 / n) -> T (n) <= 1 / n, для всіх n> = C> 0
O (1 / n) -> T (n) <= 1 / C, оскільки 1 / n <= 1 / C для всіх n> = C
O (1 / n) -> O (1), оскільки нотація Big-O ігнорує константи (тобто значення C не має значення)


Ні: нотація Big O також використовується для розмови про середні випадки та очікувані часові (і навіть найкращі) сценарії. Решта випливає далі.
Конрад Рудольф

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

2
Роланд: Це неправильне уявлення; верхня межа - це не те саме, що в гіршому випадку, це два незалежні поняття. Розглянемо очікуваний (і середній) час виконання hashtable-containsалгоритму, який можна позначити як O (1) - і найгірший випадок може бути заданий дуже точно як Theta (n)! Омега та Тета можуть просто використовуватися для позначення інших меж, але сказати це знову : вони не мають нічого спільного із середнім чи кращим випадком.
Конрад Рудольф

Конрад: Правда. І все-таки Омега, Теата та О зазвичай використовуються для вираження меж, і якщо враховувати всі можливі введення, О являє верхню межу тощо.
Роланд Евальд,

1
Те, що O (1 / n) є підмножиною O (1), є тривіальним і випливає безпосередньо з визначення. Насправді, якщо функція g є O (h), то будь-яка функція f, яка є O (g), також є O (h).
Тобіас

-2

Ніщо не менше, ніж O (1) Позначення Big-O передбачає найбільший порядок складності алгоритму

Якщо алгоритм має час виконання n ^ 3 + n ^ 2 + n + 5, то це O (n ^ 3) Нижні сили тут взагалі не мають значення, оскільки як n -> Inf, n ^ 2 буде неактуальним порівняно з п ^ 3

Так само, як n -> Inf, O (1 / n) буде неактуальним порівняно з O (1), отже, 3 + O (1 / n) буде таким же, як O (1), завдяки чому O (1) є найменшим можливим обчислювальним складність


-2
inline void O0Algorithm() {}

1
Це був би алгоритм O (1).
Лассе В. Карлсен

2
Це також, але справа в тому, що це не Ω (1). І чому моя відповідь знижена? Якщо ви думаєте, що я помиляюся, як щодо пояснення?
Стюарт

Запитав я в іншому місці , якщо, в принципі, це дуже відповідь є правильним чи ні, і це , здається спірним: stackoverflow.com/questions/3209139 / ...
jyoungdev

Добре це вбудовано, тому ви можете вважати це O (0). Однак усі алгоритми O (0) тривіальні (нічого не роблять), тому ... не дуже цікава відповідь.
Стефан Рейх

@StefanReich Правда, це не дуже цікаву відповідь, але це відповідь.
Стюарт

-2

Ось простий алгоритм O (1 / n). І це навіть робить щось цікаве!

function foo(list input) {
  int m;
  double output;

  m = (1/ input.size) * max_value;  
  output = 0;
  for (int i = 0; i < m; i++)
    output+= random(0,1);

  return output;
}

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


1
Оскільки O (1 / n) опуститься нижче горизонтальної лінії = 1, і коли n досягне нескінченності, ваш код все одно виконає задану кількість кроків, цей алгоритм є алгоритмом O (1). Позначення Big-O - це функція всіх різних частин алгоритму, і він вибирає найбільшу. Оскільки метод завжди буде виконувати деякі інструкції, коли n досягає нескінченності, вам залишаються ті самі самі інструкції, які виконуються кожен раз, і, таким чином, метод буде працювати в постійному часі. Зрозуміло, це не пройде багато часу, але це не стосується позначення Big-O.
Лассе В. Карлсен
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.