- •6. Методы решения задачи поиска кратчайшего пути
- •6.1. Нахождение кратчайшего пути
- •6.1.1. Прямой симметричный алгоритм
- •6.1.2. Задача коммивояжера
- •6.1.3. Прямой алгоритм (перебор с возвратом).
- •6.1.4. Алгоритм Дейкстры.
- •6.1.5. Алгоритм Литтла.
- •1) Зануление по строкам
- •2) Зануление по столбцам
- •6.2. Основные понятия и определения динамического программирования
- •6.2.1. Жадный алгоритм.
- •6.3 Кратчайший путь. Алгоритм Дейкстры
- •6.3.1. Алгоритм Дейкстры
- •6.4. Сетевое планирование
- •6.4.1. Правила построения сетевого графика
- •6.4.2. Алгоритм построения сетевого графика
- •6.4.3. Метод Фалкерсона
- •6.4.4. Временные параметры сетевых графиков
- •6.4.5. Пример построения сетевого графика
- •6.4.6. Пример расчета временных характеристик
- •Оглавление
6.2. Основные понятия и определения динамического программирования
Под динамическим программированием понимают некоторый специальный метод оптимизации, суть которого состоит в отыскании оптимального решения путем выполнения вычислений в несколько шагов (этапов). Вся задача оптимизации разделяется на несколько шагов, причем вес шаги могут быть уникальными или одинаковыми и чередоваться друг с другом. Некоторые задачи оптимизации легко разделяются на шаги естественным способом, а для других — вводится искусственное разделение на шаги.
Примерами задач, решаемых динамическим программированием, могут быть: распределение ресурсов (финансовых, сырьевых, материальных и т.д.) между предприятиями, замена (или ремонт) промышленного оборудования, прокладка коммуникаций (трубопроводов, дорог и т.д.) и пр. В этих задачах, как правило, в качестве шагов (этапов) выступают отрезки времени (годы, кварталы и т. д.), которые явно задаются в условии задачи.
Оптимальное решение задачи в целом складывается из оптимальных решений на каждом шаге
(6.3)
(где li — оптимальное решение на i-м шаге.
В этом случае говорят, что целевая функция L обладает «аддитивным критерием качества».
6.2.1. Жадный алгоритм.
Задача динамического программирования по своей сути является управляемым процессом, причем управление выполняется на каждом шаге. Особо надо подчеркнуть, что выбор оптимального решения на конкретном шаге не дает гарантии получения оптимального решения для всей задачи. То есть для получения оптимального решения для всей задачи иногда приходится выбирать не лучшее решение на конкретном шаге. Таким образом, планирование многошаговой задачи сводится к выбору такого решения на каждом шаге, которое учитывает последствия на следующих (будущих) шагах. На текущем шаге выбирается не лучшее решение, а то, которое предполагает максимальную сумму выигрыша от всех оставшихся шагов.
Учитывая вышесказанное, выполнять вычисления в задачах динамического программирования удобнее от конца к началу. Действительно, легко можно планировать последний,т - 1, шаг. Выполняя вычисления по последнему шагу, надо сделать ряд предположений: как закончился предыдущий,т-1, шаг и для каждого предположения найти условно-оптимальное решение наw-м шаге. Аналогично выполняютсят- 1,т-2 и т.д. шаги, вплоть до первого шага.
Таким образом, будут найдены условно-оптимальные решения на каждом шаге. Далее выполняется переход от условно-оптимального решения к безусловно-оптимальному решению на каждом шаге, т. е. выполняются вычисления от первого шага к последнему шагу, ориентируясь на полученные условно-оптимальные решения. Теперь на первом шаге известна «стоимость» решения задачи от второго шага до последнего шага и, следовательно, можно указать оптимальное решение на первом шаге (снизить «стоимость» первого шага). Далее аналогично выполняются второй, третий и т.д. шаги.
При использовании динамического программирования многошаговая задача решается дважды: от конца к началу (определение условно-оптимального решения) и от начала к концу (определениебезусловно-оптимального решения). Первый этап длительный и трудоемкий, второй — короткий и уточняет решения первого этапа (по готовым рекомендациям определяется безусловно-оптимальное решение на каждом шаге).
Пример 6. Проложить полотно железной дороги по кратчайшему, с экономической точки зрения, пути между пунктами А и Б. На географической карте строится некоторая прямоугольная область, где в левом нижнем углу помещен пункт А, а в правом верхнем углу — пункт Б. Прямоугольная область по горизонтали и по вертикали разделяется на произвольное количество отрезков, и по границам отрезков строится сетка. Для каждой стороны элементарного прямоугольника определяется стоимость прокладки пути.
Для упрощения решения задачи положим, что путь может прокладываться только по границам элементарных прямоугольных областей (т. е. под углом 90°), заранее известна стоимость строительства по каждому элементарному отрезку, и путь от пункта Б к пункту А прокладывается в направлении справа налево и сверху вниз без петель. Таким образом, каждый возможный путь от пункта А до пункта Б будет представлять собой ломаную линию. Надо проложить такой путь от А к Б, чтобы суммарные затраты на его строительство были минимальны. Возможны два варианта: полный перебор всех возможных путей, что очень долго и трудно, и использование динамического программирования с разделением задачи по шагам.
Разделим расстояние между пунктами А и Б на 17 отрезков (шагов) по горизонтали и на 8 отрезков (шагов) по вертикали. Тогда длина любого пути составит т= 17 + 8 = 25 отрезков (шагов). На рисунке указаны стоимости строительства пути по каждому отрезку.
Перемещение от Б к А выполняется последовательно по элементарному пути (шагу) к следующей узловой точке. Каждая узловая точка характеризуется двумя координатами: горизонтальной и вертикальной. Обе координаты целочисленные и большие нуля: 0≤х≤ 17 и 0≤у≤8. В каждой узловой точке будем определять условное оптимальное управление (движение по горизонтали или движение по вертикали). Направление движения выбирается из условия: стоимость строительства всех остальных отрезков пути, включая текущий отрезок, должна быть минимальной. Эту стоимость будем называть условно-оптимальной.
Итак, запустим процедуру поиска условно-оптимального решения от конца к началу (от пункта Б к пункту А). На последнем 25-м шаге будем находиться в верхнем правом углу (пункт Б). Попасть в пункт Б можно с 24-го шага и возможны два варианта: двигаться по горизонтали (стоимость 11, узел Б1) или двигаться по вертикали (стоимость 15, узел Б2) .
Рис.6
Рис.7
Из узла Б1 к пункту Б можно двигаться только в одном направлении — по горизонтали, и стоимость движения составит 11. Точно также из узла Б2 к пункту Б можно двигаться только в одном направлении — по вертикали, и стоимость движения составит 15. Таким образом, для последнего 25-го шага предпочтительнее движение из узла Б1. Теперь рассмотрим предшествующий 24-й шаг. Предыдущий 23-шаг мог закончиться в одном из узлов В1, В2 и В3. Из узла В1 движение возможно только в одном направлении — по горизонтали к узлу Б1, и стоимость этого перехода составит 11, а суммарная стоимость до конечного пункта Б — 22. Из узла В2 возможны два направления движения:
• В2 — Б1 — Б с общей стоимостью движения 11 + 15 = 26;
• В2 — Б2 — Б с общей стоимостью движения 15 + 12 = 27. Наилучший путь первый, и его стоимость 26 поместим в кружок В2.
Из узла В3 движение возможно только в одном направлении — по вертикали к узлу Б2, и общая стоимость движения составит 15 + 14 = 29.
Наилучший вариант движения от узла В1 к узлу Б1 так как его суммарная стоимость составит 22.
Далее поступаем аналогичным образом, т. е. на каждом шаге оптимизируем только текущий шаг и прибавляем результат от оптимизации последующих шагов.
По изложенному алгоритму выполняется условная оптимизация: в каждой узловой точке известно направление движения и стоимость оставшегося пути. Дойдя до пункта А, получим условную оптимальную стоимость строительства железнодорожного пути, равную 262.
Рис.8
Во время движения от пункта Б к пункту А несколько раз возникала ситуация выбора: куда идти, влево или вниз (по горизонтали или по вертикали), при одинаковой стоимости работ (вершины Е1, М1, Р1, С1, Ф1,Х1). В данной ситуации выбор направления движения был произвольным, так как при повторном просчете неудачный выбор будет исправлен.
Теперь при прямом просчете алгоритма возможно улучшение полученных решений на отдельных шагах. Переходим к безусловному оптимальному управлению — определению пути от пункта А к пункту Б самым дешевым способом.
Начинаем движение от пункта А вверх (по вертикали), хотя условно-оптимальное решение дало результат по горизонтали. Двигаясь из пункта А по вертикали, ищем самый короткий («дешевый») путь к одной из узловых точек, в которых был неоднозначный выбор (E1, M1, P1, С1 Ф1 X1). Если вновь пройденный путь дает лучшие результаты, чем ранее пройденный условно-оптимальный путь, то условно-оптимальный участок пути заменяем на безусловно-оптимальный путь.
От узловой точки P1 до пункта Б стоимость работ составляет 145. По вновь пройденному оптимальному пути, стоимость работ составляет 95.
Итоговая сумма 145 + 95 = 240, что меньше условно-оптимального решения (262). Поэтому условно-оптимальное решение от пункта А до узловой точки P1 заменим на только что найденное безусловно-оптимальное решение. Далее от узловой точки P1 также возможен альтернативный путь до узловой точки Mi .
Рис.10
Стоимость каждого из путей условно-оптимального и безусловно-оптимального одинаковая, поэтому можно выбрать любой из путей.
Но от узловой точки P1 до узловой точки E1 можно добраться, минуя узловую точку М1. Рассмотрим этот путь (на рисунке показан пунктирной линией).
Рис.11
Итоговая сумма по только что пройденному пути составляет 249, что больше ранее найденного решения. Поэтому замену путей выполнять не будем.
От узловой точки М1 до узловой точки E1 можно добраться другим путем.
Рис.12
Стоимость движения по этому пути составит 191 + 52 = 243, что «дороже» (длиннее), чем по ранее пройденному пути, поэтому замену пути выполнять не будем [3].
Больше альтернативных разветвлений не было. Оптимизация закончена. Безусловно-оптимальный путь показан на рисунке. Его стоимость составляет 240. Причем отрезок пути от узловой точки P1 до узловой точки M1 можно выполнить двумя вариантами, одинаковыми по стоимости.
Рис.13