Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
Komb_1.doc
Скачиваний:
3
Добавлен:
16.09.2019
Размер:
458.24 Кб
Скачать

1.3.Поиск в ширину в графе

Рассмотрим несколько иной метод поиска в графе, называемый поиском в ширину (breadth first search). Предварительно необходимо отметить, что при поиске в глубину чем позднее будет посещена вершина, тем раньше она будет использована. Это справедливо при условии, что вторая вершина посещается перед использованием первой. Это следствие того факта, что просмотренные, но еще не использованные вершины скапливаются в стеке. Поиск в ширину основывается на замене стека очередью. После такой модификации чем раньше посещается вершина (помещается в очередь), тем раньше она используется (удаляется из очереди). Использование вершины происходит с помощью просмотра сразу всех еще не просмотренных соседей этой вершины. Введем абстрактный тип очереди.

intqueue = data type is q_new, q_isempty, q_append, q_remfirst

Описание

Типы данных intqueue используются для хранения значений типа целого числа. Элементы могут извлекаться из очереди или удаляться из нее только по методу FIFO (First Input-First Output)

Операции

function q_new:intqueue

effects Возвращает новую очередь без элементов в ней

function q_isempty (q:intqueue): boolean

effects Возвращает значение true, если в очереди q нет элементов, в противном случае возвращает значение false

procedure q_append (q:intqueue; e:integer)

modifies q

effects Добавляет элемент e в конец очереди q

function q_remfirst (q:intqueue): integer

requires чтобы очередь q не была пустой

modifies q

effects Возвращает элемент из начала очереди q и удаляет этот элемент из очереди q

end intqueue

Рис.1.11.Спецификация абстракции данных для очереди целых чисел.

Теперь процедура поиска в ширину примет вид.

WS = proc (v: int; g: graph; НОВЫЙ: array of bool)

modifies НОВЫЙ

effects 1. q = intqueue.q_new

2. intqueue.q_append(q,v)

3. НОВЫЙ[v] = false

4. пока not(intqueue.q_isempty(q)) выполнять

4.1. p = intqueue.q_remfirst(q); c = graph.fetch(g,p); i = circ.size(c)

4.2. пока i > 0 выполнять

4.2.1. u = circ.element(c)

4.2.2. если НОВЫЙ[u], то

4.2.2.1. intqueue.q_append(q,u)

4.2.2.2. НОВЫЙ[u] = false

иначе circ.change(c)

4.2.3. i = i-1

Рис.1.12.Процедурная спецификация вспомогательной процедуры для поиска в ширину.

Оба вида поиска в графе – в глубину и в ширину могут быть использованы для нахождения пути между фиксированными вершинами v и u. Достаточно начать поиск в графе с вершины v и вести его до момента посещения вершины u. Преимуществом поиска в глубину является тот факт, что в момент посещения вершины u стек содержит последовательность вершин, определяющую путь из v в u. Это становится очевидным, если отметить, что каждая вершина, помещаемая в стек, является соседом верхнего элемента в стеке. Однако недостатком поиска в глубину является то, что полученный таким образом путь в общем случае не будет кратчайшим путем из v в u. От этого недостатка свободен метод нахождения пути, основанный на поиске в ширину.

На рис.1.13 представлены графы, вершины которых перенумерованы согласно очередности, в которой они посещаются в процессе поиска в ширину.

Соседние файлы в предмете [НЕСОРТИРОВАННОЕ]