Введение
Множество самых разнообразных задач естественно формулируется в терминах
графов. Так, например, могут быть сформулированы задачи составления расписаний
в исследовании операций, анализа сетей в электротехнике, установления структуры
молекул в органической химии, сегментации программ в программировании, анализа
цепей Маркова в теории вероятностей. В задачах, возникающих в реальной жизни,
соответствующие графы часто оказываются так велики, что их анализ неосуществим
без ЭВМ. Таким образом, решение прикладных задач с использованием теории графов
возможно в той мере, в какой возможна обработка больших графов на ЭВМ, и
поэтому эффективные алгоритмы решения задач теории графов имеют большое практическое
значение. В 16 и
17 лекциях мы излагаем несколько эффективных алгоритмов на
графах и используем их для демонстрации некоторой общей техники решения задач
на графах с помощью ЭВМ.
Конечный граф $$G
= (V,E)$$ состоит из конечного множества вершин $$V
= \{ v_1 v_2,..\}$$ и конечного множества ребер $$E\{ e_1 e_2,\ldots
\}$$. Каждому ребру соответствует пара вершин: если ребро $$(v,w)$$
соответствует ребру $$e$$, то говорят, что $$e$$ инцидентно вершинам $$v$$ и $$w$$. Граф $$G = (V,E)$$ изображается следующим образом: каждая вершина
представляется точкой и каждое ребро представляется отрезком линии, соединяющим его
концевые вершины. Граф
называется ориентированным, если
пара вершин $$(v,w)$$, соответствующая каждому ребру, упорядочена. В
таком случае говорят, что ребро $$e$$ ориентированно
из вершины $$v$$ в вершину $$w$$, а направление обозначается стрелкой
на ребре. Мы будем называть ориентированные графы орграфами. В неориентированном графе концевые вершины каждого ребра не упорядочены, и ребра не имеют направления. Ребро называется петлей, если оно начинается и кончается в одной и той же вершине.
Говорят, что два ребра
параллельны, если они имеют одну и ту же пару концевых вершин (и
если они имеют одинаковую ориентацию в случая ориентированного графа). Граф называется простым, если он не имеет ни петель,
ни параллельных ребер. Если не указывается противное, будем считать, что
рассматриваемые графы являются простыми. Всюду в 16 и
17 лекции будем
использовать символы $$\left| V \right|$$ и $$\left| E
\right|$$ для обозначения соответственно числа вершин и числа ребер в графе $$G =
(V,E)$$.
Представления
Наиболее известный способ представления графа на бумаге состоит в
геометрическом изображении точек и линий. В ЭВМ граф должен быть представлен
дискретным способом, причем возможно много различных представлений. Простота
использования, так же как и эффективность алгоритмов на графе, зависит от
подходящего выбора представления графа. Рассмотрим различные структуры данных
для представления графов.
Матрица
смежностей. Одним из наиболее распространенных
машинных представлений простого графа является матрица смежностей или соединений. Матрица смежностей графа $$G = (V,E)$$ есть $$\left|
V \right| \times \left| V \right|$$ -матрица $$A = [a_{ij} ]$$, в
которой $$a_{ij} = 1$$, если в $$G$$ существует ребро, идущее из $$i$$ -й вершины в $$j$$ -ю, и $$a_{ij} = 0$$ в противном случае. Орграф и его
матрица смежностей представлены на рис. 12.1.
(рис 12.1) Ориентированный граф и его матрица смежностей
$$\left[ {\begin{array}{*{20}c}
0 0 0 0 0 1 0 \\
1 0 1 1 0 1 0 \\
0 0 0 1 1 0 0 \\
0 0 0 0 1 0 0 \\
0 0 1 0 0 1 1 \\
0 0 0 0 0 0 0 \\
1 0 0 0 0 1 0
\end{array} } \right]$$
Заметим, что в матрице смежностей петля может быть представлена
соответствующим единичным диагональным элементом. Кратные ребра можно представить, позволив
элементу матрицы быть больше 1, но это не принято, так как обычно удобно
представлять каждый элемент матрицы одним двоичным разрядом.
Для задания матрицы смежностей требуется $$\left| V \right|^2$$
двоичных разрядов. У неориентированного графа матрица смежностей симметрична, и
для ее представления достаточно хранить только верхний треугольник. В
результате экономится почти 50% памяти, но время вычислений может при этом немного
увеличиться, потому что каждое обращение к $$a_{ij}$$ должно быть
заменено следующим: if $$i >j$$ then $$a_{ji}$$ else $$a_{ij}$$.
В случае представления графа его матрицей смежностей для большинства алгоритмов
требуется время вычисления, по крайней мере пропорциональное $$\left| V
\right|^2$$.
Матрица весов. Граф,
в котором ребру $$(i,j)$$ сопоставлено число $$w_{ij}$$,
называется взвешенным
графом, а число $$w_{ij}$$ называется весом ребра $$(i,j)$$. В сетях связи
или транспортных сетях эти веса представляют некоторые физические
величины, такие как стоимость, расстояние, эффективность, емкость или
надежность соответствующего ребра. Простой взвешенный граф может быть представлен своей
матрицей весов $$W = \left[ {w_{ij} } \right]$$,
где $$w_{ij}$$ есть вес ребра, соединяющего вершины $$i$$ и $$j$$.
Веса несуществующих ребер обычно полагают равными $$\infty$$ или 0 в зависимости от приложений. Когда
вес несуществующего ребра равен 0, матрица весов является простым обобщением матрицы смежностей.
Список ребер. Если
граф является разреженным, то возможно, что более
эффектно представлять ребра графа парами вершин. Это представление можно
реализовать двумя массивами $$g = (g_1,g_2,\ldots,g_{\left| E
\right|})$$ и $$h = (h_1,h_2,\ldots,h_{\left| E \right|} )$$. Каждый
элемент в массиве есть метка вершины, а $$i$$ -е ребро графа выходит из
вершины $$g_i$$ и входит в вершину $$h_i$$. Например, орграф,
изображенный на рис. 12.1, будет представляться следующим
образом:$$g = (1,2,2,2.2,3,3,4,5,5,5,7,7),$$
$$h = (6,1,3,4,6,4,5,5,3,6,7,1,6).$$
Ясно, что при этом легко представимы петли и кратные ребра.
Структура смежности.
В ориентированном графе вершина $$y$$ называется последователем другой
вершины $$x$$, если существует ребро, направленное
из $$x$$ в $$y$$. Вершина $$x$$ называется тогда предшественником $$y$$. В случае неориентированного графа две вершины называются соседями,
если между ними есть ребро. Граф может быть описан его структурой смежности, то
есть списком всех последователей (соседей) каждой вершины; для каждой
вершины $$v$$ задается $$Adj(v)$$ - список всех последователей
(соседей) вершины $$v$$. В большинстве алгоритмов на графах
относительный порядок вершин, смежных с вершиной $$v$$ в $$Adj(v)$$,
не важен, и в таком случае удобно считать $$Adj(v)$$ мультимножеством (или множеством,
если граф является простым) вершин, смежных
с $$v$$. Структура смежности орграфа, представленного на рис. 12.1,
такова:
Adj(v)
1: 6
2: 1, 3, 4, 6
3: 4, 5
4: 5
5: 3, 6, 7
6:
7: 1, 6
Если для хранения метки вершины используется одно машинное слово, то
структура смежности ориентированного графа требует $$\left| V \right| +
\left| E \right|$$ слов. Если граф неориентированный, нужно $$\left| V
\right| + 2\left| E \right|$$ слов, так как каждое ребро встречается дважды.
Структуры смежности могут быть удобно реализованы массивом из $$\left|
V \right|$$ линейно связанных списков, где каждый список содержит
последователей некоторой вершины. Поле данных содержит метку одного из последователей, и поле указателей
указывает следующего последователя. Хранение списков смежности в виде
связанного списка желательно для алгоритмов, в которых в графе добавляются или удаляются вершины.
Матрица инцидентности - $$M$$ задает граф : $$m_{ij}=1$$,
если ребро $$j$$ выходит из вершины $$i$$, $$m_{ij}=-1$$,
если ребро $$j$$ входит в вершину $$i$$, и $$m_{ij}=0$$ в остальных случаях.
Связность и расстояние
Говорят, что вершины $$x$$ и $$y$$ в графе смежны,
если существует ребро, соединяющее их.
Говорят, что два ребра смежны, если они
имеют общую вершину. Простой
путь, или для краткости, просто путь,
записываемый иногда как $$(v_1,v_2,\ldots,v_k )$$, - это
последовательность смежных ребер $$(v_1,v_2 ),(v_2,v_3 ),\ldots,(v_{k -
2},v_{k - 1} ),(v_{k - 1},v_k )$$, в которой все
вершины $$v_1,v_2,\ldots,v_k$$ различны, исключая, возможно,
случай $$v_1 = v_k$$. В орграфе этот путь называется ориентированным
из $$v_1$$ в $$v_k$$, в неориентированном графе он называется
путем между $$v_1$$ и $$v_k$$. Число ребер в пути называется длиной пути. Путь наименьшей длины
называется кратчайшим
путем. Замкнутый путь называется циклом.
Граф, который не содержит циклов, называется ациклическим.
Подграф графа $$G = (V,E)$$ есть граф, вершины и ребра которого
лежат в $$G$$. Подграф $$G$$, индуцированный
подмножеством $$S$$ множества $$V$$ вершин
графа $$G$$, - это подграф, который получается в результате удаления
всех вершин из $$V - S$$ и всех ребер, инцидентных им.
Неориентированный
граф $$G$$ связен,
если существует хотя бы один путь в $$G$$ между
каждой парой вершин $$v_i$$ и $$v_j$$. Ориентированный граф $$G$$ связен,
если неориентированный граф, получающийся
из $$G$$ путем удаления ориентации ребер, является связным. Граф, состоящий из
единственной изолированной вершины, является (тривиально) связным.
Максимальный связный подграф графа $$G$$ называется связной компонентой или просто компонентой $$G$$. Несвязный граф состоит из двух или более компонент.
Максимальный сильно связный подграф называется сильно связной компонентой.
Иногда недостаточно знать, что граф связен; нас может интересовать,
насколько "сильно связен" связный граф. Например, связный граф может
содержать вершину, удаление которой вместе с инцидентными ей ребрами разъединяет оставшиеся
вершины. Такая вершина называется точкой сочленения или разделяющей вершиной. Граф, содержащий точку сочленения, называется разделимым.
Граф без точек сочленения называется двусвязным или неразделимым.
Максимальный двусвязный подграф графа называется двусвязной компонентой или блоком.
Большинство основных вопросов о графах касается связности, путей и
расстояний. Нас может интересовать вопрос, является ли граф связным; если он
связен, то может оказаться нужным найти кратчайшее расстояние между выделенной парой
вершин или определить кратчайший путь между ними. Если граф несвязен, то может
потребоваться найти все его компоненты. В нашем курсе строятся алгоритмы для
решения этих и других подобных вопросов.
Остовные деревья
Связный неориентированный ациклический граф называется деревом,
множество деревьев называется лесом.
В связном неориентированном графе $$G$$ существует по
крайней мере один путь между каждой парой вершин; отсутствие
циклов в $$G$$ означает, что существует самое большее один такой путь
между любой парой вершин
в $$G$$. Поэтому, если $$G$$ - дерево, то между каждой парой
вершин в $$G$$ существует в точности один путь. Рассуждение легко
обратимо, и поэтому
неориентированный граф $$G$$ будет деревом тогда и только тогда, если
между каждой парой вершин в $$G$$ существует в точности один путь. Так
как наименьшее число ребер, которыми можно
соединить $$n$$ вершин, равно $$n - 1$$ и дерево
с $$n$$ вершинами содержит в точности $$n - 1$$ ребер, то
деревья можно считать минимально связными графами. Удаление из дерева
любого ребра превращает его в несвязный граф, разрушая единственный путь между
по крайней мере одной парой вершин.
Особый интерес представляют остовные деревья графа $$G$$, то есть деревья,
являющиеся подграфами графа $$G$$ и содержащие все его вершины. Если
граф $$G$$ несвязен, то множество, состоящее из остовных деревьев
каждой компоненты
называется остовном
лесом графа. Для построения остовного дерева (леса)
данного неориентированного графа $$G$$, мы последовательно
просматриваем ребра $$G$$, оставляя те, которые не образуют циклов с
уже выбранными.
Во взвешенном графе $$G = (V,E)$$ часто интересно определить
остовное дерево (лес) с минимальным общим весом
ребер, то есть дерево (лес), у которого сумма весов всех его ребер
минимальна. Такое
дерево называется
минимумом оставных деревьев или минимальное
остовное дерево. Другими словами, на каждом шаге мы выбираем новое
ребро с наименьшим весом (наименьшее ребро), не образующее циклов с уже выбранными
ребрами; этот процесс продолжаем до тех пор, пока не будет
выбрано $$\left| V \right| - 1$$ ребер, образующих остовное
дерево $$T$$. Этот процесс известен как жадный алгоритм.
Жадный алгоритм может быть выполнен в два этапа. Сначала ребра
сортируются по весу и затем строится остовное дерево путем выбора наименьших из
имеющихся в распоряжении ребер.
Существует другой метод получения минимума остовных деревьев, который не
требует ни сортировки ребер, ни проверки на цикличность на каждом шаге, - так
называемый алгоритм
ближайшего соседа. Мы начинаем с некоторой
произвольной вершины $$a$$ в заданном графе. Пусть $$(a,b)$$ -
ребро с наименьшим весом, инцидентное $$a$$ ;
ребро $$(a,b)$$ включается в дерево. Затем среди всех ребер,
инцидентных либо $$a$$, либо $$b$$, выбираем ребро с
наименьшим весом и включаем его в частично построенное дерево.
В результате этого в дерево добавляется новая вершина,
например, $$c$$. Повторяя процесс, ищем наименьшее ребро,
соединяющее $$a$$, $$b$$ или $$c$$ с некоторой другой
вершиной графа. Процесс продолжается до тех пор, пока
все вершины из $$G$$ не будут включены в дерево, то есть пока дерево не
станет остовным.
Наихудшим для этого алгоритма будет случай, когда $$G$$ - полный граф (то есть когда
каждая пара вершин в графе соединена ребром);
в этом случае для того, чтобы найти ближайшего соседа, на каждом шаге нужно
сделать максимальное число сравнений. Чтобы выбрать первое ребро, мы сравниваем
веса всех $$\left| V \right| - 1$$ ребер, инцидентных
вершине $$a$$, и выбираем наименьшее; этот шаг требует $$\left| V
\right| - 2$$ сравнений. Для выбора второго ребра мы ищем наименьшее среди
возможных $$2(\left| V \right| - 2)$$ ребер
(инцидентных $$a$$ или $$b$$ ) и делаем для этого $$2(\left|
V \right| - 2) - 1$$ сравнений. Таким образом, ясно, что для
выбора $$i$$ -го ребра требуется $$i(\left| V \right| - i) -
1$$ сравнений, и поэтому в сумме потребуется$$\sum\limits_{i =
1}^{\left| V \right| - 1} {[i(\left| V \right| - i) - 1] = \frac{1}
{6}\left| V \right|^3 + O(\left| V \right|^2 )}$$
сравнений для
построения минимума остовных деревьев.
Клики
Максимальный полный подграф графа $$G$$ называется кликой графа $$G$$ ;
другими словами, клика графа $$G$$ есть подмножество его вершин,
такое, что между каждой парой вершин этого подмножества существует ребро
и, кроме того, это подмножество не принадлежит никакому большому
подмножеству с тем же свойством. Например, на рис. 12.3 показан граф и
его клики.
(рис 12.2) Граф G и все его кликиКлики графа представляют "естественные" группировки вершин, и
определение клик
графа полезно в кластерном анализе в таких областях, как информационный поиск и
социология.
Изоморфизм
Два графа $$G_A = (V_A,E_A ),G_B = (V_B,E_B )$$ называются изоморфными, если
существует взаимно однозначное соответствие $$f:V_A \to V_B$$, такое,
что $$(v,w) \in E_A$$ тогда и только тогда, если $$(f(v),f(w)) \in
E_B$$, то есть существует соответствие между вершинами
графа $$G_A$$ и вершинами графа $$G_B$$, сохраняющее отношение
смежности. Например, на рис. 12.3 показаны два
изоморфных орграфа: вершины $$a,b,c,d,e,f$$ в
орграфе $$G_2$$ соответствуют вершинам 2, 3, 6, 1, 4, 5 в указанном
порядке в орграфе $$G_1^{}$$. Вообще говоря,
между $$V_A$$ и $$V_B$$ может быть более чем одно соответствие,
и на рис. 12.3 графы имеют на самом деле
второй изоморфизм: $$a,b,c,d,e,f$$ соответствуют в указанном порядке
вершинам 2, 3, 6, 1, 5, 4. Изоморфные графы
отличаются только метками вершин, в связи с чем задача определения изоморфизма
возникает в ряде практических ситуаций, таких, как информационный поиск и
определение химических соединений.
Заметим, что можно ограничится орграфами. Любой неориентированный граф
превращается в орграф заменой каждого ребра двумя противоположно направленными
ребрами. Два полученные таким образом орграфа, очевидно, изоморфны тогда и
только тогда, если изоморфны исходные графы.
(рис 12.3) Изоморфные орграфыПланарность
Граф называют планарным, если существует такое изображение на плоскости
его вершин и ребер, что:
каждая вершина $$v$$ изображается отдельной
точкой $$v'$$ на плоскости;
каждое ребро $$(v,w)$$ изображается простой кривой, имеющей
концевые точки $$(v',w^1 )$$ ;
эти кривые пересекаются только в общих концевых точках.
Задача определения того, можно ли изобразить граф на плоскости без пересечения
ребер, имеет большой практический интерес (например, при конструировании
интегральных схем или печатных плат необходимо выяснить, можно ли
окончательную схему вложить в плоскость).
Определение планарности графа отличается от других рассмотренных нами
задач, поскольку при изображении точек и линий на плоскости приходится больше
иметь дело с непрерывными, а не с дискретными величинами. Взаимосвязь между
дискретными и непрерывными аспектами планарности заинтересовала математиков и
привела к различным характеристикам планарных графов. С точки зрения математики
эти характеристики изящны, но эффективных алгоритмов определения планарности
они не дают. Наиболее успешный подход к определению планарности состоит просто
в том, что граф разбивается на подграфы и затем делается попытка разместить его
на плоскости, добавляя подграфы один за другим и сохраняя при размещении
планарность.
Вначале сделаем несколько простых, но полезных наблюдений. Поскольку орграф
планарен тогда и только тогда, если планарен соответствующий неориентированный
граф, полученный игнорированием направления ребер, то достаточно рассматривать
только неориентированные графы, поскольку неориентированный граф планарен тогда
и только тогда, если все его двусвязные компоненты планарны. Поэтому если
неориентированный граф является разделимым, мы можем разложить его на
двусвязные компоненты и рассматривать их отдельно. Наконец, поскольку
параллельные ребра и петли всегда можно добавить к графу или удалить из него
без нарушения свойства планарности, нам достаточно рассматривать только простые
графы. Поэтому при определении планарности будем предполагать, что граф
неориентированный, простой и двусвязный.
Наша основная стратегия состоит прежде всего в том, чтобы в
графе $$G$$ найти цикл $$C$$, разместить $$C$$ на
плоскости в виде простой замкнутой кривой, разложить оставшуюся часть $$G
- C$$ на непересекающиеся по ребрам пути и затем попытаться разместить
каждый из этих
путей либо целиком внутри $$C$$, либо целиком вне $$C$$. Если
нам удалось разместить так весь граф $$G$$, то он планарен, в
противном случае он непланарен. Трудность этого способа
заключается в том, что при размещении путей можно выбирать либо внутренность,
либо внешность $$C$$$, и мы должны проконтролировать, чтобы неправильный
выбор области размещения на
ранней стадии не устранял возможности размещения последующих путей, - это
могло бы привести нас к неверному заключению, что планарный граф непланарен.