
логистика / 0807155_B5569_tihomirova_a_n_sidorenko_e_v_matematicheskie_modeli_i_metody
.pdfвстречается в логистике, так что рассмотрение этих специальных (и более простых) алгоритмов вполне оправдано.
Если же некоторые ребра имеют отрицательный вес, то единственное ограничение состоит в том, чтобы в G не было циклов с суммарным отрицательным весом. Если такой цикл Ф все же существует и vt — некоторая его вершина, то, двигаясь от s к vt, обходя затем Ф достаточно большое число раз и попадая, наконец, в t, мы получим путь со сколь угодно малым (- ∞) весом. Таким образом, в этом случае кратчайшего пути не существует.
Если, с другой стороны, такие циклы существуют, но исключаются из рассмотрения, то нахождение кратчайшего пути (простой цепи) между s и t эквивалентно нахождению в этом графе кратчайшего гамильтонова пути с концевыми вершинами s и t. Задача нахождения кратчайшего гамильтонова пути намного сложнее, чем задача о кратчайшем пути – поэтому в рамках данного пособия рассматривать ее не будем и предположим, что все циклы в G имеют неотрицательный суммарный вес. Отсюда также вытекает, что неориентированные дуги (ребра) графа G не могут иметь отрицательные веса.
ПОСТАНОВКА ЗАДАЧИ
В ориентированной, неориентированной или смешанной (т. е. где часть дорог имеет одностороннее движение) сети найти кратчайший путь из заданной вершины во все остальные.
Возможные постановки задачи
Пусть дан граф G = (V, U), дугам которого приписаны веса (стоимости), задаваемые матрицей С = [сij]. Элементы {сij} матрицы весов С могут быть в общем случае положительными, отрицательными или нулями.
I. Найти кратчайший путь от заданной начальной вершины s V до заданной конечной вершины t V.
II.Найти кратчайшие пути от заданной начальной вершины s V до всех других вершин vt V.
III.Найти кратчайшие пути между всеми парами вершин vs, vt V.
161
Во всех трех случаях поиск кратчайшего пути между s и t имеет смысл, если такой путь, вообще говоря, существует, т. е. при условии t R (s). Здесь R (s) — множество, достижимое из вершины s. В случае неориентированного связного графа такой путь существует между любой парой вершин (по определению связности).
На самом деле, почти все методы, позволяющие решить задачу I о кратчайшем (s-t)-пути, дают также (в процессе решения)
ивсе кратчайшие пути от s к vt (vt V). Таким образом, они позволяют решить задачу II с небольшими дополнительными вычислительными затратами. С другой стороны, задача III может быть решена либо N-кратным применением алгоритма задачи I, причем на каждом шаге в качестве начальной вершины s берутся различные вершины, либо однократным применением специального алгоритма.
Как и для большинства задач, для решения задачи о кратчайших путях можно предложить много процедур решения. Например, физическое моделирование такого рода: на плоской доске рисуется карта местности, в города и развилки вбиваются гвозди, на каждый гвоздь надевается кольцо, дороги укладываются веревками, которые привязываются к соответствующим кольцам. Чтобы найти кратчайшее расстояние между кольцом i и кольцом k, нужно взять i в одну руку, взять k в другую и растянуть. Те веревки, которые натянутся и не дадут разводить руки шире, и образуют кратчайший путь между i и k. Однако математическая процедура, которая промоделирует эту физическую, выглядит очень сложно.
Известны алгоритмы попроще, один из которых будет описан далее. Это алгоритм, предложенный Дейкстрой еще в 1959 г. для систем с неотрицательными значениями весов и алгоритм Флойда для произвольных матриц весов. Алгоритм Дейкстры в чистом виде решает задачу II (а значит автоматически
изадачу I за то же время, и задачу III в случае N-кратного применения). Алгоритм Флойда сразу же дает решение задачи III.
Предполагаем, что матрица не удовлетворяет, вообще говоря, условию треугольника, согласно которому
162
с[i,j] <= с[i,k]+с[k,j] для всех i, j, k. В противном случае кратчайший путь между хi и хj состоит из одной единственной дуги (vi, vj) и задача становится тривиальной (если конечно такая дуга существует).
Если в графе G дуга (vi,vj) отсутствует, то ее вес полагается равным ∞.
ОПИСАНИЕ АЛГОРИТМА (ДЕЙКСТРЫ) Основная идея
Алгоритм применим только при условии, что с[i,j]≥0, и основан на приписывании вершинам временных пометок, причем пометка вершины дает верхнюю границу длины пути от s к этой вершине. Эти пометки (их величины) постепенно уменьшаются с помощью некоторой итерационной процедуры, и на каждом шаге итерации точно одна из временных пометок становится постоянной. Последнее указывает на то, что пометка уже не является верхней границей, а дает точную длину кратчайшего пути от s к рассматриваемой вершине.
Формальное описание алгоритма (Дейкстры)
Пояснения:
Алгоритм использует три массива из N (число вершин сети) чисел каждый. Первый массив Metka содержит метки с двумя значения: 0 (вершина еще не рассмотрена) и 1 (вершина уже рассмотрена); второй
массив |
Curr_dist |
содержит |
расстояния |
- текущие |
||||
кратчайшие |
расстояния от |
s |
до |
соответствующей |
||||
вершины; третий массив |
Pred_num |
содержит номера |
||||||
вершин |
(элемент |
pred_num [k] |
есть |
номер |
||||
предпоследней вершины на |
текущем |
кратчайшем |
пути |
|||||
из s |
в |
k). Матрица расстояний |
D задает |
длину |
||||
(вес) |
дуги |
d[i,j]; |
если такой |
дуги |
нет, то |
d[i,j]=∞.
Ввод:
Матрица расстояний D={d[i,j]}
163
Инициализация:
(i - номер стартовой вершины)
Вцикле от 1 до N заполнить нулями массив Metka; Заполнить числом i массив Pred_num;
Перенести i-ю строку матрицы D в массив Curr_dist; metka[i]:=1;
pred_num[i]:=0
Общий шаг:
Вцикле от 1 до N
1.Найти минимум среди неотмеченных вершин (т. е. тех k для которых metka[k] = 0); пусть минимум достигается на индексе j).
Затем выполняются следующие операции: 2.metka[j]:=1; (пометить выбранную вершину) 3.В цикле по k от 1 до N: если curr_dist[j]+d[j,k]< curr_dist[k], то
curr_dist[k]:=curr_dist[j]+d[j,k]; pred_num[k]:=j
Т.о. если наименее короткий известный путь из i в k длиннее, чем сумма наиболее короткого пути из i в j и прямого пути (j, k), значение элемента curr_dist[k] заменяется на сумму значений элементов curr_dist[j]и d[j,k]. По выходу из цикла все metka [i] = 1 (все вершины отмечены), и длина минимального пути от i до k равна curr_dist[k].
Вывод:
Теперь надо перечислить вершины, входящие в кратчайший путь. Путь от i до k выдается в обратном порядке следующей процедурой
z:= pred_num[k] ;
Выдать z;
z:=pred_num[z]. Если z = 0, то конец, иначе опять выдать z.
Анализ сложности
Для решения задачи II (а значит и задачи I) нужно N раз просмотреть массив Curr_dist из N элементов, т. е. алгоритм Дейкстры имеет квадратичную сложность: O(N2).
164

Для решения задачи III (если надо узнать кратчайшие пути между всеми вершинами) нужно N раз повторить алгоритм Дейкстры, принимая по очереди каждую вершину за стартовую. В случае полного графа с неотрицательной матрицей весов С время, необходимое для вычислений, пропорционально O(N3), а для произвольной матрицы весов оно пропорционально O(N4).
Схема работы алгоритма показана на рис.2.8.
Ввод матрицы расстояний D
Выбрать стартовую вершину (номер i)
Metka=0 для всех вершин, кроме стартовой (=1)
Curr_dist=i-ая строка матрицы D
Pred_num=i для всех вершин, кроме стартовой (=0)
Для Metka=0 найти минимальное значение Curr_dist
Для минимального Curr_dist Metka:=1
Рис. 2.8. Схема работы алгоритма Дейкстры (начало)
165

|
Исходное |
|
Да |
расстояние больше, |
Нет |
|
чем новое (через |
|
|
помеченную |
|
|
вершину) |
|
ВCurr_dist
записываем новое расстояние
ВPred_num записываем эту помеченную вершину
В Curr_dist
оставляем старое расстояние
В Pred_num оставляем номер старой вершины
Все Metka=1
Минимальные расстояния от стартовой вершины записаны в Curr_dist
Рис. 2.8.Схема работы алгоритма Дейкстры (окончание)
ПРИМЕР
Пять булочных небольшого городка обслуживает хлебобулочный комбинат, который, арендуя пять автомобилей, ежедневно поставляет в каждую булочную заказанную продукцию,
166
причем объем продукции всегда соответствует максимальной загрузке автомобиля (таким образом, использование одного авто для попутной доставки в несколько булочных исключается). Специалист отдела логистики лично проехал между всеми этими объектами и занес в таблицу реальное расстояние между i-й и j-й булочными (если между ними есть дорога): т.о. была учтена дорожная ситуация. Найти оптимальный путь от комбината к каждой из булочных. Критерий: минимизация расходов на транспортировку, соответствующих пройденному расстоянию.
В составленной специалистом таблице 2.5. под №6 указан сам хлебобулочный комбинат.
Таблица 2.5. Матрица исходных данных к задаче
|
1 |
2 |
3 |
4 |
5 |
6 |
|
|
|
|
|
|
|
1 |
0 |
5 |
4 |
12 |
1 |
нет |
|
|
|
|
|
|
|
2 |
5 |
0 |
3 |
10 |
6 |
13 |
|
|
|
|
|
|
|
3 |
4 |
3 |
0 |
6 |
13 |
22 |
|
|
|
|
|
|
|
4 |
1 |
8 |
8 |
0 |
6 |
12 |
|
|
|
|
|
|
|
5 |
4 |
9 |
3 |
8 |
0 |
10 |
|
|
|
|
|
|
|
6 |
нет |
13 |
24 |
14 |
20 |
0 |
|
|
|
|
|
|
|
РЕШЕНИЕ ПРИМЕРА
Инициализация:
(i=6, metka[6]=1):
Таблица 2.6. Инициализация исходных данных
№элемента |
1 |
2 |
3 |
4 |
5 |
6 |
Массив Metka |
0 |
0 |
0 |
0 |
0 |
1 |
Массив Pred_num |
6 |
6 |
6 |
6 |
6 |
0 |
Массив Curr_dist |
нет |
13 |
24 |
14 |
20 |
0 |
Общий шаг:
Запускаем цикл от 1 до 5.
167
1. Возьмем наиболее близкую к нужной и еще неотмеченную вершину, это вершина №2 (j=2)
1.1.Пометим ее как рассмотренную metka[2]:=1
1.2.В цикле по k от 1 до 6 сравним d[i,j]+d[j,k] и d[i,k], т.е. в данном случае curr_dist[2]+d[2,k] и curr_dist[k] (иными словами здесь сравнивается кратчайший из известных путей 2 от вершины 6 через вершину №2 к остальным вершинам и прямой путь от вершины №6 к остальным, т.е. на первом шаге тот, что был первоначально записан в матрице D)
при k=1: curr_dist[2]+d[2,1]=13+5=18, |
curr_dist[1]=∞, 18<∞ 18 |
|||||||||||
curr_dist[1]:=18, pred_num[1]:=2 |
|
|
curr_dist [2]=13 никаких |
|||||||||
при k=2: curr_dist [2]+d[2,2]=13+0=13, |
||||||||||||
изменений |
|
|
|
|
|
|
|
|
|
|
|
|
при k=3: curr_dist [2]+d[2,3] =13+3=16, |
curr_dist [3]=24, 16<24 |
|||||||||||
curr_dist[3]:=16, pred_num [3]:=2 |
|
|
|
|
|
|
|
|
||||
при k=4: curr_dist [2]+d[2,4] =13+10=23, |
curr_dist [4]=14 |
|||||||||||
никаких изменений |
|
|
|
|
|
|
|
|
|
|
|
|
при k=5: curr_dist [2]+d[2,5] =13+6=19, |
curr_dist [5]=20, 19<20 |
|||||||||||
curr_dist[5]:=19, pred_num [5]:=2 |
|
|
|
curr_dist [6]=0 никаких |
||||||||
при k=6: curr_dist [2]+d[2,6] =13+13=26, |
||||||||||||
изменений |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
Таблица 2.7. Второй этап решения задачи |
||||||||||
|
№элемента |
1 |
2 |
|
3 |
|
4 |
|
5 |
6 |
|
|
|
Массив Metka |
0 |
1 |
|
0 |
|
0 |
|
0 |
1 |
|
|
|
Массив Pred_num |
2 |
6 |
|
2 |
|
6 |
|
2 |
0 |
|
|
|
Массив Curr_dist |
18 |
13 |
|
16 |
|
14 |
19 |
0 |
|
|
2. Возьмем наименьшую из неотмеченных вершин, это №4 (j=4)
2.1.Пометим ее как рассмотренную metka[4]:=1
2.2.В цикле по k от 1 до 6 сравним curr_dist[4]+d[4,k] и curr_dist[k] (иными словами здесь сравниваются наименьшие из известных путей от вершины 6 через вершину №4 к остальным вершинам и наиболее короткий известный путь от №6 к остальным)
при k=1: curr_dist [4]+d[4,1] =14+1=15, curr_dist [1]=18 curr_dist
[1]:=15, pred_num [1]:=4
168
при k=2: curr_dist [4]+d[4,2] =14+8=22, curr_dist [2]=13 никаких изменений
при k=3: curr_dist [4]+d[4,3] =14+8=22, curr_dist [3]=16 никаких изменений
при k=4: curr_dist [4]+d[4,4] =14+0=14, curr_dist [4]=14 никаких изменений
при k=5: curr_dist [4]+d[4,5] =14+6=20, curr_dist [5]=19 никаких изменений
при k=6: curr_dist [4]+d[4,6] =14+12=26, curr_dist [6]=0 никаких изменений.
Таблица 2.8. Третий этап решения задачи
№элемента |
1 |
2 |
3 |
4 |
5 |
6 |
Массив Metka |
0 |
1 |
0 |
1 |
0 |
1 |
Массив Pred_num |
4 |
6 |
2 |
6 |
2 |
0 |
Массив Curr_dist |
15 |
13 |
16 |
14 |
19 |
0 |
3. Возьмем неотмеченную вершину, теперь это вершина №1 (j=1)
3.1.Пометим ее как рассмотренную metka[1]:=1
3.2.В цикле по k от 1 до 6 сравним curr_dist [1]+d[1,k] и curr_dist
[k] (иными словами здесь сравниваются наименьшие из известных путей от вершины 6 через вершину №1 к остальным вершинам и наиболее короткий известный путь от №6 к остальным)
при k=1: curr_dist [1]+d[1,1] =15+0=15, curr_dist [1]=15 никаких изменений
при k=2: curr_dist [1]+d[1,2] =15+5=20, curr_dist [2]=13 никаких изменений
при k=3: curr_dist [1]+d[1,3] =15+4=19, curr_dist [3]=16 никаких изменений
при k=4: curr_dist [1]+d[1,4] =15+12=27, curr_dist[4]=14 никаких изменений
при k=5: curr_dist [1]+d[1,5] =15+1=16, curr_dist [5]=19 curr_dist
[5]:=16, pred_num [5]:=1
при k=6: curr_dist [1]+d[1,6] =15+∞=∞, curr_dist [6]=0 никаких изменений.
169
Таблица 2.9. Четвертый этап решения задачи
№элемента |
1 |
2 |
3 |
4 |
5 |
6 |
Массив Metka |
1 |
1 |
0 |
1 |
0 |
1 |
Массив Pred_num |
4 |
6 |
2 |
6 |
1 |
0 |
Массив Curr_dist |
15 |
13 |
16 |
14 |
16 |
0 |
4. Возьмем неотмеченную вершину, например №5 (j=5)
4.1.Пометим ее как рассмотренную metka[5]:=1
4.2.В цикле по k от 1 до 6 сравним curr_dist [5]+d[5,k] и curr_dist
[k] (иными словами, здесь сравниваются наименьшие из известных путей от вершины 6 через вершину №5 к остальным вершинам и наиболее короткий известный путь от №6 к остальным)
при k=1: curr_dist [5]+d[5,1] =16+4=20, curr_dist [1]=15 никаких изменений
при k=2: curr_dist [5]+d[5,2] =16+9=25, curr_dist [2]=13 никаких изменений
при k=3: curr_dist [5]+d[5,3] =16+3 =19, curr_dist [3]=16 никаких изменений
при k=4: curr_dist [5]+d[5,4] =16+8=24, curr_dist [4]=14 никаких изменений
при k=5: curr_dist [5]+d[5,5] =16+0=16, curr_dist [5]=16 никаких изменений
при k=6: curr_dist [5]+d[5,6] =16+∞=∞, curr_dist [6]=0 никаких изменений.
Таблица 2.10. Пятый этап решения задачи
№элемента |
1 |
2 |
3 |
4 |
5 |
6 |
Массив Metka |
1 |
1 |
0 |
1 |
1 |
1 |
Массив Pred_num |
4 |
6 |
2 |
6 |
1 |
0 |
Массив Curr_dist |
15 |
13 |
16 |
14 |
16 |
0 |
5. Возьмем последнюю вершину №3 (j=3) 5.1.Пометим ее как рассмотренную metka[3]:=1
5.2. Очевидно, что поскольку в массиве curr_dist путей больше 16 не осталось, тогда как curr_dist[3]=16, то дальнейшее улучшение результата невозможно.
170