Ребра (ac) (cb) (bd) (da) образуютконтур. Минимальный вес ребра в контуре 2.
Стягиваем контур в одну вершину и рассматриваем граф:
Рисунок 3.14 – Граф
l(fe)=1
l(e, Vo)=l(ea)+2–3=3+2–3=2
l (f, Vo)=l (f, a)+2–3=-1
l (f, Vo) 1=l(fd)+2‑l (b, d)=1+2–2=1
Просмотр вершин Букет ребер
e (fe)
f (fe)
Vo (fe) (eVo)
Получили множество ребер исходного графа Go такое:
(fe) (ea) – образуют букет
(ac) (cb) (bd) (da) – образуют контур
Vo не является контуром дерева, удаляем (da), поскольку (da) – ребро из контура. Получили дерево:
(fe) (ea) (ac) (cb) (bd) с весом l=1+2+3+2+2=10
Задача о кратчайших путях
Пусть G – ориентированный граф, Е – ребра графа. Каждому ребру соответствует число.
Рисунок 3.15 – Эйлеров цикл
Задача Эйлера о Кенигсбергских мостах [19]: необходимо выйти из любой точки города и вернуться в нее, при этом пройдя по каждому мосту только один раз. Эйлер свел эту задачу к графу: существует ли в конечном графе такой цикл, в котором каждое ребро участвует только один раз? Цикл, в котором каждое ребро графа G участвует всего один раз, называется эйлеровым циклом. Граф, содержащий эйлеров цикл, называется эйлеровым.
Дальнейшее развитие задачи об Эйлеровом цикле
Припишем ребрам графа длину μ (ai, aj). Требуется найти путь в графе, который проходит через все ребра и имеет наименьшую длину.
Пример.
Рисунок 3.16 – Граф
S – стартовая вершина. Из вершины S надо пройти по всем ребрам так, чтобы маршрут имел минимальную длину. Очевидно, что длина маршрута будет минимальной, если каждое ребро будет пройдено всего один раз – т. е. маршрут будет эйлеровым циклом.
Все локальные степени – четные, значит граф эйлеров.
Варианты прохождения по циклу:
1) (sa) (ab) (bc) (cd) (db) (ds)
2) (sa) (ab) (bd) (dc) (cb) (bs)
3) (sb) (bc) (cd) (db) (ba) (as)
4) (sb) (bd) (dc) (cb) (ba) (as)
Длина эйлерова цикла – 22. Любой из вариантов 1–4 содержит каждое ребро графа, следовательно, длина одинакова для всех циклов 1–4. Длина эйлерова цикла не зависит от того, какая вершина будет выбрана за исходную.
Задача поиска эйлерова цикла – это задача о: – поиске наилучшего способа прохождения бригады по дорогам; – прохождении с/х техники по полям.
Впервые эта задача рассматривалась в связи с нахождением оптимального маршрута следования почтальона, который доставляет письма своим адресатам и должен при этом пройти минимальный путь.
Алгоритм нахождения эйлерова цикла для неориентированного графа [19]:
Дан эйлеров граф – т. е. граф с четными локальными степенями.
Найдем первое ребро х, инцидентное вершине S. Затем найдем ребро, смежное с ребром х, которое не образует цикл и еще не было использовано. Продолжим этот процесс до тех пор, пока не вернемся в вершину S. Если в построенный цикл С1 вошли все ребра графа – задача решена.
Если в построенный цикл С1 вошли не все ребра – строим цикл С2, состоящий из неиспользованных ребер и начинающийся с произвольного неиспользованного ребра.
Таким образом, строим циклы С2, С3,….Образование циклов продолжается до тех пор, пока не будут использованы все ребра.
Все циклы Сi необходимо объединить в один цикл. Условие объединения циклов С1 и С2 – наличие у них общей вершины х. Начинаем движение с любой вершины и двигаемся по циклу С1 до тех пор, пока не дойдем до х. Затем проходим ребро. С» и возвращаемся в х. Продолжаем обход по оставшимся ребрам до возвращения к исходной точке. Эта процедура легко обобщается на случай любого числа объединяемых циклов.
Циклы Эйлера для ориентированного графа
Алгоритм построения эйлерова цикла в эйлеровом ориентированном графе является аналогом алгоритма построения эйлерова цикла для неориентированного графа.
Строятся циклы Сi с учетом ориентации ребер, и затем все циклы объединяются в один.
Гамильтонов цикл (задача о коммивояжере)
Простой цикл, проходящий через каждую вершину графа только один раз, называется гамильтоновым циклом.
Если ребрам приписана длина, то различные варианты циклов отличаются друг от друга. Поэтому ставится задача нахождения гамильтонова цикла, имеющего минимальную длину.
Гамильтонов цикл наименьшей длины называется оптимальным гамильтоновым циклом (ОГЦ)
Поиск оптимального гамильтонова цикла – задача о коммивояжере, который должен посетить множество пунктов и вернуться домой, пройдя наименьший путь.
Решением задачи о коммивояжере не всегда является ОГЦ.
Гамильтоновы графы применяются для моделирования многих практических задач. Графическая модель задачи коммивояжера состоит из гамильтонова графа, вершины которого изображают города, а ребра – связывающие их дороги. Кроме того, каждое ребро оснащено весом, обозначающим транспортные затраты, необходимые для путешествия по соответствующей дороге, например, расстояние между городами или время движения по дороге. Для решения задачи нам необходимо найти гамильтонов цикл минимального общего веса.
Рисунок 3.17 – Ребра, входящие в гамильтонов цикл С
К сожалению, алгоритм решения данной задачи, дающий оптимальное решение, пока не известен. Для сложных сетей число гамильтоновых циклов, которые необходимо просмотреть для выделения минимального, непомерно огромно. Однако существуют алгоритмы поиска субоптимального решения [1]. Субоптимальное решение необязательно даст цикл минимального общего веса, но найденный цикл будет, как правило, значительно меньшего веса, чем большинство произвольных гамильтоновых циклов! Один из таких алгоритмов – алгоритм ближайшего соседа.
Этот алгоритм выдает субоптимальное решение задачи коммивояжера, генерируя гамильтоновы циклы в нагруженном графе с множеством вершин V. Цикл, полученный в результате работы алгоритма, будет совпадать с конечным значением переменной маршрут, а его общая длина – конечное значение переменной w.
begin
Выбрать v € V;
маршрут:=v;
w:=0;
v':=v;
Отметить v';
while остаются неотмеченные вершины do begin
Выбрать неотмеченную вершину и,
ближайшую к v';
маршрут:= маршрут u;
w:= w + вес ребра v'u;
v':=u;
Отметить v';
end
маршрут:= маршрут v;
w:= w + вес ребра v'v;
end
Пример. Примените алгоритм ближайшего соседа к графу, изображенному на рисунке 3.18. За исходную вершину возьмите вершину D.
Рисунок 3.18 – Граф
Таблица 3.2 – Алгоритм ближайшего соседа
и | маршрут | w | v' | |
Исходные значения | – | D | 0 | D |
С | dc | 3 | С | |
А | DCA | 9 | A | |
В | DCAB | 14 | В | |
Последний проход | В | DCABD | 24 | В |
В результате работы алгоритма был найден гамильтонов цикл DCABD общего веса 24. Делая полный перебор всех циклов в этом маленьком графе, можно обнаружить еще два других гамильтоновых цикла: ABCDA общего веса 23 и ACBDA общего веса 31. В полном графе с двадцатью вершинами существует приблизительно 6,1 * 10^16 гамильтоновых циклов, перечисление которых требует чрезвычайно много машинной памяти и времени.
Реализация примера данного алгоритма в Delphi:
procedure TForm1. Button1Click (Sender: TObject);
const mat:array [1.. 4,1..4] of byte=((0,5,6,8), (5,0,7,10), (6,7,0,3), (8,10,3,0));
Versh:array [1..4] of char=('a', 'b', 'c', 'd');
buk:char='d';
Type t=set of 'a'..'d';
Var dlina, i, j, min, n, k, s:byte;
put:string;
z:t;
begin
dlina:=0;
Memo1. Lines. Clear;
for i:=1 to 4 do if versh[i]=buk then begin n:=i; s:=i;
include (z, buk);
put:=put+buk;
end;
for j:=1 to 3 do begin
if mat [n, 1]<>0 then begin min:=mat [n, 1]; k:=1; end
else begin min:=mat [n, 2]; k:=2; end;
for i:=1 to 4 do
if (mat [n, i]<min) and (mat [n, i]<>0) and (not (versh[i] in z)) then begin
min:=mat [n, i];
k:=i;
end;
dlina:=dlina+min;
put:=put+versh[k];
include (z, versh[k]);
n:=k;
end;
put:=put+'d';
dlina:=dlina+mat [k, s];
Memo1. Lines. Add ('маршрут:'+' '+put);
Memo1. Lines. Add ('длинамаршрута='+IntToStr(dlina));
end;
end.
Рисунок 3.19 – Форма с результатом
3.2.1 Задание к работе
1 изучить теоретический материал по методическому пособию [24], лекциям и записям на практических занятиях;
2 получить задание по индивидуальному варианту в виде графа или матрицы смежности, в первом случае построить матрицу смежности, во втором – нарисовать граф;
3 составить подробное описание графа: ориентированный или неориентированный, количество вершин, дуг (рёбер), содержит ли циклы и какие, найти степени вершин, количество компонент связности и т. д.;
4 создать приложение на Delphi для расчёта матрицы инцидентности по известной матрице смежности (если граф достаточно сложный, то можно взять подграф этого графа);
5 в качестве дополнительного творческого задания создать приложение на Delphi для реализации алгоритма ближайшего соседа, алгоритма Прима, алгоритма Уоршелла, алгоритма Дейкстры, алгоритма определения количества компонент связности графа и других известных алгоритмов на графах. [13], [17], [18], [19], [20], [21].
Пример 1: По заданной матрице смежности построить матрицу инцидентности.
implementation
procedure TForm1. UpDown1Click (Sender: TObject; Button: TUDBtnType);