Динамическое программирование
Динамическое программирование — метод решения задачи путём её разбиения на несколько одинаковых подзадач, рекуррентно связанных между собой.
Само понятие «динамическое программирование» впервые было использовано в 1940-х годах Ричардом Беллманом для описания процесса нахождения решения задачи, где ответ на одну задачу может быть получен только после решения другой задачи, «предшествующей» ей.
Таким образом, американский математик и один из ведущих специалистов в области математики и вычислительной техники — Ричард Эрнст Беллман — стал прародителем динамического программирования.
Позднее формулировка понятия была доработана и усовершенствованна до современного вида самим же Беллманом.

Слово «программирование» в контексте «динамическое программирование» на самом деле к классическому пониманию программирования (написанию кода на языке программирования) практически никакого отношения не имеет. Слово «Программирование» имеет такой же смысл как в словосочетании «математическое программирование», которое является синонимом слова «оптимизация».

Поэтому программы будут использоваться в качестве оптимальной последовательности действий для получения решения задачи.

В общем же для начала, неформальное определение понятия динамического программирования может звучать так:
Задачи оптимизации, как правило, связаны с задачей максимизации или минимизации той или иной целевой функции (например, максимизировать вероятность того, что система не сломается, максимизировать мат. ожидание получения прибыли и т.д.).

Задачи комбинаторики, как правило, отвечают на вопрос, сколько существует объектов, обладающих теми или иными свойствами, или сколько существует комбинаторных объектов, обладающих заданными свойствами.

То есть, ДП решает не все задачи, а лишь некоторые, определенный класс подзадач. Но этот класс подзадачи используется во многих областях знаний: программирование, математика, лингвистика, статистика, теория игр, экономика, в компьютерных науках и т.п.

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

Неформальное объяснение свойства оптимальности у подзадач может быть продемонстрировано с помощью диаграммы:

Есть задача, которую мы хотим решить при помощи ДП, т.е. найти какой-то план ее решения. Допустим эта задача сложна и сразу решить мы ее не можем. Мы берем малую подзадачу и решаем сначала ее (для x1). Затем используя это малое решение x1, и не меняя структуру этого решения, решаем следующую задачу уже с x1 и x2. И т.д.
Во многих задачах требуется найти лучшее решение при заданных ограничениях. Важно рассмотреть задач на графы. К таким задачам относятся поиск кратчайшего пути, минимальные остовные деревья и паросочетания. Динамическое программирование - это методика эффективной реализации рекурсивных алгоритмов через сохранение промежуточных результатов.

Пример задачи

Денежная система страны предоставляет монеты номиналом с1=1б с2, …сN. Как выдать сумму S с помощью минимального числа монет?

На вход подается сумма s и количество номиналов N, далее в следующей строке вводится значение номиналов.

На выходе в первой строке минимальное количество монет, во второй количество монет каждого номинала.

Понятие динамического программирования

Неформальное объяснение оптимальности подзадач ДП.

Рассмотрим неформальную идею ДП.

Итак, возьмем пример с заводом, изготавливающим мебель.

Для достижения цели максимизации прибыли необходимо решить множество подзадач:

  • сколько стульев произвести — переменная X1,
  • сколько столов произвести — переменная X2,
  • сколько нанять работников — переменная X3,
  • … Хn.
При большом количестве подзадач сложно понять, как решать такую задачу. Как правило, решить одну малую задачу проще, чем решить большую задачу, состоящую из маленьких.

Поэтому ДП предлагает следующее:

  • берем одну подзадачу с переменной X1, об остальных подзадачах пока забываем.
  • После того, как найдем оптимальное решение для первой подзадачи, берем подзадачу для двух переменных Х1 и Х2, и решаем ее с помощью уже найденного решения для первой подзадачи.
  • Получаем решение уже для большей подзадачи, где фигурируют переменные Х1 и Х2. Затем, используя полученное решение, берем подзадачи, охватывающие X1, X2 и Х3.
  • И так продолжаем пока не получим решение для всей общей задачи.

ФОРМАЛЬНАЯ ИДЕЯ ДП

Часто при постановке задачи кажущимся оптимальным решением является перебор всех возможных вариантов. Однако, вследствии очень большого количества таких вариантов и, как результат, перегрузки памяти компьютера, такой способ не всегда приемлем.

Кроме того, может возникнуть такой вопрос: для того чтобы найти, например, минимум или максимум, почему бы нам не найти производную? или не использовать множества Ла-Гранжа, или другие методы аппарата математического анализа? Зачем нужно ДП, если есть большой арсенал средств?

Дело в том, что:
При этом важно, что при решении более сложной задачи, мы не решаем заново маленькую подзадачу, а используем уже решенный ответ этой подзадачи.
На графике это может выглядеть так:
Когда мы решаем задачу с производными, множествами Ла-Гранжа и т.п., то мы работаем с непрерывными функциями. При решении же задач ДП мы будем работать в основном с дискретными функциями, поэтому говорить здесь о применении непрерывных функций неуместно.

По этой причине во многих задачах, но не во всех, применение аппарата математического анализа будет неприемлемым.
This site was made on Tilda — a website builder that helps to create a website without any code
Create a website