Алгоритм Каргера для нахождения минимального разреза
Алгоритм Каргера — рандомизированный алгоритм для нахождения минимального разреза в связном графе. Он был разработан Дэвидом Каргером (англ. David Karger) в 1993 году.
Основные определения
Пусть
— неориентированный мультиграф с множеством вершин и множеством ребер , и , .Определение: |
Стягиванием (англ. contraction) ребра
| называется следующая последовательность действий:
Определение: |
Мультивершиной (англ. supervertex) называется вершина, полученная из двух вершин стягиванием ребра между ними, каждая из которых, в свою очередь, может быть также мультивершиной. |
Определение: |
Стянутым графом (англ. contracted graph) называется граф, состоящий из двух мультивершин, полученный из исходного графа последовательным стягиванием произвольных ребер. |
Определение: |
Разрезом (англ. cut)
| называется разбиение множества на два множества и , удовлетворяющее следующим условиям:
Такой разрез часто называют также глобальным разрезом, чтобы отличать его от . -разреза
Определение: |
Вес разреза
| обозначается и вычисляется по формуле:
Задача поиска разреза минимальной веса (англ. min-cut problem) заключается в поиске разреза минимального веса среди всех возможных разрезов исходного графа. Эту задачу можно решить с помощью любого из алгоритмов поиска максимального потока, зафиксировав произвольную вершину в качестве истока и запуская его раз для всех возможных стоков. Если использовать быстрый алгоритм поиска максимального потока, работающий за , то время работы такого алгоритма поиска минимального разреза будет . Однако ниже описан существенно более простой в реализации и более быстрый алгоритм Каргера.
Алгоритм
Пусть нам дан граф
.minCut(): answer = INF; for i = 1..c curCut = getCut(); if curCut < answer answer = curCut; return answer;
Так как алгоритм вероятностный и функция
возвращает вес случайного потока, а не минимального, то для того, чтобы наверняка найти вес минимального, необходим вызвать эту функцию раз. Какое конкретное значение выбрать будет описано ниже. Реализация функции — это и есть основа алгоритма. Будем действовать следующим образом: пока вершин больше двух, будем выбирать случайное ребро и стягивать его. Когда в графе останется две вершины, то количество ребер между этими вершинами будет равно весу некоторого разреза исходного графа.getCut(): n = количество вершин в G; while n > 2 e = случайное ребро из G; contract(e); n--; m = количество ребер в G; return m;
Корректность алгоритма
Докажем корректность алгоритма. Для удобства доказательства и оценок вероятностей, будем считать, что мы ищем не просто вес минимального разреза, а величину конкретного минимального разреза. То есть зафиксируем какой-то один из минимальных разрезов, и если функция
вернет правильный вес, но посчитает его на другом минимальном разрезе, то будем считать, что ответ получен неверный. Это условие не ухудшает оценки вероятностей и время работы алгоритма.Лемма (1): |
Пусть — некоторая мультивершина, и - какие-то две из вершин, которые были стянуты в вершину . Тогда существует такой путь в исходном графе между вершинами и , что ко всем ребрам этого пути была применена операция стягивания. |
Доказательство: |
Рассмотрим подграф | исходного графа в который входят все ребра, которые были стянуты в вершину . Очевидно, что связен, а значит в нем существует путь между его любыми двумя вершина. Следовательно, существует путь между и , состоящий из стянутых ребер. Лемма доказана.
Лемма (2): |
Если стянуть некоторое ребро в графе G, то вес минимального разреза в графе будет не меньше чем вес минимального разреза в исходном графе . |
Доказательство: |
Составим биекцию между ребрами графов | и , не рассматривая ребра между вершинами и в графе . Очевидно, что это возможно, исходя из следующих соображений. Все ребра в , не инцидентные вершинам и , остались без изменений, а всем ребрам, инцидентным этим вершинам, по определению стягивания можно сопоставить новое ребро в . Пусть — минимальный разрез в графе , и, не уменьшая общности, . Рассмотрим разрез в графе . Исходя из биекции между ребрами и тем, что все ребра вида не пересекают разрез (так как ), то . Тогда если разрез в графе — минимален, вес минимального разреза в совпадает с весом минимального размера в . Если в существует разрез меньшего веса, то вес минимального разреза в больше чем в . Лемма доказана.
Лемма (3): |
Пусть — вес минимального потока в графе . Тогда . |
Доказательство: |
Заметим, что, чтобы выполнялось условие, степень каждой вершины должна быть не менее, чем лемме о рукопожатиях имеем, что . Лемма доказана. | . Действительно, пусть для некоторой вершины . Тогда , что противоречит условию. Далее, по
Лемма (4): |
Функция после своего выполнения получит стянутый граф соответствующий конкретному разрезу исходного графа тогда и только тогда, когда ни одно ребро, принадлежащее разрезу , не будет стянуто. |
Доказательство: |
Необходимость: От противного. Если некоторое ребро , принадлежащее разрезу в будет стянуто, то обе вершины и будут принадлежать одной мультивершине, а значит не соответствует разрезу . Противоречие.Достаточность: Пусть ни одно ребро, принадлежащее разрезу не было стянуто. Рассмотри произвольную пару вершин и в графе . Если алгоритм стянул и в одну мультивершину в , тогда по лемме 1. |