Студопедия

КАТЕГОРИИ:


Архитектура-(3434)Астрономия-(809)Биология-(7483)Биотехнологии-(1457)Военное дело-(14632)Высокие технологии-(1363)География-(913)Геология-(1438)Государство-(451)Демография-(1065)Дом-(47672)Журналистика и СМИ-(912)Изобретательство-(14524)Иностранные языки-(4268)Информатика-(17799)Искусство-(1338)История-(13644)Компьютеры-(11121)Косметика-(55)Кулинария-(373)Культура-(8427)Лингвистика-(374)Литература-(1642)Маркетинг-(23702)Математика-(16968)Машиностроение-(1700)Медицина-(12668)Менеджмент-(24684)Механика-(15423)Науковедение-(506)Образование-(11852)Охрана труда-(3308)Педагогика-(5571)Полиграфия-(1312)Политика-(7869)Право-(5454)Приборостроение-(1369)Программирование-(2801)Производство-(97182)Промышленность-(8706)Психология-(18388)Религия-(3217)Связь-(10668)Сельское хозяйство-(299)Социология-(6455)Спорт-(42831)Строительство-(4793)Торговля-(5050)Транспорт-(2929)Туризм-(1568)Физика-(3942)Философия-(17015)Финансы-(26596)Химия-(22929)Экология-(12095)Экономика-(9961)Электроника-(8441)Электротехника-(4623)Энергетика-(12629)Юриспруденция-(1492)Ядерная техника-(1748)

Топологическая сортировка

Поиск в ширину

Идея метода. Суть (в сжатой формулировке) заключается в том, чтобы рассмотреть все вершины, связанные с текущей. Принцип выбора следующей вершины - выбирается та, которая была раньше рассмотрена. Для реализации данного принципа необходима структура данных “очередь”.

Пример. Исходный граф на левом рисунке. На правом рисунке рядом с вершинами в скобках указана очередность просмотра вершин графа.

Приведем процедуру реализации данного метода обхода вершин графа.

Логика просмотра вершин.

procedure PW(v:integer);

var Og:array[1..N] of 0..N; {очередь}

yk1,yk2:integer; {указатели очереди, yk1 - запись; yk2 - чтение}

j:integer;

begin

FillChar(Og,SizeOf(Og),0);yk1:=0;yk2:=0; {начальная инициализация}

Inc(yk1);Og[yk1]:=v;Nnew[v]:=false; {в очередь - вершину v}

while yk2<yk1 do begin {пока очередь не пуста}

Inc(yk2);v:=Og[yk2];write(v:3); {“берем” элемент из очереди}

for j:=1 to N do {просмотр всех вершин, связанных с вершиной v}

if (A[v,j]<>0) and Nnew[j] then begin {если вершина ранее не просмотрена}

Inc(yk1);Og[yk1]:=j;Nnew[j]:=false; {заносим ее в очередь}

end;

end;

end;

 

Нерекурсивный алгоритм топологической сортировки ориентированного графа без циклов.

Предположим, что граф имеет вершины с номерами 1..n, для каждой вершины i известно число num[i] выходящих из нее ребер и номера вершин dest[i][1],..., dest[i][num[i]], в которые эти ребра ведут. Будем условно считать, что ребра перечислены 'слева направо': левее то ребро, у которого номер меньше. Нам надо напечатать все вершины в таком порядке, чтобы конец любого ребра был напечатан перед его началом. Мы предполагаем, что в графе нет ориентированных циклов - иначе такое невозможно.

Для начала добавим к графу вершину 0, из которой ребра ведут в вершины 1,...,n. Если ее удастся напечатать с соблюдением правил, то тем самым все вершины будут напечатаны.

Алгоритм хранит путь, выходящий из нулевой вершины и идущий по ребрам графа. Переменная l отводится для длины этого пути. Путь образован вершинами vert[1],..., vert[l] и ребрами, имеющими номера edge[1]...edge[l]. Номер edge[s] относится к нумерации ребер, выходящих из вершины vert[s]. Тем самым для всех s должны выполняться неравенство

 

edge[ s ] <= num[vert[ s ]]

и равенство

vert[ s +1] = dest [vert[ s ]] [edge[ s ]]

 

Впрочем, для последнего ребра мы сделаем исключение, разрешив ему указывать 'в пустоту', т.е. разрешим edge[l] равняться num[vert[l]]+1.

В процессе работы алгоритм будет печатать номера вершин, при этом соблюдая требование 'вершина напечатана только после тех вершин, в которые из нее ведут ребра'. Наконец, будет выполняться такое требование:

(И) вершины пути, кроме последней (т.е. vert[1]..vert[l]) не напечатаны, но свернув с пути налево, мы немедленно упираемся в напечатанную вершину

Вот что получается:

 

l:=1; vert[1]:=0; edge[1]:=1;

while not ((l=1) and (edge[1]=n+1)) do begin

| if edge[l]=num[vert[l]]+1 then begin

| | {путь кончается в пустоте, поэтому все вершины,

| | следующие за vert[l], напечатаны - можно

| | печатать vert[l]}

| | writeln (vert[l]);

| | l:=l-1; edge[l]:=egde[l]+1;

| end else begin

| | {edge[l] <= num[vert[l]], путь кончается в

| | вершине}

| | lastvert:= dest[vert[l]][edge[l]]; {последняя}

| | if lastvert напечатана then begin

| | | edge[l]:=edge[l]+1;

| | end else begin

| | | l:=l+1; vert[l]:=lastvert; edge[l]:=1;

| | end;

| end;

end;

{путь сразу же ведет в пустоту, поэтому все вершины

левее, то есть 1..n, напечатаны}

Доказательство, что если в графе нет циклов, то этот алгоритм заканчивает работу:

Пусть это не так. Каждая вершина может печататься только один раз, тако что с некоторого момента вершины не печатаются. В графе без циклов длина пути ограничена (вершина не может входить дважды), поэтому подождав еще, мы можем дождаться момента, после которого путь не удлиняется. После этого может разве что увеличиваться edge[l] - но и это не беспредельно.

<== предыдущая лекция | следующая лекция ==>
Поиск в глубину | Climate + Soil ® Plants ® Animals
Поделиться с друзьями:


Дата добавления: 2014-01-11; Просмотров: 466; Нарушение авторских прав?; Мы поможем в написании вашей работы!


Нам важно ваше мнение! Был ли полезен опубликованный материал? Да | Нет



studopedia.su - Студопедия (2013 - 2024) год. Все материалы представленные на сайте исключительно с целью ознакомления читателями и не преследуют коммерческих целей или нарушение авторских прав! Последнее добавление




Генерация страницы за: 0.007 сек.