Система непересекающихся множеств. Алгоритм Крускала.

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

Sort(E) – по возрастанию веса

Для каждого ребра e из E MakeSet(e)

For (u,v) из E (уже по возрастанию веса)

If (FindSet(u) != FindSet(v))

Union(u->Set, v->Set)

Оценка

До начала работы алгоритма необходимо отсортировать рёбра по весу, это требует O(E × log(E)) времени. После чего компоненты связности удобно хранить в виде системы непересекающихся множеств. Все операции в таком случае займут O(E × α(E, V)), где α — функция, обратная к функции Аккермана. Поскольку для любых практических задач α(E, V) < 5, то можно принять её за константу, таким образом общее время работы алгоритма Крускала можно принять за O(E * log(E)).

Система непересекающихся множеств

Эта структура данных предоставляет следующие возможности. Изначально имеется несколько элементов, каждый из которых находится в отдельном (своём собственном) множестве. За одну операцию можно объединить два каких-либо множества, а также можно запросить, в каком множестве сейчас находится указанный элемент. Также, в классическом варианте, вводится ещё одна операция — создание нового элемента, который помещается в отдельное множество.

Таким образом, базовый интерфейс данной структуры данных состоит всего из трёх операций:

· Система непересекающихся множеств. Алгоритм Крускала. - student2.ru — добавляет новый элемент Система непересекающихся множеств. Алгоритм Крускала. - student2.ru , помещая его в новое множество, состоящее из одного него.

· Система непересекающихся множеств. Алгоритм Крускала. - student2.ru — объединяет два указанных множества (множество, в котором находится элемент Система непересекающихся множеств. Алгоритм Крускала. - student2.ru , и множество, в котором находится элемент Система непересекающихся множеств. Алгоритм Крускала. - student2.ru ).

· Система непересекающихся множеств. Алгоритм Крускала. - student2.ru — возвращает, в каком множестве находится указанный элемент Система непересекающихся множеств. Алгоритм Крускала. - student2.ru . На самом деле при этом возвращается один из элементов множества (называемый представителем или лидером (в англоязычной литературе "leader")). Этот представитель выбирается в каждом множестве самой структурой данных (и может меняться с течением времени, а именно, после вызовов Система непересекающихся множеств. Алгоритм Крускала. - student2.ru ).

Например, если вызов Система непересекающихся множеств. Алгоритм Крускала. - student2.ru для каких-то двух элементов вернул одно и то же значение, то это означает, что эти элементы находятся в одном и том же множестве, а в противном случае — в разных множествах.

Описываемая ниже структура данных позволяет делать каждую из этих операций почти за Система непересекающихся множеств. Алгоритм Крускала. - student2.ru в среднем (более подробно об асимптотике см. ниже после описания алгоритма).

Определимся сначала, в каком виде мы будем хранить всю информацию.

Множества элементов мы будем хранить в виде деревьев: одно дерево соответствует одному множеству. Корень дерева — это представитель (лидер) множества.

При реализации это означает, что мы заводим массив Система непересекающихся множеств. Алгоритм Крускала. - student2.ru , в котором для каждого элемента мы храним ссылку на его предка в дерева. Для корней деревьев будем считать, что их предок — они сами (т.е. ссылка зацикливается в этом месте).

Наивная реализация

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

Итак, вся информация о множествах элементов хранится у нас с помощью массива Система непересекающихся множеств. Алгоритм Крускала. - student2.ru .

Чтобы создать новый элемент (операция Система непересекающихся множеств. Алгоритм Крускала. - student2.ru ), мы просто создаём дерево с корнем в вершине Система непересекающихся множеств. Алгоритм Крускала. - student2.ru , отмечая, что её предок — это она сама.

Чтобы объединить два множества (операция Система непересекающихся множеств. Алгоритм Крускала. - student2.ru ), мы сначала найдём лидеров множества, в котором находится Система непересекающихся множеств. Алгоритм Крускала. - student2.ru , и множества, в котором находится Система непересекающихся множеств. Алгоритм Крускала. - student2.ru . Если лидеры совпали, то ничего не делаем — это значит, что множества и так уже были объединены. В противном случае можно просто указать, что предок вершины Система непересекающихся множеств. Алгоритм Крускала. - student2.ru равен Система непересекающихся множеств. Алгоритм Крускала. - student2.ru (или наоборот) — тем самым присоединив одно дерево к другому.

Наконец, реализация операции поиска лидера ( Система непересекающихся множеств. Алгоритм Крускала. - student2.ru ) проста: мы поднимаемся по предкам от вершины Система непересекающихся множеств. Алгоритм Крускала. - student2.ru , пока не дойдём до корня, т.е. пока ссылка на предка не ведёт в себя. Эту операцию удобнее реализовать рекурсивно (особенно это будет удобно позже, в связи с добавляемыми оптимизациями).

Эвристика сжатия пути

Эта эвристика предназначена для ускорения работы Система непересекающихся множеств. Алгоритм Крускала. - student2.ru .

Она заключается в том, что когда после вызова Система непересекающихся множеств. Алгоритм Крускала. - student2.ru мы найдём искомого лидера Система непересекающихся множеств. Алгоритм Крускала. - student2.ru множества, то запомним, что у вершины Система непересекающихся множеств. Алгоритм Крускала. - student2.ru и всех пройденных по пути вершин — именно этот лидер Система непересекающихся множеств. Алгоритм Крускала. - student2.ru . Проще всего это сделать, перенаправив их Система непересекающихся множеств. Алгоритм Крускала. - student2.ru на эту вершину Система непересекающихся множеств. Алгоритм Крускала. - student2.ru .

Таким образом, у массива предков Система непересекающихся множеств. Алгоритм Крускала. - student2.ru смысл несколько меняется: теперь это сжатый массив предков, т.е. для каждой вершины там может храниться не непосредственный предок, а предок предка, предок предка предка, и т.д.

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

Таким образом, к массиву Система непересекающихся множеств. Алгоритм Крускала. - student2.ru следует подходить именно как к массиву предков, возможно, частично сжатому.

Наши рекомендации