Пам'ятка без масиву


14

У вступі Кормен та ін. До алгоритмів , розділ 15.3 Елементи динамічного програмування пояснюють запам'ятовування наступним чином:

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

І додається, як виноска:

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

Чи є якісь добре відомі проблеми DP, які потребують (або полегшують) зберігання запам'ятованих значень у словнику, а не в (багатовимірному) масиві?


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


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

Відповіді:


5

Напевно, є кращі приклади, але ось один, у верхній частині голови:

S,Тг>г


3

Я хотів би навести 2 приклади.

0-1 Проблема з рюкзаком

У випадку проблеми 0-1 Рюкзак (де W - ємність рюкзака і N - кількість предметів), іноді краще використовувати динамічне програмування «зверху вниз» із запам'ятовуванням замість систематичного перерахування знизу вгору всього 2D масиву розміром WxN (особливо у випадку, коли ємність рюкзака W велика, але кардинальність набору дозволених комбінацій ваг предметів набагато менша, ніж W ).

У цьому випадку, для економії пам’яті, можна скористатися словником для запам'ятовування замість 2D масиву.

Алгоритм розбору Ерлі

Алгоритм розбору Ерлі може бути використаний для розбору висловлювань, які належать до безконтекстної граматики. На відміну від алгоритму CYK (який заснований на підході DP знизу вгору і використовує 2D таблицю для запам'ятовування) - Earley parser використовує підхід зверху вниз у поєднанні з діаграмою розбору для запам'ятовування.

Діаграма розбиття містить частково проаналізовані граматичні виробництва (наприклад: з огляду на виробництво X → AB , і після успішного узгодження A частини цього виробництва, ми зберігаємо частково збігану продукцію всередині діаграми розбору: X → A • B , де крапкові точки до вже узгодженої частини).

Кількість стовпців всередині діаграми розбору дорівнює кількості лексем. Однак у загальному випадку може бути дуже складно оцінити кількість частково проаналізованих граматичних виробів на стовпчик (це залежить від граматики та конкретної послідовності лексем).

Отже, зручніше реалізувати діаграму розбору на основі структури даних словника.

У домені "Обробка природних мов", як правило, Ерлі-парер є більш зручним вибором, оскільки він не вимагає нормальної форми грамматики Чомського (а CYK має таку вимогу).


0

На мій досвід конкурентного програмування, використання хеш-таблиці (Python's dictабо подібної) часто зручніше, ніж використання масиву, тому що будь-який тип хешируемих даних може використовуватися як ключ, наприклад рядки, набори (frozenset в Python) або кортежі (string, int)тощо. Якщо ви використовуєте масив, ви повинні вручну перевести всі ключі в цілі числа (починаючи з 0), що займе додаткову роботу і, як зазначає джерело, може бути неможливим, якщо ви не знаєте простір ключів заздалегідь. Тож словники швидше загальні, ніж масиви.

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

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