Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
Информатика - шпоры.doc
Скачиваний:
0
Добавлен:
01.05.2025
Размер:
135.68 Кб
Скачать

35. Алгоритм обхода вершин графа "в ширину".

При решении многих графовых задач возникает необходимость систематического перебора вершин графа. Это означает, что ни одна вершина не должна быть пропущена и не должна рассматриваться (посещаться) дважды.

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

Девизом этого алгоритма обхода можно объявить фразу: «Не удалять подысходные вершины, пока не рассмотрены все ближние вершины по отношению к исходной». При обходе в глубину чем позже посещалась вершина (переставала быть новой), тем раньше она становилась использованной (переставали быть новыми все ее соседи). иными словами при обходе в глубину каждая просмотренная вершина помещается в стек, а каждая использованная вершина удаляется из стека. обход в ширину основывается на замене стека для просмотренных вершин очередью, в которой записаны все просмотренные вершины (не новые), а из очереди удаляются использованные.

Чем раньше просмотрена некоторая вершина, тем раньше она становится использованной, благодаря тому, что после просмотра очередной вершины, все ее новые соседи записываются в конец очереди. Тем самым гарантируется, что они наверняка будут просмотрены, т.е. перестанут быть новыми, поэтому только что просмотренную вершину можно сразу объявить использованной и удалять из очереди.

Очевидное свойство: если отыскивается путь от исходной вершины до некоторой заданной, то когда дойдет очередь до просмотра этой заданной конечной вершины, можно утверждать, что найденный путь к ней является кратчайшим (т.к. все более близкие вершины были рассмотрены раньше).

Алгоритм:

1. Начало. Поиск начинается с некоторой заданной вершины v0. Она вносится в пустую очередь и рассматривается. Затенм в конец очереди вписываются все ее соседи, а сама исходная вершина объхявляется использованной и удаляется из очереди.

2. Общий шаг. Рассматривается первая в данный момент в очереди вершина, а все ее новые соседи записываются в конец очереди. Т.о. неучтенных новых соседей у нее не остается и следовательно ее можно считать использованной и удалить из очереди.

3. Конец. Поиск заканчивается, когда а) будет рассмотрена заданная конечная вершина и следовательно определен путь к ней, или, б) когда в очереди не останется ни одной вершины. Следовательно все вершины графа рассмотрены.

Запишем алгоритм на условном Паскале. Будем использовать операции:

1) создание очереди

2) очередь пуста – логическая функция

3) Первый – доступ к первому (функция)

4) в очередь (u) – процедура

5) из очереди – процедура

Признаки новизны вершины хранятся в логическом массиве

НОВАЯ: Array[v] of Boolean

Будем использовать цепные списки соседних вершин для каждой вершины графа

Соседи: Array[v] of P_Spisok;

Procedure В_ширину(v:V);

Begin

Создание_очереди;

В_очередь(v); НОВАЯ[v]:=False;

While Not Oч_пуста Do

Begin

P:=первый;

Из_очереди;

Обработка (р);

For u Соседи[p] Do

If НОВАЯ[u] Then

Begin

В_очередь(u);

НОВАЯ[u]:= False;

End; end; end;

Основная программа, которая использует процедуру В_ширину для просмотра всех вершин графа имеет вид:

Begin

{инициализация}

For v V Do НОВАЯ[v]:= True;

{обход}

For v V Do

If НОВАЯ[v] Then

Begin

Inc(k);

В_ширину(v);

End;

End.

Второй цикл по перебору всех вершин графа нужен в связи с тем что один запуск процедуры в_ширину позволяет просмотреть все вершины в пределах 1 компоненты связности. Если граф состоит из нескольких компонент связи, то процедуру В_ширину нужно запустить для каждой из этих компонент связности. Следовательно, этот алгоритм как и алгоритм В_глубину можно применять для подсчета компонент связности в заданном графе.