Студопедия

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

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

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






Double dist(int, int) const;






>;

Оба класса реализуют интерфейс АТД абстрактных кратчайших путей для нахождения кратчайших расстояний и путей. Этот интерфейс, который показан в программе 21.2, яв­ляется обобщением интерфейса абстрактного транзитивного замыкания взвешенного орг­рафа для выяснения связности в орграфах, который изучался в главе 19. В обеих реали­зациях класса конструктор решает задачу поиска кратчайших путей для всех пар и сохраняет результат в приватных элементах данных. Кроме того, поддерживаются функ­ции реализации запросов, которые возвращают длину кратчайшего пути из одной задан­ной вершины в другую, а также первое или последнее ребра в пути. Основное назначе­ние такого АТД состоит в его практическом использовании для реализации алгоритмов поиска кратчайших путей для всех пар.


Глава 21. Кратчайшие пути



Программа 21.3. Вычисление диаметра сети

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

template < class Graph, class Edge> double diameter(Graph & G) { int vmax = 0, wmax = 0; allSP< Graph, Edge> all(G); for (int v = 0; v < G.V(); v++) for (int w = 0; w < G.V(); w++) if (all.path(v, w))

if (all.dist(v, w) > all.dist(vmax, wmax))

{ vmax = v; wmax = w; } int v = vmax; cout «v; while (v! = wmax)

{ v = all.path(v, wmax)-> w(); cout «" -" «v; } return all.dist(vmax, wmax);



Программа 21.3 представляет собой типовую клиентскую программу, которая при по­иске взвешенного диаметра (weighted diameter) сети использует интерфейс АТД для поиска всех кратчайших путей. Она проверяет все пары вершин, чтобы найти такую пару, для которой длина кратчайшего пути максимальна; затем она обходит путь, ребро за ребром. На рис. 21.13 показан путь, вычисленный этой программой для нашего примера эвкли­довой сети. Цель алгоритмов этого раздела состоит в обеспечении линейного времени выполне­ния функций запроса. Как правило, мы ожидаем, что будет огромное количество таких запросов, поэтому мы готовы к существенным затратам ресурсов на представление при­ватных элементов данных и предварительную обработку в конструкторе, что будет содей-

ствовать быстрым ответам на запросы. Оба рассматривае­мых нами алгоритма требуют области памяти для приватных элементов данных, пропорциональной V2.

Основной недостаток этого общего подхода состоит в том, что для огромной сети мы не можем иметь достаточно­го объема доступной памяти (или не можем предоставить необходимое время на предварительную обработку). В прин­ципе, наш интерфейс предоставляет свободу выбора между временными затратами на предварительную обработку и зат­ратами памяти при обработке запроса. Если мы ожидаем только несколько запросов, предварительную обработку можно не делать, а просто выполнять для каждого запроса единственный алгоритм; тем не менее, существуют ситуа­ции, требующие более совершенных алгоритмов (см. упраж­нения 21.48—21.50). Эта задача обобщает ту, которой мы по­святили большую часть главы 19 и связана с поддержкой быстрых запросов достижимости при ограниченном про­странстве памяти.


РИСУНОК 21.13. ДИАМЕТР СЕТИ

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



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


Первая рассматриваемая реализация функций АТД поиска кратчайших путей для всех пар решает эту задачу за счет использования алгоритма Дейкстры для решения в отно­шении каждой вершины задачи с единственным источником. В C++ можно написать этот метод непосредственно, как показано в программе 21.4: для решения задачи с единствен­ным источником для каэдой вершины строится один вектор объектов SPT. Этот прием обобщает основанный на BFS метод для невзвешенных неориентированных графов, ко­торый рассматривался в разделе 17.7. Это также похоже на использование DFS в програм­ме 19.4, где вычисляется транзитивное замыкание невзвешенного орграфа с началом в каждой вершине.

Программа 21.4. Алгоритм Дейкстры для поиска всех кратчайших путей___________

Этот класс использует алгоритм Дейкстры построения SPT для каждой вершины так, чтобы можно было вычислить pathR и запросить dist для любой пары вершин.

#include " SPT.cc"

template < class Graph, class Edge> class allSP

{ const Graph & G;

vector< SPT< Graph, Edge> ♦ > A; public:

allSP(const Graph & G): G(G), A(G.V()) { for (int s = 0; s < G.V(); s++)

A[s] = new SPT< Graph, Edge> (G, s); } Edge *pathR(int s, int t) const

{ return A[s]-> pathR(t); } double dist (int s, int t) const { return A[s]-> dist(t); >

>;

Свойство 21 7. С помощью алгоритма Дейкстры можно найти все кратчайшие пути в сети с неотрицательными весами за время, пропорциональное VE logdV, где d — 2, если Е < 2V, и d = E/V в противном случае.

Доказательство'. Непосредственно следует из свойства 21.6. ■

Как и в задачах о кратчайших путях для единственного источника с MST, эта грани­ца завышена; время счета VE оказывается таким же, как и для типовых графов.

Чтобы сравнить эту реализацию с другими, полезно изучить матрицы, скрытые в структуре вектора векторов приватных элементов данных. Векторы wt формируют точно такую же матрицу расстояний, как та, которую мы рассматривали в разделе 21 1: элемент на пересечении строки s и столбца t есть длина кратчайшего пути из s в tКак показано на рис. 21.8 и 21.9, векторы spt перенесены из матрицы путей: элемент на пересечении строки s и столбца t представляет собой последний элемент в кратчайшем пути из s в t.

Для насыщенных графов можно было бы использовать представление в виде матри­цы смежности и избежать вычисления обратного графа за счет неявного транспонирова­ния матрицы (обмен индексами строк и столбцов), как в программе 19.7. Разработка ре­ализации по этому плану представляет собой интересное упражнение по программированию и приводит к компактной реализации (см. упражнение 21.43); тем не менее, другой подход, который рассматривается немного ниже, допускает даже более компактную реализацию.







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