Динамическое программирование. 9
Федеральное Государственное Образовательное Учреждение
Среднего профессионального образования
Краснодарский
гуманитарно-технологический
колледж
Курсовая работа по дисциплине «Математические методы»
На тему:
«Динамическое
Выполнил:
студент 4го курса гр.22-03
Мироненко Роман
Проверила:
Тутынина
Н.И.
Краснодар – 2010г.
Содержание
- Введение
- История
- Идея динамического программирования
- Общая структура динамического программирования
- Задача динамического программирования
- Пример задачи динамического программирования
- Задача о загрузке
- Общие сведения
- Рекуррентные соотношения для процедур прямой и обратной прогонки
- Решение задачи о загрузке
- Анализ чувствительности решения
- Заключение
- Список используемой литературы
ВВЕДЕНИЕ
В
наше время наука уделяет все
большое внимание вопросам организации
и управления, это приводит к необходимости
анализа сложных
В
моделях исследования операций переменные,
от которых зависят ограничения
и целевая функция, могут быть
дискретными (чаще всего целочисленными)
и континуальными (непрерывными). В
свою очередь, ограничения и целевая
функция делятся на линейные и
нелинейные. Существуют различные методы
решения данных моделей, наиболее известными
и эффективными из них являются методы
линейного программирования, когда
целевая функция и все
История
Словосочетание динамическое программирование впервые было использовано в 1940-х годах Р. Беллманом для описания процесса нахождения решения задачи, где ответ на одну задачу может быть получен только после решения задачи, «предшествующей» ей. В 1953 г. он уточнил это определение до современного. Первоначально эта область была основана, как системный анализ и инжиниринг, которая была признана IEEE (Институт инженеров по электротехнике и электронике ). Вклад Беллмана в динамическое программирование был увековечен в названии уравнения Беллмана, центрального результата теории динамического программирования, который переформулирует оптимизационную задачу в рекурсивной форме.
Слово
«программирование» в словосочетании
«динамическое
Идея динамического программирования
Оптимальная подструктура в динамическом программировании означает, что оптимальное решение подзадач меньшего размера может быть использовано для решения исходной задачи. К примеру, кратчайший путь в графе из одной вершины (обозначим s) в другую (обозначим t) может быть найден так: сначала считаем кратчайший путь из всех вершин, смежных с s, до t, а затем, учитывая веса ребер, которыми s соединена со смежными вершинами, выбираем лучший путь до t (через какую вершину лучше всего пойти). В общем случае мы можем решить задачу, в которой присутствует оптимальная подструктура, проделывая следующие три шага.
- Разбиение задачи на подзадачи меньшего размера.
- Нахождение оптимального решения подзадач рекурсивно, проделывая такой же трехшаговый алгоритм.
- Использование полученного решения подзадач для конструирования решения исходной задачи.
Подзадачи решаются делением их на подзадачи ещё меньшего размера и т. д., пока не приходят к тривиальному случаю задачи, решаемой за константное время (ответ можно сказать сразу). К примеру, если нам нужно найти n!, то тривиальной задачей будет 1! = 1 (или 0! = 1).
Перекрывающиеся подзадачи в динамическом программировании означают подзадачи, которые используются для решения некоторого количества задач (не одной) большего размера (то есть мы несколько раз проделываем одно и то же). Ярким примером является вычисление последовательности Фибоначчи, F3 = F2 + F1 и F4 = F3 + F2 — даже в таком тривиальном случае вычисления всего двух чисел Фибоначчи мы уже посчитали F2 дважды. Если продолжать дальше и посчитать F5, то F2 посчитается ещё два раза, так как для вычисления F5 будут нужны опять F3 и F4. Получается следующее: простой рекурсивный подход будет расходовать время на вычисление решение для задач, которые он уже решал.
Чтобы избежать такого хода событий мы будем сохранять решения подзадач, которые мы уже решали, и когда нам снова потребуется решение подзадачи, мы вместо того, чтобы вычислять его заново, просто достанем его из памяти. Этот подход называется кэширование. Можно проделывать и дальнейшие оптимизации — например, если мы точно уверены, что решение подзадачи нам больше не потребуется, можно выкинуть его из памяти, освободив её для других нужд, или если процессор простаивает и мы знаем, что решение некоторых, ещё не посчитанных подзадач, нам понадобится в дальнейшем, мы можем решить их заранее.
Подводя итоги вышесказанного можно сказать, что динамическое программирование пользуется следующими свойствами задачи:
- перекрывающиеся подзадачи;
- оптимальная подструктура;
- возможность запоминания решения часто встречающихся подзадач.
Динамическое программирование обычно придерживается двух подходов к решению задач:
- нисходящее динамическое программирование: задача разбивается на подзадачи меньшего размера, они решаются и затем комбинируются для решения исходной задачи. Используется запоминание для решений часто встречающихся подзадач.
- восходящее динамическое программирование: все подзадачи, которые впоследствии понадобятся для решения исходной задачи просчитываются заранее и затем используются для построения решения исходной задачи. Этот способ лучше нисходящего программирования в смысле размера необходимого стека и количества вызова функций, но иногда бывает нелегко заранее выяснить, решение каких подзадач нам потребуется в дальнейшем.
Языки
программирования могут запоминать
результат вызова функции с определенным
набором аргументов, чтобы ускорить
«вычисление по имени». В некоторых
языках такая возможность встроена
(например, Scheme, Common Lisp, Perl), а в некоторых
требует дополнительных расширений (C++).
Известны сериальное динамическое программирование,
включённое во все учебники по исследованию
операций, и несериальное динамическое
программирование (НСДП), которое в настоящее
время слабо известно, хотя было открыто
в 1960-х годах. Обычное динамическое программирование
является частным случаем несериального
динамического программирования, когда
граф взаимосвязей переменных — просто
путь. НСДП, являясь естественным и общим
методом для учета структуры задачи оптимизации,
рассматривает множество ограничений
и/или целевую функцию как рекурсивно
вычислимую функцию. Это позволяет находить
решение поэтапно, на каждом из этапов
используя информацию, полученную на предыдущих
этапах, причём эффективность этого алгоритма
прямо зависит от структуры графа взаимосвязей
переменных. Если этот граф достаточно
разрежен, то объём вычислений на каждом
этапе может сохраняться в разумных пределах.
Одним из основных свойств задач, решаемых
с помощью динамического программирования,
является аддитивность. Неаддитивные
задачи решаются другими методами.
Общая структура динамического программирования
Динамическое программирование — это вид математического программирования, который представляет собой систему приемов для нахождения оптимального решения с помощью определения последствий отдельного решения и организации оптимальной стратегии для дальнейших решений.
Характерной особенностью динамического программирования является последовательное исследование переменных. Главное заключается в том, что создается такая вычислительная схема, когда предпочтительнее большое количество задач с малым числом переменных, а не одна задача с множеством переменных. В результате процесс вычисления представляется не таким объемным. Но следует отметить, что для этого необходимо соблюдение двух условий:
- когда критерий оптимальности аддитивен или когда оптимальные решения отдельных шагов создают общее оптимальное решение;
- когда будущие результаты не предполагают использование предыстории того положения системы, при котором принимается решение.
Такие
условия производны от принципа оптимальности
Беллмана, на котором базируется теория
динамического
На принципе Беллмана основывается также главный метод — определение правил доминирования. Последний, в свою очередь, подразумевает осуществление сравнения примеров будущего развития на каждом этапе, при этом бесперспективные варианты сразу же исключаются.
Динамическое программирование в значительной мере полезно в случае нахождения решения задачи, которая изначально предполагает наличие определенных этапов. В данном контексте ярким примером может быть задача ремонта и замены оборудования. На одном заводе осуществляется параллельное производство двух шин в двух формах. В случае, если возникает неполадка с одной из форм, машину необходимо разбирать. Перспективным представляется осуществить замену и второй формы для предотвращения возможной поломки формы на следующем этапе. Следует также отметить, что, при просчитывании ситуации, стоит заменить сразу две формы, не дожидаясь поломки одной из них. Здесь использование метода динамического программирование актуально, поскольку возможен выбор оптимальной стратегии осуществления замены форм, беря во внимание наличие всех факторов. Скажем, преимущества от продолжения эксплуатации формы, убытки от простоя машины, цена непригодных шин и пр.
Динамическое программирование обычно применяется к задачам, в которых искомый ответ состоит из частей, каждая из которых в свою очередь дает оптимальное решение некоторой подзадачи.
Динамическое программирование полезно, если на разных путях многократно встречаются одни и те же подзадачи; основной технический приём — запоминать решения встречающихся подзадач на случай, если та же подзадача встретится вновь.
В
типичном случае динамическое программирование
применяется к задачам
Из
предыдущего рассуждения видно,
что решение можно оформить рекурсивно.
Но простое применение этого приема
очень легко может привести к
переполнению стека. Необходимо позаботиться
об оптимизации рекурсивных
Типовой
алгоритм решения задач методом
динамического
- Описать строение оптимальных решений.
- Выписать рекуррентное соотношение, связывающие оптимальные значения параметра для подзадач.
- Двигаясь снизу вверх, вычислить оптимальное значение параметра для подзадач.
- Пользуясь полученной информацией, построить оптимальное решение.
Задача
динамического программирования
Большинство методов исследования операций связано в первую очередь с задачами вполне определенного содержания. Классический аппарат математики оказался малопригодным для решения многих задач оптимизации, включающих большое число переменных и/или ограничений в виде неравенств. Несомненна привлекательность идеи разбиения задачи большой размерности на подзадачи меньшей размерности, включающие всего по нескольких переменных, и последующего решения общей задачи по частям. Именно на этой идее основан метод динамического программирования.
Динамическое программирование (ДП) представляет собой математический метод, заслуга создания и развития которого принадлежит прежде всего Беллману. Метод можно использовать для решения весьма широкого круга задач, включая задачи распределения ресурсов, замены и управления запасами, задачи о загрузке. Характерным для динамического программирования является подход к решению задачи по этапам, с каждым из которых ассоциирована одна управляемая переменная. Набор рекуррентных вычислительных процедур, связывающих различные этапы, обеспечивает получение допустимого оптимального решения задачи в целом при достижении последнего этапа.
Происхождение названия динамическое программирование, вероятно, связано с использованием методов ДП в задачах принятия решений через фиксированные промежутки времени (например, в задачах управления запасами). Однако методы ДП успешно применяются также для решения задач, в которых фактор времени не учитывается. По этой причине более удачным представляется термин многоэтапное программирование, отражающий пошаговый характер процесса решения задачи.
Фундаментальным принципом, положенным в основу теории ДП, является принцип оптимальности. По существу, он определяет порядок поэтапного решения допускающей декомпозицию задачи (это более приемлемый путь, чем непосредственное решение задачи в исходной постановке) с помощью рекуррентных вычислительных процедур.
Динамическое программирование позволяет осуществлять оптимальное планирование управляемых процессов. Под «управляемыми» понимаются процессы, на ход которых мы можем в той или другой степени влиять.
Пусть
предполагается к осуществлению
некоторое мероприятие или
Сформулируем общий принцип, лежащий в основе решения всех задач динамического программирования («принцип оптимальности»):
«Каково бы ни было состояние системы S перед очередным шагом, надо выбрать управление на этом шаге так, чтобы выигрыш на данном шаге плюс оптимальный выигрыш на всех последующих шагах был максимальным».
Динамическое программирование – это поэтапное планирование многошагового процесса, при котором на каждом этапе оптимизируется только один шаг. Управление на каждом шаге должно выбираться с учетом всех его последствий в будущем.
При постановке задач динамического программирования следует руководствоваться следующими принципами:
- Выбрать параметры (фазовые координаты), характеризующие состояние S управляемой системы перед каждым шагом.
- Расчленить операцию на этапы (шаги).
- Выяснить набор шаговых управлений xi для каждого шага и налагаемые на них ограничения.
- Определить какой выигрыш приносит на i-ом шаге управление xi, если перед этим система была в состоянии S, т.е. записать «функцию выигрыша»:
- Определить, как изменяется состояние S системы S под влиянием управление xi на i-ом шаге: оно переходит в новое состояние
- Записать основное рекуррентное уравнение динамического программирования, выражающее условный оптимальный выигрыш Wi(S) (начиная с i-го шага и до конца) через уже известную функцию Wi+1(S):
Этому выигрышу соответствует условное оптимальное управление на i-м шаге xi(S) (причем в уже известную функцию Wi+1(S) надо вместо S подставить измененное состояние )
- Произвести условную оптимизацию последнего (m-го) шага, задаваясь гаммой состояний S, из которых можно за один шаг дойти до конечного состояния, вычисляя для каждого из них условный оптимальный выигрыш по формуле
- Произвести условную оптимизацию (m-1)-го, (m-2)-го и т.д. шагов по формуле (1.2), полагая в ней i=(m-1),(m-2),…, и для каждого из шагов указать условное оптимальное управление xi(S), при котором максимум достигается.
Заметим, что если состояние системы в начальный момент известно (а это обычно бывает так), то на первом шаге варьировать состояние системы не нужно - прямо находим оптимальный выигрыш для данного начального состояния S0. Это и есть оптимальный выигрыш за всю операцию
- Произвести
безусловную оптимизацию
управления, «читая» соответствующие рекомендации на каждом шаге. Взять найденное оптимальное управление на первом шаге ; изменить состояние системы по формуле (1.1); для вновь найденного состояния найти оптимальное управление на втором шаге х2* и т.д. до конца.
Данные
этапы рассматривались для
(если
только выигрыши wi положительны).
Эти задачи решаются точно так же, как
задачи с аддитивным критерием, с той единственной
разницей, что в основном уравнении (1.2)
вместо знака «плюс» ставится знак «умножения»:
Пример
задачи динамического
программирования
Задача планирования рабочей силы:
При
выполнении некоторых проектов число
рабочих, необходимых для выполнения
какого-либо проекта, регулируется путем
их найма и увольнения. Поскольку
как наем, так и увольнение рабочих
связано с дополнительными
Предположим, что проект будет выполнятся в течение n недель и минимальная потребность в рабочей силе на протяжении i-й недели составит bi рабочих. При идеальных условиях хотелось бы на протяжении i-й недели иметь в точности bi рабочих. Однако в зависимости от стоимостных показателей может быть более выгодным отклонение численности рабочей силы как в одну, так и в другую сторону от минимальных потребностей.
Если xi – количество работающих на протяжении i-й недели, то возможны затраты двух видов: 1) С1(xi- bi)-затраты, связанные с необходимостью содержать избыток xi - bi рабочей силы и 2) С2(xi- xi-1)-затраты, связанные с необходимостью дополнительного найма (xi- xi-1) рабочих.
Элементы модели динамического программирования определяются следующим образом:
- Этап і представляется порядковым номером недели і, і=1,2,…n.
- Вариантами решения на і-ом этапе являются значения xi – количество работающих на протяжении і-й недели.
- Состоянием на і-м этапе является xi-1 – количество работающих на протяжении (і-1) –й недели (этапа).
Рекуррентное
уравнение динамического
где
Вычисления начинаются с этапа n при xn=bn и заканчиваются на этапе 1.
ЗАДАЧА О ЗАГРУЗКЕ
Общие сведения
Задача о загрузке – это задача о рациональной загрузке судна (самолета, автомашины и т.п.), которое имеет ограничения по объему или грузоподъемности. Каждый помещенный на судно груз приносит определенную прибыль. Задача состоит в определении загрузки судна такими грузами, которые приносят наибольшую суммарную прибыль.
Рекуррентное уравнение процедуры обратной прогонки выводится для общей задачи загрузки судна грузоподъемностью W предметов (грузов) n наименований. Пусть mi-количество предметов і-го наименования, подлежащих загрузке, ri-прибыль, которую приносит один загруженный предмет і-го наименования, wi-вес одного предмета і-го наименования. Общая задача имеет вид следующей целочисленной задачи линейного программирования.
Максимизировать z=r1m1+r2m2+…+rnmn.
при условии, что
w1m1+w2m2+…+wnmn
m1,m2,…,mn
Три элемента модели динамического программирования определяются следующим образом:
- Этап і ставится в соответствии предмету і-го наименования, і=1,2,…n.
- Варианты решения на этапе і описываются количеством mi предметов і-го наименования, подлежащих загрузке. Соответствующая прибыль равна rimi. Значение mi заключено в пределах от 0 до [W/wi], где [W/wi] – целая часть числа W/wi.
- Состояние xi на этапе і выражает суммарный вес предметов, решения о погрузке которых приняты на этапах і,і+1,...n. Это определение отражает тот факт, что ограничения по весу является единственным, которое связывает n этапов вместе.
Пусть fi(xi)-максимальная суммарная прибыль от этапов і,і+1,...,n при заданном состоянии xi. Проще всего рекуррентное уравнение определяется с помощью следующей двухшаговой процедуры.
Шаг 1. Выразим fi(xi) как функцию fi+1(xi+1) в виде
где fn+1(xn+1)=0.
Шаг 2. Выразим xi+1 как функцию xi для гарантии того, что левая часть последнего уравнения является функцией лишь xi. По определению xi-xi+1 представляет собой вес, загруженный на этапе і, т.е. xi-xi+1=wimi или xi+1=xi-wimi. Следовательно, рекуррентное уравнение приобретает следующий вид:
Рекуррентные
соотношения для
процедур прямой и
обратной прогонки
Фермеру принадлежит стадо овец, насчитывающее k голов. Один раз в год фермер принимает решение о том, сколько овец продать и сколько оставить. Прибыль от продажи одной овцы в і-м году составляет pi. Количество оставленных в i-м году овец удваивается в (1+1)-м году. По истечении п лет фермер намеревается продать все стадо.
Этот чрезвычайно простой пример приводится для того, чтобы наглядно продемонстрировать преимущества алгоритма обратной прогонки по сравнению с алгоритмом прямой прогонки. Вычислительные схемы процедур прямой и обратной прогонки обладают различной эффективностью в случаях, когда этапы модели нумеруются в некотором специальном порядке. Такая ситуация имеет место в приводимом примере, где этап j ставится в соответствие году j, т. е. этапы должны рассматриваться в хронологическом порядке.

- Динамическое программирование
- Динамическое программирование
- Динамическое программирование
- Динамическое программирование
- Динамическое программирование
- Динамическое программирование (
- Динамическое программирование в экономике
- Динамическое программирование
- Динамическое программирование
- Динамическое программирование
- Динамическое программирование
- Динамическое программирование
- Динамическое программирование
- Динамическое программирование