Динамическое программирование может сократить время, необходимое для выполнения рекурсивного алгоритма. Я знаю, что динамическое программирование может помочь уменьшить временную сложность алгоритмов. Являются ли общие условия такими, чтобы при выполнении рекурсивного алгоритма подразумевалось, что использование динамического программирования уменьшит временную сложность алгоритма? Когда я должен использовать динамическое программирование?
13
Ответы:
Динамическое программирование полезно, если ваш рекурсивный алгоритм часто сталкивается с одними и теми же ситуациями (входными параметрами). Существует общее преобразование из рекурсивных алгоритмов в динамическое программирование, известное как запоминание , в котором есть таблица, хранящая все результаты, когда-либо рассчитанные вашей рекурсивной процедурой. Когда рекурсивная процедура вызывается для набора уже использованных входных данных, результаты просто выбираются из таблицы. Это сводит рекурсивный Фибоначчи к итеративному Фибоначчи.
Динамическое программирование может быть еще умнее, применяя более конкретные оптимизации. Например, иногда нет необходимости хранить всю таблицу в памяти в любой момент времени.
источник
Если вы просто пытаетесь ускорить свой рекурсивный алгоритм, может быть достаточно запоминания . Это метод хранения результатов вызовов функций, чтобы будущие вызовы с теми же параметрами могли просто повторно использовать результат. Это применимо, если (и только если) ваша функция
Это сэкономит вам время, если (и только если) функция вызывается с одними и теми же параметрами снова и снова. Популярные примеры включают в себя рекурсивное определение чисел Фибоначчи, то есть
Если оценивать наивно, то вызывается экспоненциально часто. С запоминанием, всегда вычислялось уже , таким образом, остается только линейное количество вызовов.f ( n ) f ( n + 1 )f f(n) f(n+1)
Обратите внимание, что, напротив, запоминание почти бесполезно для таких алгоритмов, как сортировка слиянием: обычно несколько (если таковые имеются) частичных списков идентичны, а проверки на равенство стоят дорого (сортировка только немного дороже!).
В практических реализациях то, как вы сохраняете результаты, имеет большое значение для производительности. Использование хеш-таблиц может быть очевидным выбором, но может нарушить локальность. Если ваши параметры являются неотрицательными целыми числами, массивы являются естественным выбором, но могут вызвать огромные накладные расходы памяти, если вы используете только некоторые записи. Следовательно, запоминание - это компромисс между эффектом и стоимостью; окупится ли это, зависит от вашего конкретного сценария.
Динамическое программирование - это совершенно другой зверь. Это применимо к проблемам с собственностью, которая
Обычно это подразумевается, когда люди используют принцип оптимальности Беллмана .
Теперь, это только описывает класс проблем, которые могут быть выражены определенным видом рекурсии. Оценка их (часто) эффективна, потому что запоминание может быть применено с большим эффектом (см. Выше); обычно меньшие подзадачи возникают как часть многих более крупных проблем. Популярные примеры включают расстояние редактирования и алгоритм Беллмана-Форда .
источник