Изучение алгоритма Краскала: реализация Python для поиска минимальных остовных деревьев

В мире теории графов и алгоритмов алгоритм Краскала известен как популярный метод поиска минимального остовного дерева (MST) связного взвешенного графа. Благодаря своей простоте и эффективности он стал идеальным выбором для различных приложений. В этой статье блога мы углубимся в алгоритм Крускала и предоставим реализацию на Python. Итак, хватайте шляпу программиста и начнем!

Понимание алгоритма Краскала:

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

  1. Отсортируйте все ребра графа в порядке неубывания их весов.
  2. Инициализируйте пустой набор, называемый «лесом», для хранения минимального связующего дерева.
  3. Перебрать отсортированные ребра:
    a. Если добавление текущего ребра не создает цикл в лесу, добавьте его в лес.
    b. В противном случае игнорируйте край.
  4. Повторяйте шаг 3 до тех пор, пока все ребра не будут обработаны или пока лес не будет содержать n-1 ребер (где n — количество вершин в графе).

Реализация на Python:

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

# Function to find the parent of a vertex
def find_parent(parent, vertex):
    if parent[vertex] == vertex:
        return vertex
    return find_parent(parent, parent[vertex])
# Function to perform the union of two sets
def union(parent, rank, x, y):
    root_x = find_parent(parent, x)
    root_y = find_parent(parent, y)
    if rank[root_x] < rank[root_y]:
        parent[root_x] = root_y
    elif rank[root_x] > rank[root_y]:
        parent[root_y] = root_x
    else:
        parent[root_y] = root_x
        rank[root_x] += 1
# Kruskal's algorithm implementation
def kruskal(graph):
    # Sort edges in non-decreasing order of weights
    sorted_edges = sorted(graph, key=lambda x: x[2])
    num_vertices = len(graph)
    parent = [i for i in range(num_vertices)]
    rank = [0] * num_vertices
    minimum_spanning_tree = []
    for edge in sorted_edges:
        u, v, weight = edge
        parent_u = find_parent(parent, u)
        parent_v = find_parent(parent, v)
        if parent_u != parent_v:
            minimum_spanning_tree.append(edge)
            union(parent, rank, parent_u, parent_v)
    return minimum_spanning_tree

Объяснение реализации:

Реализация Python состоит из трёх основных функций:

  1. find_parent(parent, vertex): эта функция используется для поиска родительской вершины в лесу. Он использует концепцию непересекающихся множеств и рекурсию для поиска конечного родителя.

  2. union(parent, rank, x, y): эта функция выполняет объединение двух наборов, присоединяя корень одного набора к корню другого. Он заботится о балансировке рангов для обеспечения эффективности.

  3. kruskal(graph): это основная реализация алгоритма Краскала. Он сортирует ребра по их весам и перебирает их, добавляя ребра в минимальное связующее дерево, если они не создают циклы.

Собираем все вместе:

Чтобы использовать реализацию алгоритма Краскала, вам необходимо представить свой граф в виде списка ребер, где каждое ребро представляет собой кортеж со связанными вершинами и весом. Вот пример:

graph = [(0, 1, 4), (0, 7, 8), (1, 2, 8), (1, 7, 11), (2, 3, 7), (2, 8, 2), (2, 5, 4),
         (3, 4, 9), (3, 5, 14), (4, 5, 10), (5, 6, 2), (6, 7, 1), (6, 8, 6), (7, 8, 7)]
minimum_spanning_tree = kruskal(graph)
print("Minimum Spanning Tree:")
for edge in minimum_spanning_tree:
    print(edge)

Этот фрагмент кода демонстрирует использование реализации алгоритма Крускала на примере графа. Вы можете заменить graph

В области теории графов и алгоритмов алгоритм Краскала выделяется как популярный подход к определению минимального остовного дерева (MST) связного взвешенного графа. Благодаря своей простоте и эффективности он стал предпочтительным выбором для различных применений. В этой статье блога мы углубимся в тонкости алгоритма Краскала и предоставим пошаговую реализацию на Python. Итак, давайте засучим рукава и приступим к программированию!

Понимание алгоритма Краскала:

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

  1. Отсортируйте все ребра графа в порядке неубывания их весов.
  2. Создайте пустой набор под названием «лес» для хранения минимального связующего дерева.
  3. Перебрать отсортированные ребра:
    a. Если добавление текущего ребра не создает цикл в лесу, добавьте его в лес.
    b. В противном случае не обращайте внимания на край.
  4. Повторяйте шаг 3 до тех пор, пока все ребра не будут обработаны или пока лес не будет содержать n-1 ребер (где n — количество вершин в графе).

Реализация на Python:

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

# Function to find the parent of a vertex
def find_parent(parent, vertex):
    if parent[vertex] == vertex:
        return vertex
    return find_parent(parent, parent[vertex])
# Function to perform the union of two sets
def union(parent, rank, x, y):
    root_x = find_parent(parent, x)
    root_y = find_parent(parent, y)
    if rank[root_x] < rank[root_y]:
        parent[root_x] = root_y
    elif rank[root_x] > rank[root_y]:
        parent[root_y] = root_x
    else:
        parent[root_y] = root_x
        rank[root_x] += 1
# Kruskal's algorithm implementation
def kruskal(graph):
    # Sort edges in non-decreasing order of weights
    sorted_edges = sorted(graph, key=lambda x: x[2])
    num_vertices = len(graph)
    parent = [i for i in range(num_vertices)]
    rank = [0] * num_vertices
    minimum_spanning_tree = []
    for edge in sorted_edges:
        u, v, weight = edge
        parent_u = find_parent(parent, u)
        parent_v = find_parent(parent, v)
        if parent_u != parent_v:
            minimum_spanning_tree.append(edge)
            union(parent, rank, parent_u, parent_v)
    return minimum_spanning_tree

Объяснение реализации:

Реализация Python состоит из трёх основных функций:

  1. find_parent(parent, vertex): эта функция используется для поиска родительской вершины в лесу. Он использует концепцию непересекающихся множеств и рекурсию для поиска конечного родителя.

  2. union(parent, rank, x, y): эта функция выполняет объединение двух наборов, присоединяя корень одного набора к корню другого. Он заботится о балансировке рангов для обеспечения эффективности.

  3. kruskal(graph): это основная реализация алгоритма Краскала. Он сортирует ребра по их весам и перебирает их, добавляя ребра в минимальное связующее дерево, если они не создают циклы.

Собираем все вместе:

Чтобы использовать реализацию алгоритма Краскала, вам необходимо представить свой граф в виде списка ребер, где каждое ребро представляет собой кортеж со связанными вершинами и весом. Вот пример:

graph = [(0, 1, 4), (0, 7, 8), (1, 2, 8), (1, 7, 11), (2, 3, 7), (2, 8, 2), (2, 5, 4),
         (3, 4, 9), (3, 5, 14), (4, 5, 10), (5, 6, 2), (6, 7, 1), (6, 8, 6), (7, 8, 7)]
minimum_spanning_tree = kruskal(graph)
print("Minimum Spanning Tree:")
for edge in minimum_spanning_tree:
    print(edge)

Этот фрагмент кода демонстрирует использование реализации алгоритма Крускала