Разделы
Главная Сапромат Моделирование Взаимодействие Методы Инновации Индукция Исследования Факторизация Частоты
Популярное
Как составляется проект слаботочных сетей? Как защитить объект? Слаботочные системы в проекте «Умный дом» Какой дом надежнее: каркасный или брусовой? Как правильно создавать слаботочные системы? Что такое энергоэффективные дома?
Главная »  Математика 

1 ... 10 11 12 13 14 15 16 ... 28

TypeVertex=array[l..nvertex} of Integer; TypeAdjacent=array[l..nAdjacent] of Integer;

:Text;

{ Текстовый файл }

:Integer;

{ Количество вершин }

:TypeAdj acent;

{ Список смежности графа }

:TypeVertex;

Указатели вершин списка смежности}

:TypeVertex;

Количество вершин в списке

смежности}

:TypeVertex;

Список вершин графа }

Mark

:TypeVertex;

Номера компонент для вершин графа 5

Procedure Var yes :Boolean );

{ Переназначение меток вершин }

{ их порядковыми номерами в списке смежности } { yes - признак правильной структуры списка смежности } Var

i,j,m :Integer;

begin

for i:=l to n do

for j:=l to Nbr[i] do begin yes:=FALSE; for m: - = 1 to n do

if Adj[Fst[i]+j]=Vtx[m] then begin yes:=TRUE; Adj [Fst [i]+j] :=m; break-end;

if not yes then exit; end;

end;

Procedure

i,v : Integer; begin

Mark[x]:=count;

Алгоритм 6.4. Программа выделения связных компонент неориентированного графа Program {Выделение компонент

связности графа}

uses CRT,DOS; Const

nVertex-100; {Максимальное количество вершин} nAdjacent=1000; {Максимальная длина списка смежности}



for i:=l to Nbr[x] do begin v:=Adj[Fst[x]+i];

if then

end end;

Procedure Connect; (Выделение компонент связности}

v,count :Integer;

begin

for v:=l to n do Markfv]:=0;

count:=0; {Номер компоненты связности}

for v:=l to n do begin

if Mark[v]=0 then begin count:=count+l; Component(v,count) ;

end; end;

end;

Var {Main)

i, j :Integer; yes :Boolean; begin {Main}

Assign(f,Connect.in ) ; Reset (f) ; (Фай, открыт для чтения) { Ввод списка смежности } Read(f,n); {Количестве строк в списке) Fst[1]:=0; {Указатель начала первой строки списка) for i: =1 to n do begin

Read(f,Vtx[i]); { Метка вершины)

Read{f,Nbr[i]); { Количество вершин в списке)

for j:=l to Nbrfi] do Read (f, Adj [ Fst [ i]+j ]) ;

{ Список смежных вершин) Fst [i+1] :=Fst[i]+Nbr[i];{Указатель начала следующей

строки в

end;

Close(f);

Assign(f,Connect.out);

Rewrite(f); {Файл открыт для записи) Init(yes);

if not yes then begin

WriteLn(f, Плохая структура смежности графа!);

Close(f);

exit ; end;

5-2697



Connect;

for i:=l to n do Write(f,Vtx[i]:3); Writeln(f); for i:=l to n do Write(f,Mark[i]:3) ; Close (f) ; end. {Main}

6.7. Эйлеровы графы

Классической в теории графов является следующая задача. Имеются два острова, соединенньгх семью мостами с берегами реки и друг с другом, как показано на рис. 6.15. Задача состоит в следующем: осуществить прогулку по городу таким образом, чтобы, пройдя по каждому мосту один раз, вернуться обратно. Решение этой задачи сводится к нахождению некоторого специального маршрута на графе.


Рис. 6.15. План расположения мостов и соответствующий ему мультиграф

Определение. Пусть/= (X, Ф) - неориентированный псевдограф. Цепь в Г называется эйлеровой, если она проходит по одному разу через каждое ребро псевдографа Г. Такой граф называется эйлеровым. Замкнутая эйлерова цепь называется

эйлеровым циклом.

Поставим в соответствие плану расположения суши и мостов, приведенному на рис. мультиграф на рис. в котором

каждой части суши соответствует вершина, а каждому мосту - ребро, соединяющее соответствующие вершины. Теперь задача звучит так: найти эйлерову цепь (цикл) в мультиграфе. Решение этой задачи было дано Л. Эйлером.

Теорема Л. Эйлера. Эйлерова цепь в псевдографе Г= (X, U, Ф) существует тогда и только тогда, когда выполняются следующие условия:

1. Граф связный;

2. Степени внутренних вершин четные (внутренние вершины не являются началом и концом



3. Если вершины а и Ъ являются началом и концом цепи и а Ь, то степени их нечетные;

4. Если вершины а и b являются началом и концом цепи и a =b, то степени их четные.

Доказательство. (=>) Дано, что существует эйлерова цепь auhx2u2...xnunb, где а, b, xs е X, и, е U, в которрй содержатся все ребра по одному разу. Такая цепь включает все вершины графа, если граф не содержит изолированных вершин. Докажем условия 1) по данной цепи из любой вершины можно попасть в любую другую, значит, граф связный; 2) каждая тройка цепи Щ хх(щ привносит вершине л:,- степень два, а так как все ребра и, в цепи различные, то степени внутренних вершин четные; 3) и 4) доказательства повторяют доказательство пункта 2.

( =) Даны условия 1-4. Построим эйлерову цепь. Предварительно приведем условие 3 к условию 4 включением в граф фиктивного ребра которым свяжем вершины а и Теперь и в случае 3 все вершины будут иметь четную степень. Пусть А е X- произвольная вершина (рис. 6.16). Из нее будем строить цепь, выбирая в качестве продолжения пути ребро, которое еще не пройдено. Эта цепь (цикл может закончиться только в вершине А, та к как, при входе в любую другую вершину, всегда существует ребро, по которому можно выйти из нее (степени вершин

Возможны два случая: 1) построенный цикл Гг содержит все ребра графа, тогда теорема доказана; 2) содержит не все ребра графа. Во втором случае рассмотрим граф Г \ /полученный удалением из всех ребер, входящих в . Граф Г \ вновь содержит вершины только с четными степенями (у каждой вершины удалили по четному числу Так как Г- связный граф, то существует вершина в , инцидентная ребру из Г \Гу. Пусть это вершина В X. Построим из нее цикл так же, как строили цикл I]. Построим общий цикл из и так, как это сделано на рис. Для вновь проверяем рассмотренные выше два случая, как для /


Рис. 6.16. Объединение двух циклов в один цикл



Процесс расширения продолжаем до тех пор, пока не будут включены все ребра графа в один цикл: Аи{х2...аи*Ь...и„А. Разрывая данный цикл по ребру и*, получим эйлерову цепь flwi/2.,./ w £, где tj s X, w,e U.

Конструкта вный характер доказательства теоремы позволяет на формальном уровне в алгоритме 6.5 записать рассмотренный поиск эйлеровой цепи. Исходный граф представлен своей структурой смежностиЛфх] где - множество вершин, смежных е X.

Результирующая эйлерова цепь формируется в множестве Z.

Алгоритм 6.5. Алгоритм поиска эйлеровой цепи графа

3v is X; {Вершина начала эйлеровой цепи)

Z- М; {Начало строящейся эйлеровой цепи}

R = 0; {Частныйрасширяющийся цикл эйлеровой цепи}

repeat

Cycle(v, R);

Z=ZR, {Объединениециклов в один цикл) until Not 3ve Z \AdJM\> 0

Procedure Cycle(v, R)

R= {v}; {Построениеотдельного цикла эйлеровой цепи) repeat

w = Adj[v]; R=Rv{w};

Adj[v]=Adj[v]\ {w}; {Удалить пройденное ребро (v, w) } . ifv*wthen Adj[w] = Adj[w]\ {v}; {Удалитьpe6po(v, w) }

v =w;

until Not \Adj[v]\> 0; {Пока все ребра не пройдены} end;

Частные же циклы, расширяющие Z, представляются множеством R. Ребра, включенные в частный цикл R (а значит, и в Z), удаляются как пройденные из структуры смежности Adj[x] (из графа). Формирование расширяющих циклов R осуществляется до тех пор, пока структура смежности графа содержит хотя бы

одно ребро.

Сложность алгоритма поиска эйлеровой цепи. Число обращений к процедуре Cycle не более, чем число вершин При каждом обращении количество производимых действий пропорционально числу ребер, входящих в выделенный цикл. Сложность суммарной работы процедуры Cycle пропорциона-



льна количеству ребер £/вграфе. Поэтому сложность выделения эйлеровой цепи составляет 0(\Х\ + \U\). Программная реализация поиска эйлеровой цепи представлена в алгоритме 6.6, который соответствует множественному описанию соответствующего алгоритма 6.5.

Алгоритм 6.6. Программе поиска эшеровой цепи графа

Program EilerWay; {Эйлерова цепь в псевдографе}

uses CRT,DOS;

Const

nVertex=100; {Максимальное количество вершин) nAdjacent 1000; /Максимальная длина списка смежности) Туре

TypeVertex=array[1..nVertex] of Integer; TypeAdjacent=array[1..nAdjacent] of Integer;

f :Text; { Текстовый файл }

ks : Integer; { Начальная вершина эйлеровой цепи }

n :Integer; { Количество вершин }

Adj :TypeAdjacent; { Список смежности графа }

Fst :TypeVertex; { Указатели вершин списка смежности)

Nbr :TypeVertex; { Количество вершин в списке

смежности } Vtx :TypeVertex; { Список вершин графа } Deg :TypeVertex; { Степени вершин графа } kz :Integer; { Количество вершин в эйлеровой цепи) z :TypeAdjacent;{ Последовательность вершин

эйлеровой цепи } г :TypeAdjacent;{ Отдельный расширяющийся цикл }

Procedure Var yes :Boolean );

i,j,k,m :Integer;

begin

{ Переназначение меток вершин }

{ их порядковыми номерами в списке смежности }

{ yes - признак правильной структуры списка смежности }

for i:=l to n do

for j:=l to Nbr[i] do begin yes:=FALSE; for m:=l to n do

if Adj [Fst[i]+j]=vtx[m] then begin yes:=TRUE; Adj[Fst[i]+j]:=m;



break;

end;

if not yes then expend;

{ Разместить петли в начале списка смежности } for i:=l to n do begin k:=l;

for j:=l to Nbr[i] do if Adj[Fst[i]+j]=i then begin

Adj[Fst[i]+j]:=Adj [Fst[i]+k];

Adj[Fst[i]+k]:=i;

k:=k+l; end;

end;

{ Степени вершин графа )

for i:=l to n do begin

Deg[i]:=0;

for to do begin

Deg[i]:=Deg[i]+l;

if then

end; end;

( Поиск начальной вершины ks цепи } k:=0; ks:=l;

for i:=l to n do if ( Deg[i] mod 2 ) > 0 then begin

k:=k+l; ks:=i; end;

if ( k<>2 ) and ( k<>0 ) then yes:-FALSE;

{ Граф не эйлеровый }

end;

Procedure v : .ntege .. var count : Integer );

{ Построение частной эйлеровой цепи г[ ] } Var

w :Integer;

i,j :Integer;

begin

count:=l; r[count]:=v;

repeat

w:=Adj[Fst[v]+1]; { Следующая вершина цепи > count:=count+l; r[count]:=w;

{ Удалить ребро (v,w) из списка смежности

для вершины v } Fst[v]:=Fst[v]+1; Nbr[v]:=Nbr[v]-1;



{ Если ребро (w,v) не петля, то удалить и его

из списка для вершины w } if vow then

for i:=l to Nbr[w] do if Adj [Fst [w]+i] =v then begin for j:=i+l to Nbr[w] do

Adj[Fst[w]+j-l] :=Adj [Fst[w]+j] ; Nbr[w]:=Nbr[w]-1; break; end; v: =w;

until Not( Mbrlvj>0 i; end;

Procedure { Построение эйлеровой цепи }

v,w :Integer;

i,j,kt ;Integer; count :Integer; yes :Boolean;

begin

v:=ks; kz:=l;

kt:=kz; z[kz]:=v;

Write (f,); {До объединения}

for i:=l to kz do Write(f,Vtx[z[i]]:3); WriteLn(f); repeat

Cycle(v,count) ;

Write(f, R= ) ;

for i:=l to count do

WriteLn(f) ;

for i:=l to count-1 do begin

z[kz+i]:=z[kt+i];

z[kt+i]:=r[i+1] ; end;

kz:=kz+count-l;

Write

for i:=l to kz do Write(f,Vtx[z[i]]:3); WriteLn(f); yes:=FALSE;

for i:=kz downto 1 do if Nbr[z[i]]>0 then begin v : = z [ i J ; kt:=i; yes:=TRUE; break; end; until Not yes; end;



Var (Main)

i, j :Integer; yes :Boolean; begin {Main}

Assign(f,Eiler.in);

Reset (f) ; {Фай.1 открыт для чтения}

{ Ввод списка смежности }

Read(f,n); (Количество строк в списке}

Fst[1]:-0; {Указате.щ начала первой строки списка}

for i:=l to n do begin

Read (f, Vtx [i] ) ; {Метка вершины}

Read(£,Nbr[i) ) ; {Количестве вершин в списке)

for j:=l to Nbr[i] do Read (f, Adj [ Fst [ i ]+j ].) ;

{Список смежных вершин} Fst[i+1]:=Fst[i]+Nbr[i];{Указатель начала следующей

строки в

end;

Close(f);

Assignff, Eiler.out);

открыт для

Init(yes) ;

if not yes then begin

WriteLn(f, Плохая структура смежности графа'); WriteLn(f, или граф не эйлеровый!); Close(f) ; exit;

end;

Eiler;

Write(f, 0=)

for i:=l to kz do Write(f,Vtx[z[i] ]:3) ; WriteLn(f); Close (f); end. (Main)

Рассмотрим пример расчета по программе алгоритма 6.6 поиска эйлеровой цепи в графе, изображенного на рис. 6.17.

--1

Рис. 6.17. Пример расчета эйлеровой цепи графа



Для программы алгоритма 6.6 исходные данные структуры смежности графа на рис. 6.17 задаются в текстовом файле Eiler.in. Структура (правило) заполнения файла совпадает с той, которая описана в рассмотренном примере поиска в глубину при расчете по программе алгоритма 6.2.

Данные файла ЕИег.гпдля примера на рис. 6.17:

14 2 3

2 4 13

3 4 12

4 4 15

5 4 14

6 2 2 5

7 2 2 3

8 2 3 4

9 2 4 5

Результаты расчетов сохраняются в выходном файле Eiler.out со следующей структурой:

Z= 1

R = 1231451 Z = 1231451 R= 562738495

Z = 123145627384951 0 = 123145627384 951.

На каждом шаге показана строящаяся эйлерова цепь Z, которая расширяется выделенным R циклом. Результирующая эйлерова цепь графа отмечена признаком О в начале строки.

6.8. Остовные деревья

Определение. Остовиым деревом связного неориентированного графа (X, U, Ф) называется дерево = (X, U0, Ф) , являющееся подграфом графа Г и содержащее все его вершины (рис. 6.18).


Рис. 6.18. Связный граф и два остовных дерева





1 ... 10 11 12 13 14 15 16 ... 28