Сравнительный анализ алгоритмов
Рассмотрим связный неориентированный граф с вершинами 1, 2, 3, 4 и рёбрами (Рисунок 1):
Рисунок 1 - Неориентированный граф
Список рёбер графа с весами, отсортированный по возрастанию:
3 ↔ 4, вес: 1
2 ↔ 3, вес: 2
1 ↔ 4, вес: 3
2 ↔ 4, вес: 4
1 ↔ 2, вес: 5
Таблица 1 – Исходная матрица расстояний
|
1 |
2 |
3 |
4 |
1 |
0 |
5 |
∞ |
3 |
2 |
5 |
0 |
2 |
4 |
3 |
∞ |
2 |
0 |
1 |
4 |
3 |
4 |
1 |
0 |
4.1 Пример работы алгоритма Крускала.
Алгоритм Крускала работает с общим списком рёбер, предварительно отсортированным по возрастанию весов. На каждом шаге мы берем самое «дешёвое» ребро и добавляем его в остов, если оно не создает цикл. Для отслеживания циклов используется система непересекающихся множеств.
Инициализация:
Каждая вершина находится в собственном множестве: {1}, {2}, {3}, {4}.
Список рёбер для рассмотрения: (3 – 4 : 1), (2 – 3 : 2), (1 – 4 : 3), (2 – 4 : 4), (1 – 2 : 5).
Множество рёбер MST: пустое, текущий вес: 0.
Шаг 1. Рассматриваем ребро (3 – 4) с минимальным весом 1.
Вершина 3 (множество {3}) и вершина 4 (множество {4}) находятся в разных множествах.
Добавляем ребро (3 – 4) в MST. Объединяем множества.
Состояние множеств: {1}, {2}, {3,4}.
Текущий вес MST: 1.
Шаг 2. Рассматриваем ребро (2 – 3) с весом 2.
Вершина 2 (множество {2}) и вершина 3 (множество {3, 4}) находятся в разных множествах.
Добавляем ребро (2 – 3) в MST. Объединяем множества.
Состояние множеств: {1}, {2,3,4}.
Текущий вес MST: 1 + 2 = 3.
Шаг 3. Рассматриваем ребро (1 – 4) с весом 3.
Вершина 1 (множество {1}) и вершина 4 (множество {2,3,4}) находятся в разных множествах.
Добавляем ребро (1 – 4) в MST. Объединяем множества.
Состояние множеств: {1,2,3,4}.
Текущий вес MST: 3 + 3 = 6.
Проверка условия остановки.
Количество добавленных рёбер равно V – 1 = 4 – 1 = 3. Все вершины объединены в одно множество. Остальные рёбра (2 – 4 : 4) и (1 – 2 : 5) пропускаются, так как их вершины уже принадлежат одному множеству (их добавление привело бы к циклу).
Результат работы: алгоритм Крускала выполнил 1 предварительную сортировку (для 5 рёбер) и ровно 3 итерации основного цикла, в рамках которого было сделано 3 проверки на принадлежность к множествам и 3 операции объединения. Остальные рёбра были отсечены условием остановки.
Пример работы алгоритма Прима
Алгоритм пошагово строит дерево, начиная с одной произвольной вершины, и на каждом шаге добавляет самое короткое ребро, связывающее уже построенное дерево с оставшимися вершинами.
Инициализация:
Множество посещённых вершин (внутри MST): {1}.
Множество непосещённых вершин: {2,3,4}.
Минимальные расстояния до дерева dist: dist[1] = 0, dist[2] = ∞, dist[3] = ∞, dist[4] = ∞.
Шаг 1. Текущая вершина 1.
Рассматриваем рёбра из вершины 1 к непосещённым соседям:
К вершине 2: вес 5. Обновляем dist[2] = min(∞, 5) = 5.
К вершине 4: вес 3. Обновляем dist[4] = min(∞, 3) = 3.
Состояние dist для непосещённых {2,3,4}: [dist[2] = 5, dist[3] = ∞, dist[4] = 3].
Шаг 2. Выбираем вершину с минимальным dist – это вершина 4 (dist[4] = 3).
Добавляем вершину 4 в MST. Добавленное ребро: (1 – 4), вес 3.
Множество посещённых: {1,4}. Множество непосещённых: {2,3}.
Рассматриваем рёбра из вершины 4 к непосещённым соседям:
К вершине 2: вес 4. Обновляем dist[2] = min(5, 4) = 4.
К вершине 3: вес 1. Обновляем dist[3] = min(∞, 1) = 1.
Состояние dist для непосещённых {2,3}: [dist[2] = 4, dist[3] = 1].
Шаг 3. Выбираем вершину с минимальным dist – это вершина 3 (dist[3] = 1).
Добавляем вершину 3 в MST. Добавленное ребро: (4 – 3), вес 1.
Множество посещённых: {1,4,3}. Множество непосещённых: {2}.
Рассматриваем рёбра из вершины 3 к непосещённым соседям:
К вершине 2: вес 2. Обновляем dist[2] = min(4, 2) = 2.
Состояние dist для непосещённых {2}: [dist[2] = 2].
Шаг 4. Выбираем оставшуюся вершину 2 (dist[2] = 2).
Добавляем вершину 2 в MST. Добавленное ребро: (3 – 2), вес 2.
Множество посещённых: {1,2,3,4}. Непосещённых нет.
Результат работы: алгоритм Прима выполнил 4 шага (по числу вершин), на каждом из которых выбиралась оптимальная вершина и проверялись её смежные рёбра, совершив в сумме 5 проверок рёбер (по числу рёбер в графе).
