- •Содержание
- •Введение
- •Задача коммивояжера
- •Общее описание
- •1.2. Методы решения зк
- •1.2.1. Жадный алгоритм
- •1.2.2. Деревянный алгоритм.
- •1.2.3. Метод ветвей и границ
- •1.2.4. Алгоритм Дейкстры
- •Алгоритм Дейкстры
- •1.2.5. Мой метод (метод Анищенко) решения задачи коммивояжера
- •1.2.6. Анализ методов решения задачи коммивояжера
- •1.3 Практическое применение задачи коммивояжера
- •Литература
1.2.4. Алгоритм Дейкстры
Одним из вариантов решения ЗК является вариант нахождения кратчайшей цепи, содержащей все города. Затем полученная цепь дополняется начальным городом – получается искомый тур.
Можно предложить много процедур решения этой задачи, например, физическое моделирование. На плоской доске рисуется карта местности, в города, лежащие на развилке дорог, вбиваются гвозди, на каждый гвоздь надевается кольцо, дороги укладываются верёвками, которые привязываются к соответствующим кольцам. Чтобы найти кратчайшее расстояние между i и k, нужно взять I в одну руку и k в другую и растянуть. Те верёвки, которые натянутся и не дадут разводить руки шире и образуют кратчайший путь между i и k. Однако математическая процедура, которая промоделирует эту физическую, выглядит очень сложно. Известны алгоритмы попроще. Один из них – алгоритм Дейкстры, предложенный Дейкстрой ещё в 1959г. Этот алгоритм решает общую задачу:
В ориентированной, неориентированной или смешанной (т. е. такой, где часть дорог имеет одностороннее движение) сети найти кратчайший путь между двумя заданными вершинами.
Алгоритм использует три массива из n (= числу вершин сети) чисел каждый. Первый массив a содержит метки с двумя значениями: 0 (вершина ещё не рассмотрена) и 1 (вершина уже рассмотрена); второй массив b содержит расстояния – текущие кратчайшие расстояния от vi до соответствующей вершины; третий массив c содержит номера вершин – k-й элемент ck есть номер предпоследней вершины на текущем кратчайшем пути из vi в vk. Матрица расстояний Dik задаёт длины дуг dik; если такой дуги нет, то dik присваивается большое число Б, равное «машинной бесконечности».
Теперь можно описать:
Алгоритм Дейкстры
1(инициализация).
В цикле от одного до n заполнить нулями массив а; заполнить числом i массив с: перенести i-тую строку матрицы D в массив b;
a[i]:=1; c[i]:=0; {i-номер стартовой вершины}
2(общий шаг).
Найти минимум среди неотмеченных (т. е. тех k, для которых a[k]=0); пусть минимум достигается на индексе j, т. е. bjbk; a[j]:=1;
0 |
23 |
12 |
∞ |
∞ |
∞ |
∞ |
∞ |
23 |
0 |
25 |
∞ |
22 |
∞ |
∞ |
35 |
12 |
25 |
0 |
18 |
∞ |
∞ |
∞ |
∞ |
∞ |
∞ |
18 |
0 |
∞ |
20 |
∞ |
∞ |
∞ |
22 |
∞ |
∞ |
0 |
23 |
14 |
∞ |
∞ |
∞ |
∞ |
20 |
23 |
0 |
24 |
∞ |
∞ |
∞ |
∞ |
∞ |
14 |
24 |
0 |
16 |
∞ |
35 |
∞ |
∞ |
∞ |
∞ |
16 |
0 |
табл. 12 |
3(выдача ответа).
{Путь vi..vk выдаётся в обратном порядке следующей процедурой:}
3.1. z:=c[k];
3.2. Выдать z;
3.3. z:=c[z]; Если z = 0, то конец, иначе перейти к 3.2.
Для выполнения алгоритма нужно n раз просмотреть массив b из n элементов, т. е. алгоритм Дейкстры имеет квадратичную сложность. Проиллюстрируем работу алгоритма Дейкстры численным примером (для большей сложности, считаем, что некоторые города (вершины) i,j не соединены между собой, т. е. D[i,j]=∞). Пусть, например, i=3. Требуется найти кратчайшие пути из вершины 3. Содержимое массивов a,b,c после выполнения первого пункта показано на табл. 12:
|
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
a |
0 |
0 |
1 |
0 |
0 |
0 |
0 |
0 |
b |
12 |
25 |
0 |
18 |
∞ |
∞ |
∞ |
∞ |
c |
3 |
3 |
0 |
3 |
3 |
3 |
3 |
3 |
табл. 13 |
Очевидно, содержимое таблицы меняется по мере выполнения общего шага. Это видно из следующей таблицы:
|
|
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
min bk=12 |
a |
1 |
0 |
1 |
0 |
0 |
0 |
0 |
0 |
b |
12 |
25 |
0 |
18 |
∞ |
∞ |
∞ |
∞ | |
c |
3 |
3 |
0 |
3 |
3 |
3 |
3 |
3 | |
min bk=18 |
a |
1 |
0 |
1 |
1 |
0 |
0 |
0 |
0 |
b |
12 |
25 |
0 |
18 |
∞ |
38 |
∞ |
∞ | |
c |
3 |
3 |
0 |
3 |
3 |
4 |
3 |
3 | |
min bk=25 |
a |
1 |
1 |
1 |
1 |
0 |
0 |
0 |
0 |
b |
12 |
25 |
0 |
18 |
47 |
38 |
∞ |
60 | |
c |
3 |
3 |
0 |
3 |
2 |
4 |
3 |
2 | |
min bk=38 |
a |
1 |
1 |
1 |
1 |
0 |
1 |
0 |
0 |
b |
12 |
25 |
0 |
18 |
47 |
38 |
62 |
60 | |
c |
3 |
3 |
0 |
3 |
2 |
4 |
6 |
2 | |
min bk=47 |
a |
1 |
1 |
1 |
1 |
1 |
1 |
0 |
0 |
b |
12 |
25 |
0 |
18 |
47 |
38 |
61 |
60 | |
c |
3 |
3 |
0 |
3 |
2 |
4 |
5 |
2 | |
min bk=60 |
a |
1 |
1 |
1 |
1 |
1 |
1 |
0 |
1 |
b |
12 |
25 |
0 |
18 |
47 |
38 |
61 |
60 | |
c |
3 |
3 |
0 |
3 |
2 |
4 |
5 |
2 |
Возьмём произвольную пару вершин
j,k. Исключим непосредственное ребро C[j,k]. С помощью алгоритма Дейкстры найдём кратчайшее расстояние между городами j..k. Пусть это расстояние включает некоторый город m. Имеем часть тура j,m,k. Теперь для каждой пары соседних городов (в данном примере – для j,m и m,k) удалим соответственное ребро и найдём кратчайшее расстояние. При этом в кратчайшее расстояние не должен входить уже использованный город.
Далее аналогично находим кратчайшее расстояние между парами вершин алгоритмом Дейкстры, до тех пор, пока все вершины не будут задействованы. Соединим последнюю вершину с первой и получим тур. Чаще всего это последнее ребро оказывается очень большим, и тур получается с погрешностью, однако алгоритм Дейкстры можно отнести к приближённым алгоритмам.