Аналіз складності алгоритму щодо реалізації функціональної мови програмування


10

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

Приклад, поданий мені, що ілюстрував це далі, користувачем @chi :

Наприклад, розгляньте завдання: задане повернення x i . У оперативній пам'яті це можна вирішити в O ( 1 ), оскільки доступ до масиву є постійним часом. Використовуючи TM, нам потрібно сканувати весь вхід, так що це O ( n )(i,х1,,хн)хiО(1)О(н)

Це змушує мене замислитися над функціональними мовами; З мого розуміння, "Функціональні мови тісно пов'язані з обчисленням лямбда" (з коментаря Ювала Філімуса тут ). Отже, якщо функціональні мови базуються на лямбдальному обчисленні, але вони працюють на машинах, що базуються на оперативній пам'яті, який правильний спосіб провести аналіз складності алгоритмів, реалізованих за допомогою суто функціональних структур даних та мов?

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

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

У такому випадку обчислювальна модель була б іншою, правильно?


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

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

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

1
@KurtMueller Зауважте, що ми можемо отримати лямбда-термін розміром після лише скорочення O ( n ) . Це робить модель витрат підрахунку кількості бета-версій нереальною. Можливо, кращим може бути зважування кожного кроку за розмірами термінів. Однак це не єдина можлива модель: оптимальне оцінювання лямбда-термінів не застосовує бета наївно, віддаючи перевагу більш досконалим машинам для скорочення графіків. У такому випадку підрахунок бета, мабуть, не був би доцільним. О(2н)О(н)
чі

1
Зауважте, що вам також потрібно знати, чи є ваша функціональна мова прагною чи лінивою / суворою чи не суворою. Нещодавно я стикався з ситуацією, коли алгоритм реального світу був багаточленним в Haskell (не суворий), але наївний переклад на OCaml (строгий) був експоненціальним.
Ерік Ліпперт

Відповіді:


6

Це залежить від семантики вашої функціональної мови. Ви не можете робити алгоритм аналізу мов програмування поодиноко, оскільки ви не знаєте, що твердження насправді означають. Специфікація для вашої мови повинна забезпечувати достатньо детальну семантику. Якщо у вашій мові вказується все, що стосується обчислення лямбда, вам потрібна певна міра витрат на зменшення (це О (1) чи вони залежать від розміру терміну, який ви скорочуєте?).

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


Я вважаю, що я начебто розумію вашу відповідь (непорозуміння, швидше за все, пояснюється моїм нерозумінням в обчисленні лямбда): Ви говорите, що в основному вам доведеться робити аналіз у кожному конкретному випадку (мова йде про мову), а не загальний спосіб, оскільки певні операції мають різні значення для кожної мови. Чи правильно моє розуміння?
Абдул

Так. Ваш мовний дизайнер повинен повідомити вам, що насправді означають те, що ви можете написати мовою, перш ніж ви зможете проаналізувати час виконання алгоритму.
adrianN

"Ви не можете робити алгоритм аналізу мов програмування ізольовано" - це стосувалося мов FP або мов взагалі? Якщо мова йшла про більш ранні, то як ми можемо аналізувати алгоритми в школі таким загальним способом, тобто аналізувати проблеми Java, C / C ++, Python? Це тому, що всі вони дуже схожі? Або це тому, що основні структури даних та ADT є однаковими та реалізованими так само? Або, нарешті, це тому, що ці курси просто заради освіти, і не обов'язково їх суворо точно визначати?
Абдул

1
Це справедливо для всіх мов програмування. Щоб бути чітко правильним, спочатку потрібно виправити модель машини, сказати оперативну пам’ять та (невеличку жменю) інструкцій, які вона підтримує. Аналіз програм можна робити лише за допомогою цих інструкцій. Тоді ви можете придумати відображення вашої мови програмування до цієї моделі машини. Потім ви можете проаналізувати програми мовою програмування. Для дуже жорсткого лікування перевірте, як це робить Кнут у "Мистецтві комп'ютерного програмування". Багато цього можна спростити через великі константи ховання.
adrianN
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.