Студопедия

Главная страница Случайная страница

Разделы сайта

АвтомобилиАстрономияБиологияГеографияДом и садДругие языкиДругоеИнформатикаИсторияКультураЛитератураЛогикаМатематикаМедицинаМеталлургияМеханикаОбразованиеОхрана трудаПедагогикаПолитикаПравоПсихологияРелигияРиторикаСоциологияСпортСтроительствоТехнологияТуризмФизикаФилософияФинансыХимияЧерчениеЭкологияЭкономикаЭлектроника






Функции АТД поиска на графе






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

■ Найти непомеченную вершину (отправная вершина).

■ Посетить (и пометить как посещенные) все вершины в связной компоненте, ко­
торая содержит отправную вершину.



Часть 5. Алгоритмы на графах


Метод маркирования не задан в этом описании, но в большинстве случаев мы при­меняем тот же метод, который был использован в реализациях поиска в глубину в раз­деле 18.2: мы инициализируем все элементы приватного вектора, индексированного име­нами вершин, отрицательным целым числом и помечаем вершины, присваивая соответствующим компонентам вектора неотрицательные значения. Использование этой процедуры сводится к установке значения всего лишь одного разряда (знакового) мет­ки; в условиях большинства реализаций в векторе хранится также и другая информация, имеющая отношение к помеченным вершинам (например, в реализации из раздела 18.2 это порядок, в котором маркируются вершины). Не определен также метод поиска вер­шин в следующей связной компоненте, но мы чаще всего применяем просмотр этого век­тора в порядке возрастания индекса.

Программа 18.2. Поиск на графе___________________________________________

Данный базовый класс предназначен для обработки графов, которые могут оказаться несвязными. Производные классы должны дать определение функции searchC, которая, будучи вызванной с петлей вершины v в качестве второго аргумента, устанавливает ord[t] в cnt++ для каждой вершины t, содержащейся в той же связной компоненте, что и вершина v. Чаще всего конструкторы в производных классах вызывают функцию search, которая, в свою очередь, вызывает searchC один раз для каждой связной компоненты графа.

template < class Graph> class SEARCH {

protected: const Graph & G; int cnt;

vector < int> ord; virtual void searchC(Edge) = 0; void search() { for (int v = 0; v < G.V(); v++)

if (ord[vj == -1) searchC (Edge (v, v)); } public: SEARCH (const Graph & G): G(G),

ord(G.V(), -1), cnt(0) { }

int operator[](int v) const { return ord[v]; } };

Мы передаем в функцию поиска ребро (используя фиктивную петлю в первом вызо­ве для каждой связной компоненты) вместо того, чтобы задавать ей его вершину назна­чения, ибо ребро говорит нам, как выйти в эту вершину. Если мы знаем ребро, то это равносильно знанию, какой коридор ведет к конкретному перекрестку в лабиринте. Эта информация полезна во многих классах DFS. Если мы просто отслеживаем, в какие вер­шины мы нанесли визит, то от этой информации мало толку, в то же время более инте­ресные задачи требуют знания места, откуда мы пришли.

Программа 18.2 представляет собой реализацию, которая служит иллюстрацией этих возможностей. На рис. 18.8 представлен пример, который показывает, как отражается посещение каждой вершины на состоянии вектора ord любого производного класса. Как правило, рассматриваемые производные классы также исследуют все ребра, инцидентные каждой посещенной вершине. В таких случаях знание того факта, что мы посетили все вершины, говорит нам, что мы также посетили все ребра, как и в случае обхода Тремо.


Глава 18. Поиск на графе



 


выполняет построение представления леса в векторе st (родительские связи) и в векторе ord (из базового класса). Клиенты могут использовать объект DFS для поиска родителя любой заданной вершины леса (ST) или позиции любой заданной вершины при прямом обходе леса (перегруженный оператор []). Свойства таких лесов и их представления изучаются в разделе 18.4.

Программа 18.3 представляет собой пример, который показывает, как можно получить базо­вый класс DFS для вычисления остовного леса на основе базового класса SEARCH из программы 18.2. Мы включаем приватный вектор st в произ­водный класс с целью хранения представления дерева в виде родительских связей, которое мы инициализируем в конструкторе. Кроме того, мы даем определение функции searchC, которая во всем совпадает с функцией searchC из програм­мы 18.1 за исключением того, что она принимает ребро v-w в качестве аргумента и устанавливает st[w] в v. Наконец, мы вводим общедоступную функцию-элемент, которая дает клиентам воз­можность определять родителя любой вершины. Остовные леса являются предметом интереса для многих приложений, но в этой главе они интере­суют нас главным образом в силу того, что они важны для понимания динамического поведения поиска в глубину, что является темой обсуждений раздела 18.4.

В связном графе конструктор из программы 18.2 вызывает функцию searchC всего один раз, а именно, для ребра 0-0, после чего выясняет, что все другие вершины помечены. В графе, состоя­щем из более чем одной связной компоненты, конструктор просматривает все связные компо­ненты непосредственно. Поиск в глубину является первым из нескольких методов, который будет применяться для просмотра связной компоненты графа. Независимо от того, какой метод (при этом не играет роли, каково представление гра­фа) был выбран, программа 18.2 является эффек­тивным методом просмотра всех вершин графа.






© 2023 :: MyLektsii.ru :: Мои Лекции
Все материалы представленные на сайте исключительно с целью ознакомления читателями и не преследуют коммерческих целей или нарушение авторских прав.
Копирование текстов разрешено только с указанием индексируемой ссылки на источник.