3.2. Поиск минимального остова в связном неориентированном взвешенном графе
Задача. Дан граф G(V,E) – связный, неориентированный, взвешенный. Нам нужно выделить в нем минимальный (по суммарному весу ребер) связный граф с теми же вершинами – остов (остовное дерево), т.е. исключить из графа часть ребёр таким образом, чтобы сумма весов оставшихся была минимальна, и получившийся граф по-прежнему был связным.
Идея решения. Для решения этой задачи обычно применяется алгоритм Краскалла (классический пример т.н. «жадного алгоритма»).
Алгоритм Краскалла
Сначала упорядочиваем все ребра по возрастанию весов.
Заводим таблицу: в левой колонке список ребер, в правой компоненты связности.
В первой строчке список ребер пустой и все компоненты связности одновершинные. Берем минимальное по стоимости (по весу) ребро включаем его в список ребер. Соответствующие две вершины объединяем в одну компоненту связности.
Берем следующее по стоимости (весу) ребро, добавляем к содержимому предыдущей строчки левого столбца; объединяем компоненты связности. Если концы ребра уже принадлежат одной и той же компоненте связности, то данное ребро в состав минимального остова не включается.
Повторяем эти операции до тех пор, пока все вершины не окажутся в одной единственной компоненте связности (для этого потребуется включить в состав остова ровно n-1 ребро).
Пример. Пусть имеется граф, изображенный на рисунке 3.1.
Рисунок 3.1. – Исходный граф
Решение. Составим таблицу, в которой будем отражать порядок выбора ребер для минимального остова.
Подграф (ребра) | Связи (компоненты связности) |
Пустой | 1,2,3,4,5,6,7 |
(1,7) – минимально по цене | (1,7),2,3,4,5,6 |
(1,7) + (3,4) | (1,7),2,(3,4),5,6 |
(1,7)(3,4) + (2,7) | (1,2,7),(3,4),5,6 |
(1,7)(3,4) (2,7) + (2,3) | (1,2, 3,4,7),5,6 |
(1,7)(3,4) (2,7) (2,3) | (1,2, 3,4,7),5,6 |
(1,7)(3,4) (2,7) (2,3) | (1,2, 3,4,7),5,6 |
(1,7)(3,4) (2,7) (2,3) + (4,5) | (1,2, 3,4,5 ,7),6 |
(1,7)(3,4) (2,7) (2,3)(4,5) | (1,2, 3,4,5 ,7),6 |
(1,7)(3,4) (2,7) (2,3) (4,5) + (1,6) | (1,2, 3,4,5 ,6,7) |
Пояснения.
* - вершины 3 и 7 уже находятся в одной компоненте связности на момент включение в остов ребра (3,7);
** - следующее по весу ребро – (4,7), однако вершины 4 и 7 уже находятся в одной компоненте связности на момент включения в остов ребра (4,7);
*** - аналогично.
Теорема 3.1. Алгоритм Краскалла всегда выдает минимальный по стоимости остов.
Доказательство. Заметив, что в результате работы алгоритма Краскалла мы всегда получаем дерево (так как мы не включаем ребра, вершины которых лежат в одной компоненте связности, следовательно возникновение циклов невозможно).
Предположим, что получившееся в результате работы алгоритма Краскалла дерево не минимально по своей стоимости и существует другое, предположительно «оптимальное» дерево. Например, такое, как на рисунке 3.2. Цифрами в кружочках обозначены ребра в порядке их добавления в дерево.
Рисунок 3.2.
Рассмотрим подробно тот этап работы алгоритма Краскалла, на котором мы впервые добавили в остов «неправильное» ребро, т.е. то, которого нет в «оптимальном» дереве. Первые два по породку добавления ребра (3,6) и (6,5) присутствуют в «оптимальном» дереве. Расхождение начинается после добавление ребра (7,8).
Добавил ребро (7,8) к «оптимальному» дереву (см. рис 3.3):
Рисунок 3.3.
При этом в «оптимальном» дереве возникает цикл, и мы можем убрать из него любое ребро, например, (1,2), участвующее в цикле, и при этом граф останется связанным. Заметим, что при этом общий вес полученного дерева будет меньше веса «оптимального» дерева, т.к. ребро (7,8) самое меньшее по весу в этом цикле (т.к. в алгоритме Краскалла мы по очереди добавляем все ребра, начиная с самого минимального по весу, меньше ребра (7,8) по весу только ребра (3,6) и (6,5), а они в этот цикл не входят). В этом примере мы можем построить меньший, чем предполагаемый «оптимальный», по суммарному весу остов.
Рисунок 3.4. – Минимальный остов.
Он отличается от «оптимального» заменой ребра (1,2) на меньшее по весу ребро (7,8).
Данные рассуждения можно обобщить для случая произвольного графа.
Теорема доказана.
Оценим трудоемкость работы алгоритма Краскалла
Пусть в графе было n вершин и k ребер (). При быстрой сортировке на первый эта работы алгоритма затрачиваетсяk logk действий. Далее нам потребуется ровно (n-1) результативных этапов (результативным будем считать этап работы алгоритма, в результате которого осуществляется добавление ребра к минимальному остову и слияние компонент связности), и не больше, чем k – (n-1) нерезультативных этапов. Нерезультативный этап состоит из одного сравнения – проверки принадлежности вершин добавляемого ребра на нахождение в одной компоненте связности. В случае же результативного этапа мы должны переприсвоить номера компонент связности n вершинам – итого n действий.
Таким образом, трудоемкость алгоритма Краскалла:
T(n) = (n-1) · n + (k – n + 1)·1 + k logk ≈ n2logn
Трудоемкость сортировки
Трудоемкость результативных этапов
Трудоемкость нерезультативных этапов
Следовательно, алгоритм Краскалла – полиномиальный.
- Основные понятия. Справочный материал
- Основные понятия
- 1.2. Справочный материал. Сравнение скорости роста основных функций
- 2 Новые быстрые версии старых алгоритмов
- 2.1. Сортировки массивов
- 2.1.1 Метод прямого выбора (SelectSort)
- 2.1.2 Быстрая сортировка методом двоичных вставок (MergeSort)
- 2.2. Преобразование Фурье (бпф)
- 2.2.1. Дискретное преобразование Фурье
- 2.2.2. Полубыстрое преобразование Фурье (ппф)
- 2.2.3. Быстрое преобразование Фурье (бпф)
- 2.3. Быстрая свертка
- 2.3.1. Понятие свертки
- 2.3.2. Обычный и быстрый алгоритм свертки
- 2.4. Быстрое умножение
- 2.4.1. Быстрое умножение чисел
- 1 Суммирование
- 4 Произведения чисел вдвое меньшей
- 2.4.2. Быстрое умножение матриц
- 2.4.3. Очень быстрое умножение числе (алгоритм Шенхаге – Штрассена)
- 3. Задачи на графах
- 3.1. Справочный материал
- 3.2. Поиск минимального остова в связном неориентированном взвешенном графе
- 3.3. Нахождение кратчайшего расстояния
- 3.3.1. Алгоритм Форда – Беллмана
- 3.3.2. Алгоритм Дейкстры
- 3.4. Нахождение диаметра, радиуса и центра графа
- 3.5. Задача об изоморфизме графов
- 3.6. Задача коммивояжера. Её решение методом ветвей и границ.
- Задачи динамического программирования
- Задачи динамического программирования. Её решение методом динамического программирования.
- 4.2. Задача об оптимальном наборе самолетом скорости и высоты
- 4.3. Задача грабителя (задача о рюкзаке)
- 4.4. Задача о перемножении матриц
- 5 Классы p и np
- 5.1 Машина Тьюринга
- 5.2 Недетерменированные машины Тьюринга(ндмт)
- 5.3 Сводимость. Np-полнота.
- 5.4 Иерархия по сложности. Труднорешаемые задачи.
- Классы сложности.
- 6 Неразрешимые задачи
- 6.1 Новая модель алгоритма вычислений.
- 6.2 Нумерация программ
- 6.3 Неразрешимые проблемы
- 6.4 Теорема об ускорении
- Лабораторные работы
- Расчетно-графическое задание
- Ответы к домашним заданиям