Как найти все остовные деревья графа
Перейти к содержимому

Как найти все остовные деревья графа

  • автор:

Построение всех остовных деревьев графа

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

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

Элементарные преобразования деревьев

Рассмотрим два (ориентированных или неориентированных) остовных дерева и графа . «Расстояние» между двумя деревьями обозначается через и определяется как число дуг из , которых нет в (или, что эквивалентно, как число дуг из , которых нет в , поскольку оба дерева и имеют дуг). Если , т.е. если

,

где и , то дерево можно получить из дерева удалив из дугу и добавив дугу . Такое преобразование дерева в дерево называется элементарным преобразованием дерева. На рис. 3 приведено дерево T4, которое получено из дерева T0 c помощью 4 элементарных преобразований: убрать (x1, x8) и добавить (x5, x8); убрать (x5, x6) и добавить (x6, x7); убрать (x2, x3) и добавить (x2, x4); убрать (x3, x5) и добавить (x4, x5).

Рис.3. Остовы T0 и T4.

Существует теорема, согласно которой дерево Tk может быть получено из дерева T0 с помощью серий из k элементарных преобразований при =k.

Процедура порождения всех деревьев неориентированного графа

Первый шаг состоит в приписывании номеров ребрам графа G (ребра нумеруются от 1 до m, где m — число ребер в графе G). На каждом этапе (т. е. при каждом ветвлении в дереве решений) выбирается ребро, которое вместе с остальными, выбранными уже на предыдущих этапах, будет образовывать часть конструируемого дерева. Таким образом, прежде чем отобрать такое ребро, выясняют, действительно ли добавление его к частично сформированному дереву (которое на этом шаге является набором поддеревьев) не приводит к появлению цикла. Если цикл появляется, то данное ребро отбрасывается и проверке подвергается следующее ребро, с большим номером. Если цикла нет, то ребро добавляется к другим, уже отобранным, и процесс продолжается до тех пор, пока не будет построено остовное дерево. Ребра перебираются в порядке возрастания их номеров; это приводит к исчерпывающему и без повторений решению задачи.

Для облегчения манипуляций с поддеревьями в каждом поддереве выделяют произвольным образом корень (некоторую вершину поддерева) и затем рассматриваю поддерево уже как древовидность. Для организации проверки на возможность образования (при добавлении ребра) каждую вершину xj помечают парой (rj, pj). Первая пометка rj указывает «корень» поддерева, содержащего вершину xj. Первоначально rj = xj для всех вершин xj. На некотором шаге два поддерева T1, и T2 сращиваются посредством добавления ребра al=(xa, xb) с вершиной xa из T1 и вершиной xb из T2. Если на этом шаге r1 — «корневая» пометка вершин в T1, а r2 — «корневая» пометка вершин в T2 и для примера r1 < r2, то все вершины в T2, должны «сменить» свои корневые пометки на r1, и два поддерева T1 и T2 «сольются» в единственное новое дерево T1.

Вторая пометка pj, приписанная вершине xj, указывает вершину, предшествующую вершине xj, т.е. если =(xk, xj) — дуга рассматриваемого поддерева, то pj = xk. Для корневой вершины дерева такая пометка полагается равной нулю.

А. Замена корня дерева

Если корнем дерева T является вершина r и нужно в качестве корня выбрать новую вершину xs, то такую «замену» r на xs можно осуществить простым обращением ориентации дуг, принадлежащих цепи, идущей от r к xs, не меняя при этом ориентацию других дуг. Соответствующие изменения пометок будут таковы.

Изменение пометок «предшествования»

Пусть xj = xs и z = pj.

Положить xi = z, a z = pi.

Шаг обновления: pi = xj.

Если xi = r, то перейти к шагу 5. в противном случае положить xj = xi и перейти к шагу 2.

Положить ps = 0, стоп.

Изменение корневых пометок

У всех вершин, имеющих корневую пометку r, заменить ее на пометку xs.

Б. Сращивание двух поддеревьев

Если осуществлено сращивание двух поддеревьев T1 и T2 (путем добавления ребра (xa, xb)), то в пометки необходимо внести следующие изменения:

(1) У вершин с корневой пометкой r2 заменить эту пометку на r1.

(2) Заменить в дереве T2 корень r2 на xb (пункт А), после чего изменить пометку «предшествования» у вершины xb с pb = 0 на pb = xa.

B. Расщепление дерева на две части

Поскольку метод порождения деревьев, рассматриваемый ниже, является поиском, использующим дерево решений, то возникает необходимость удаления некоторых ребер (на шагах возвращения), чтобы испытать затем другие ребра. В такой ситуации удаление ребра приводит к расщеплению некоторого дерева на две части, например на T1 и T2, и в пометки одного из этих поддеревьев должны быть внесены изменения. Пусть удаляется ребро (xa, xb), где xaÎT1 и xbÎT2. Тогда при pb = xa (т. е. если ребро (xa, xb) в первоначальном дереве ориентировано от xa к xb) пометки в дереве T1, можно оставить прежними, а пометки в дереве T2 должны быть изменены. Если же pa = xb (т. е. ребро (xa, xb) ориентировано от xb к xa), то можно не менять пометки в дереве T2, но нужно изменить пометки в T1. Предполагая, что пометки меняются в дереве T2, покажем, как надо «восстанавливать» корень в этом дереве.

Положить S = <xb> и pb = 0 (xb будет корнем дерева T2).

Найти все вершины xj с pjÎS и изменить их корневые пометки на rj = xb. Если таких вершин нет, остановиться.

Шаг обновления: S = S È <xj | pjÎS>; вернуться к шагу 2.

Следует отметить, что ни у одной вершины, кроме нового корня xb, пометки предшествования менять не нужно. Заметим также, что число описанных выше шагов 2 и 3, которое необходимо для восстановления корня, равно длине самой длинной цепи в T2 исходящей из вершины xb.

Описание алгоритма. Возьмем произвольную вершину x * графа G. Пусть ее степень равна d * . Перенумеруем ребра, инцидентные этой вершине: a1, a2, …, ad*. Затем перенумеруем остальные ребра графа G: ad*+1, ad*+2, …, am. При порождении деревьев ребра будут перебираться в соответствии с введенной нумерацией.

Шаг 1. Приписать вершинам пометки: (ri, pi), где ri=xi и pi=0, «xiÎX. Положить k=1.

Шаг 2. Выбрать для исследования некоторое ребро. Например, ak=(xi, xj). Если km, где m — число ребер графа, то перейти к 2 (1). При k=m+1, т. е. если «неисследованных» ребер нет, перейти к шагу 5.

(1) Если ri=rj, то это означает, что вершины xi и xj принадлежат одному и тому же поддереву и добавление ребра ak приведет к появлению цикла. Отбросить ребро ak, т. е. положить k=k-1 и вернуться к шагу 2.

(2) Если rirj то ребро ak можно добавить к ребрам построенных поддеревьев. Перейти к шагу 3.

Шаг 3. Срастить два поддерева, у которых вершины имеют корневые пометки ri и rj, применив для этого метод, описанный выше в пункте Б.

Шаг 4. Отобрав n-1 ребер, мы получаем некоторое дерево. Заполнить это дерево и перейти к шагу 5. Если отобрано меньше, чем n-1 ребер, то положить k=k+1 и вернуться к шагу 2.

Шаг 5. (Возвращение.) Удалить ребро, добавленное последним. Предположим, что таким ребром является al. Если al — единственное оставшееся для добавления ребро, l=d * то остановиться. Все остовные деревья, таким образом построены, т. к. при любом дальнейшем ветвлении дерева решений вершина x * останется изолированной.

В противном случае надо обновить пометки, действуя так, как указано в пункте B, положить k=l-1 и возвратиться к шагу 2.

Построим все остовные деревья графа, изображенного на рис.4. Выберем в качестве x * вершину x1.

Рис.4. Граф G.

На рис.5 изображено соответствующее дерево решений, которое порождено в процессе работы алгоритма. Если взять ребра, указанные в кружочках какой-либо цепи, выходящей из верхнего узла этого дерева и оканчивающейся в самом нижнем узле, то из них можно построить некоторый остов данного графа. Эти остовы перенумерованы числами от 1 до 21 и приведены на рис.6.

Рис.5. Полное дерево поиска.

Рис.6. Все остовы графа G.

Кратчайший остов графа

Рассмотрим взвешенный связный неориентированный граф G=(X, A); вес ребра (xi, xj) обозначим cij. Из большого числа остовов графа нужно найти один, у которого сумма весов ребер наименьшая. Такая задача возникает, например, в том случае, когда вершины являются клеммами электрической сети, которые должны быть соединены друг с другом с помощью проводов наименьшей общей длины (для уменьшения уровня наводок). Другой пример: вершины представляют города, которые нужно связать сетью трубопроводов; тогда наименьшая общая длина труб, которая должна быть использована для строительства (при условии, что вне городов «разветвления» трубопроводов не допускаются), определяется кратчайшим остовом соответствующего графа.

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

Задача построения кратчайшего остова графа является одной из немногих задач теории графой, которые можно считать полностью решенными. Итак, пусть Ti и Tj — два произвольных поддерева, полученных путем добавления ребер при построении кратчайшего остова графа. Определим Dij, как кратчайшее из расстояний между вершинами из Ti и вершинами из Tj следующим образом:

, ij. (1)

Зададим следующую операцию: Для поддерева Ts найти такое поддерево Tj*, чтобы . Пусть будет тем ребром, вес которого соответствует величине в выражении (1). Тогда ребро принадлежит кратчайшему остову и может быть добавлено к другим ребрам частично сформированного кратчайшего остова.

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

Алгоритм Краскала, Прима для нахождения минимального остовного дерева

Алгоритмы нахождения MST применимы в различных областях, начиная от кластеризации данных до построения компьютерных, транспортных сетей.
Я надеюсь, что вы после прочтения данной статьи, примерно понимали, как работают жадные алгоритмы нахождения MST.

Формальная постановка задачи

Имеется следующий неориентированный взвешенный граф. Назовем остовным деревом подграф, содержащий все вершины исходного графа, который является деревом. И задача состоит в том, чтобы найти такое остовное дерево, сумма рёбер которого минимальна.

Исходный граф

Исходный граф

Неформальная постановка задачи

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

Алгоритм Краскала

Механизм, по которому работает данный алгоритм, очень прост. На входе имеется пустой подграф, который и будем достраивать до потенциального минимального остовного дерева. Будем рассматривать только связные графы, в другом случае при применении алгоритма Краскала мы будем получать не минимальное остовное дерево, а просто остовной лес.

Вначале мы производим сортировку рёбер по неубыванию по их весам.

Добавляем i-ое ребро в наш подграф только в том случае, если данное ребро соединяет две разные компоненты связности, одним из которых является наш подграф. То есть, на каждом шаге добавляется минимальное по весу ребро, один конец которого содержится в нашем подграфе, а другой — еще нет.

Алгоритм завершит свою работу после того, как множество вершин нашего подграфа совпадет с множеством вершин исходного графа.

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

Разбор конкретного примера по шагам

Из представленного сверху графа, выпишем все его ребра в отсортированном порядке:

1) D <—> B; w = 2
2) D <—> C; w = 6
3) A <—> B; w = 7
4) A <—> C; w = 8
5) C <—> E; w = 9
6) D <—> F; w = 9
7) F <—> E; w = 10
8) B <—> C; w = 11
9) D <—> E; w = 11

И начнем по списку добавлять эти ребра в наш остов:

Подграф после добавиления 1-го ребраПодграф после добавиления 1-го ребра Подграф после добавления 2-го и 3-го рёберПодграф после добавления 2-го и 3-го рёбер

При добавлении в наше остовное дерево ребра A <—> C, как вы можете заметить, образовывается цикл, поэтому мы просто пропускаем данное ребро.

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

Минимальный остов

Минимальный остов

Проводим проверку с помощью встроенного алгоритма для нахождения MST на graphonline, и видим, что подграфы идентичны.
И да, из-за того, что при равенстве весов рёбер мы можем выбрать любое из них, конечные подграфы, являющиеся минимальными остовными деревьями, могут различаться с точностью до некоторых рёбер.

Провели проверку

Провели проверку

Суммарный вес искомого MST равен 33.

Реализация

Реализовать представленный алгоритм проще всего с помощью СНМ(система непересекающихся отрезков).

Вначале, как мы уже раннее говорили, необходимо отсортировать ребра по неубыванию по их весам. Далее с помощью вызовов функции make_set() мы каждую вершину можем поместить в свое собственное дерево, то есть, создаем некоторое множество подграфов. Дальше итерируемся по всем ребрам в отсортированном порядке и смотрим, принадлежат ли инцидентные вершины текущего ребра разным подграфам с помощью функции find_set() или нет, если оба конца лежат в разных компонентах, то объединяем два разных подграфа в один с помощью функции union_sets().

В итоге асимптотическая сложность данного алгоритма сводится к:

, где:
sort() —
make_set()-
find_set —
union_sets —

Алгоритм Прима

Суть самого алгоритма Прима тоже сводится к жадному перебору рёбер, но уже из определенного множества. На входе так же имеется пустой подграф, который и будем достраивать до потенциального минимального остовного дерева.

Изначально наш подграф состоит из одной любой вершины исходного графа.

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

Продолжаем выполнять предыдущий шаг до тех пор, пока не найдем искомое MST.

Разбор конкретного примера

Выбираем чисто случайно вершину E, далее рассмотрим все ребра исходящие из нее, включаем в наше остовное дерево ребро C <—> E; w = 9, так как данное ребро имеет минимальный вес из всех рёбер инцидентных множеству вершин нашего подграфа. Имеем следующее:

Подграф после добавления 1-го ребра

Подграф после добавления 1-го ребра

Теперь выборка производится из рёбер:
D <—> C; w = 6
A <—> C; w = 8
F <—> E; w = 10
B <—> C; w = 11
D <—> E; w = 11

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

Добавляем в наш подграф ребро D <—> C и по аналогии добаляем ребро D <—> B . Получаем следующее:

Подграф, полученный после добавления рассмотренных рёбер

Подграф, полученный после добавления рассмотренных рёбер

Давайте добьем наш подграф до минимального остовного дерева. Вы, наверное, уже догадались о том, по каким ребрам мы будем связывать наши оставшиеся вершины:
A и F.

Проводим последние штрихи и получили тот же самый подграф в качестве минимального остовного дерева. Но как мы раннее говорили, сам подграф ничего не решает, главное тут — множество рёбер, которые включены в наше остовное дерево.

Искомое минимальное остовное дерево

Искомое минимальное остовное дерево

GRAFY_Lab#3

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

Рассмотрим неориентированный граф G=(X,U) с n вершинами. Следующие определения дерева, как легко показать, эквивалентны друг другу:

i. связный граф, не имеющий циклов;

ii. связный граф, содержащий n вершин и n-1 ребер;

iii. граф, в котором каждая пара вершин соединена одной единственной простой цепью.

Граф G 1 =(X 1 ,U 1 ) называется подграфом (или частью) графа G=(X,U), если , . Подграф G 1 называется остовным подграфом, если .

Остовным деревом (или остовом) графа G называется всякий остовный подграф графа G, являющийся деревом. Например, если G – граф, показанный на рис. 1.а, то граф, на рис. 1.б является остовом графа G, как и граф, изображенный на рис. 1.в.

рис. 1.а рис. 1.б рис. 1.в

Очевидно, что в каждом графе существует остов: разрушая в каждой компоненте связности циклы, т.е. удаляя лишние ребра, придем к остову. В общем случае остов определен неоднозначно. Естественно возникает вопрос: как много остовов в графе?

Теорема 1. Пусть Gn-вершинный граф без петель и – его матрица инциденций с одной удаленной строкой (т.е. с n-1 независимыми строками). Пусть – транспонированная матрица к . Тогда определитель равен числу различных остовных деревьев графа G.

Теорема 2. При n>1 число остовов в полном графе равно .

II. Практический пример.

Задача :

Найти все остовные деревья в графе.

Решение :

1.) Т.к. нам дан полный граф с числом вершин n=4 , то используя Теорему 1 сможем найти количество всех остовов:

Kn = n n -2 = 4 2 = 16

2.) Находим все остовные деревья графа:

III. Алгоритм Прима.

Кратчайший остов графа (остов минимального веса).

Рассмотрим взвешенный связный неориентированный граф G=(X,U); вес ребра (xi, xj) обозначим cij. Из большого числа остовов графа нужно найти один, у которого сумма весов ребер наименьшая. Такая задача возникает, например, в том случае, когда вершины являются клеммами электрической цепи которые должны быть соединены друг с другом с помощью проводов наименьшей общей длины (для уменьшения уровня наводок).

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

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

Воспользуемся алгоритмом Р. Прима ( 1957 г .), применимый к произвольному связному графу

Шаг 1. Выбираем ребро минимального веса и строим дерево .

Шаг 2. Если дерево порядка уже построено и , то среди ребер, соединяющих вершины этого дерева с вершинами графа G=(X,U), не входящими в , выбираем ребро минимального веса. Строим дерево , присоединяя к ребро вместе с его не входящим в концом.

IV. Текст программы.

V. Вывод.

Проделав данную лабораторную работу, мы ознакомились с понятиями дерева и остовного дерева ; узнали 2 новые теоремы, благодаря которым научились определять точное количество остовных деревьев в графе, а также освоили алгоритм нахождения остова минимального веса, применимый для произвольного связного графа.

Как найти все остовные деревья графа

В некоторых ситуациях возникает необходимость в построении полного списка остовных деревьев графа Например, в том случае, когда надо отобрать «наилучшее» дерево, а критерий, позволяющий осуществить такой отбор, является очень сложным (или даже частично субъективным), так что непосредственное решение задачи оптимизации (не использующее перечисление всех остовных деревьев) оказывается невыполнимым. В других ситуациях, например при нахождении передаточной функции системы [42,6] или при вычислении определителей некоторых матриц в макроэкономической теории [2], с помощью порождения всех остовов соответствующих графов можно добиться упрощения вычислительных процедур.

Число различных остовов полного связного неориентированного помеченного графа с вершинами было найдено впервые Кэли [4]. Оно равно . У Муна [45] приводится список из более чем 25 работ, содержащих разнообразные доказательства этой формулы. (См. также задачу 6.) Формулы для числа остовов в более общих графах можно найти у Риордана [49]. Хотя эти формулы, как правило, очень сложные и их вывод для наших целей не нужен, но стоит, пожалуй, привести следующий результат.

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

Доказательство этой теоремы можно найти в [53] и в [1] (см. также задачу 5).

2.1. Элементарные преобразования деревьев

Рассмотрим два (ориентированных или неориентированных) остовных дерева и графа «Расстояние» между двумя деревьями обозначается через и определяется как число дуг из которых нет в (или, что эквивалентно, как число дуг из которых нет в поскольку оба дерева имеют дуг). Если т. е. если

где то дерево можно получить из дерева удалив из дугу и добавив дугу Такое преобразование дерева в дерево называется элементарным преобразованием дерева.

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

Доказательство. Пусть дуг из которых нет в Тк, и к дуг из Тк, которых нет в Если в дерево добавить дугу то в получившемся графе, согласно определению дерева, найдется цикл. (На рис. жирными линиями показано неориентированное дерево а пунктирной линией — дуга дерева приведенного на рис. 7.5(д).) В полученном цикле содержится по крайней мере одна дуга, не принадлежащая дереву Тк. Следовательно, ее можно удалить, разорвав тем самым цикл, и это даст новое дерево Поскольку в число дуг, общих с дугами из Тк, на единицу больше (чем в ), то Применяя элементарные преобразования дальше, получим последовательность деревьев , в которой для каждого . На рис. 7.5(б) — (д) показано, как с помощью 4 элементарных преобразований из дерева получается дерево

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *