Програматично знайти алгоритм позначення Ландау (Велика О або Тета позначення)?


11

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

Я витратив деякий час на Codility (вправи на кодування / альго), і помітив, що вони дадуть вам позначення Ландау за подане рішення (як у використанні часу, так і в пам'яті).

Мені було цікаво, як вони це роблять ... Як би ти це зробив?

Чи є ще один спосіб, крім лексичного аналізу або розбору коду?

Це питання стосується переважно PHP та JavaScript, але я відкритий для будь-якої мови та теорії.


4
Перевірте цю відповідь з ТА. Це звучить як те, що ти шукаєш.
Деко

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

1
Для доказів того, що визначити час роботи взагалі неможливо, дивіться тут і тут - відповіді там виявляються навіть більше, ніж ви просите насправді.
Алекс десять Бринк

Відповіді:


13

Мені було цікаво, як вони це роблять ... Як би ти це зробив?

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

Проблема такого підходу полягає в тому, що він може помилитися, якщо функції витрат змінюють форму, коли N стає великим; напр 1000 N + N^1.5.

Чи є ще один спосіб, крім лексичного аналізу або розбору коду?

Лексичного аналізу та розбору недостатньо. Також потрібно зробити кілька міркувань щодо поведінки алгоритму. І зробити це автоматично для раніше невідомого алгоритму важко.


6
"зробити це автоматично для раніше невідомого алгоритму важко" - Точніше: це рівнозначно вирішенню проблеми зупинки.
Йорг W Міттаг

Емм ... не зовсім так. Вирішення проблеми зупинки було б рівнозначно можливості зробити це для всіх раніше невідомих алгоритмів.
Стівен C

2
Так, вибачте. Робити це за одним алгоритмом рівносильно (а точніше, має на увазі) доведення припинення.
Йорг W Міттаг

1
Практичність цього полягає в тому, що 1) неможливо довести або спростувати припинення для деяких алгоритмів, але 2) більшість алгоритмів не мають цієї теоретичної перешкоди, але 3) стан доказів теореми недостатньо розвинений, щоб вміти робити це все одно ... за винятком порівняно простих випадків. Звідси моє твердження, що я думаю, що вони роблять це по-іншому. Але очевидно, ми не можемо бути впевнені, як вони насправді роблять це, не дивлячись на їх код.
Стівен С

3

Вони не можуть без аналізу коду.

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

void lets_trick_runtime(int n) {
   if (n == 10 || n == 25 || n == 118) {
      // unfair speed-up
      do_precalculated_solution_in_constant_time(n);
      return;
   }
   if (n == 11 || n == 26 || n == 119) {
      // unfair slow-down
      do_some_fake_processing_in_n_cube_time(n);
      return;
   }
   // fair solution
   do_general_solution_in_quadratic_time(n);
}

Оцінка часу виконання вище може бути спроможною давати підроблені оцінки - постійний час для значень, nде є попередньо розраховане рішення, і кубічний час для значень, де unfair slow-downпочинається, - замість "справедливого" квадратичного часу.


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

1

Я думаю, що це неможливо.

Якщо ви запускаєте кілька тестів із фіксованою кількістю різних розмірів вхідних даних, ви можете легко обчислити поліном, який наблизить час виконання, який ви оцінили дуже добре. Отже, ви закінчуєте поліном для кожної можливої ​​програми, що означало б P = NP(так!;)).

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

Однак можуть бути дуже особливі випадки, коли можливий пізній метод. Але ці випадки можуть бути такими маленькими, що це сумнівно, якщо зусилля колись будуть окуплені.


1
+1, хоча я думаю, що проблему зупинки можна вважати рідкістю.
Ям Маркович

0

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

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

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

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


0

Моя інтуїція полягає в тому, що загальне рішення цієї проблеми неможливо; стверджуючи, як це робиться, апріорні факти про час виконання алгоритмів без їх запуску (ви натякаєте на лексичний аналіз). Це означає, що для евристичного алгоритму (мабуть, великого) класу алгоритмів можливо (оскільки ми це робимо постійно), але загальний алгоритм робити це було б рівнозначно вирішенню проблеми Entscheidungs, яка, як відомо, не може бути можливо (пор. Церква, Тюрінг та ін.). Я ~ 99,9% впевнений у цьому зараз, коли думаю про це ...

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.