Алгоритм Kruskall не будет искать циклы, потому что это неэффективность работы; Но пытается создать компоненты, которые являются деревом, а затем соединяют их друг с другом. Как вы знаете, если вы соедините два разных дерева с одним новым краем, вы создадите новое дерево, и нет необходимости проверять циклы.
Если посмотреть на wiki page алгоритм выглядит следующим образом:
1. create a forest F (a set of trees), where each vertex in the graph is a separate tree
2. create a set S containing all the edges in the graph
3. while S is nonempty and F is not yet spanning
a. remove an edge with minimum weight from S
b. if that edge connects two different trees, then add it to the forest, combining
two trees into a single tree
c. otherwise discard that edge.
Вы должны использовать Disjoint Set Data Structure для этого. снова из вики:
сначала сортировать по массе с использованием сортировки в O (E log E) время; это позволяет выполнить шаг «удалить край с минимальным весом от S» для работы в постоянное время. Затем мы используем данные с непересекающимися данными (Союз & Найти), чтобы отслеживать, в каких вершинах находятся компоненты . Нам нужно выполнить операции O (E), две операции «найти» и, возможно, одно объединение для каждого ребра. Даже простые данные с непересекающимися данными , такие как леса с разделенными наборами с объединением по рангам, могут выполнять операции O (E) в O (E log V). Таким образом, общее время равно O (E log E) = O (E log V).
Создание Disjoint леса
Теперь вы посмотрите на Boost Graph Library-Incremental Components часть может. Вы должны реализовать некоторые методы: MakeSet, Найти, Союз, После этого вы можете реализовать алгоритм kruskall. Все, что вы делаете, работает с некоторыми наборами, и самый простой способ сделать это - использовать связанный список.
Каждый набор имеет один элемент с именем представительский элемент, который является первым элементом в наборе.
1- Сначала осуществить MakeSet пути связанных списков:
Это подготавливает структуру данных непересекающихся-наборы для дополнительных алгоритма, подключенных компонентов, делая каждую вершину в графе с элементом своего собственного компонента (или установить).
Вы просто должны инициализировать каждую вершину (элемент) в качестве представительного элемента нового набора, вы можете сделать это, установив их, как они сами родители:
function MakeSet(x)
x.parent := x
2- Реализовать Найти метод:
Найти репрезентативной элемент набора, который содержит вершину x
:
function Find(x)
if x.parent == x
return x
else
return Find(x.parent)
Элемент if
проверяет, является ли элемент представительным или нет. мы устанавливаем все репрезентативные элементы множеств в качестве их первого элемента, устанавливая их как сами родительские.
3- И, наконец, когда вы получили все предыдущие вещи просто часть реализации Union метода:
function Union(x, y)
xRoot := Find(x) // find representative element of first element(set)
yRoot := Find(y) // find representative element of second element(set)
xRoot.parent := yRoot // set representative element of first set
// as same as representative element of second set
Теперь, как вы должны запустить Крускали?
Сначала поместите все узлы в n
непересекающиеся наборы по MakeSet метод. На каждом шаге после нахождения нужного ребра (не проверенного и минимального) найдите соответствующие наборы его вершин конечных точек на Найдите метод (их репрезентативные элементы), если они одинаковы, отбросьте это край, потому что этот край вызывает цикл, но Если они находятся в разных наборах, используйте метод Union для объединения этих множеств. Поскольку каждый набор является древовидным соединением, это дерево.
Вы можете оптимизировать это, выбрав лучшую структуру данных для непересекающихся множеств, но пока думаю, что этого достаточно. Если вас интересуют более сложные структуры данных, вы можете реализовать ранг базовый путь, вы найдете его в wiki, это легко, но я не упомянул об этом, чтобы не допустить недоумения.
Поправьте меня, если я ошибаюсь, но это дерево, так что каждый узел, кроме первого узла будет иметь родительский узел. Рассматривали ли вы эту реализацию. –
@Legend, В алгоритме kruskall, во время выполнения алгоритма у нас есть лес, а не дерево, поэтому ваше предположение неверно. –