Максимальное паросочетание Пусть дан некоторый невзвешенный неориентированный граф. Паросочетанием в этом графе называется такое подмножество его рёбер, что никакие два ребра не смежны. Максимальное же паросочетание – это паросочетание, в котором максимальное возможное количество рёбер. Алгоритм поиска максимального паросочетания в произвольном графе есть достаточно сложная, хотя и решаемая с полиномиальной сложностью задача. Для двудольных графов (у которых существует такое разбиение множества вершин на две части (доли), что концы каждого ребра принадлежат разным долям) существуют довольно простые и эффективные алгоритмы для нахождения максимального паросочетания. Наиболее известная задача на применение подобных алгоритмов имеет следующую формулировку: "Имеется X мальчиков и Y девочек. Каждый согласен танцевать на балу только с определёнными индивидами противоположного пола, причём это отношение коммутативно – если мальчик согласен танцевать с какой-то девочкой, то она тоже согласна танцевать с ним и наоборот. Организаторам бала необходимо набрать наибольшее количество пар на танец. Логично, что каждая персона танцует не более, чем с одним другим". На основе данных задачи можно построить двудольный граф, в котором вершины одной доли обозначают мальчиков, а другой – девочек. Две вершины соединяются ребром, если соответствующие мальчик и девочка согласны танцевать друг с другом. Построив в данном графе максимальное паросочетание, мы и сформируем необходимое множество пар. Условие задачи Пусть есть граф G=(V, E). Подмножество его ребер, такое что никакие два ребра из этого подмножества не инцидентны какой-либо одной вершине из V, называется паросочетанием. Задача определения максимального подмножества таких ребер называется задачей нахождения максимального паросочетания. Полным паросочетанием называется паросочетание, в котором участвуют (в качестве концов ребер) все вершины графа. Очевидно, что любое полное паросочетание является также максимальным паросочетанием. Рассматриваемый алгоритм Данный алгоритм поиска максимального паросочетания использует метод, известный как "чередующиеся цепи". Пусть M — паросочетание в графе G. Вершину v будем называть парной, если она является концом одного из ребер паросочетания M. Путь, соединяющий две непарные вершины, в котором чередуются ребра, входящие и не входящие в множество M, называется чередующейся (аргументальной) цепью относительно M. Очевидно, что чередующаяся цепь должна быть нечетной длины, начинаться и заканчиваться ребрами, не входящими в множество M. Также ясно, что имея чередующуюся цепь P, мы можем увеличить паросочетание M, удалив из него те ребра, которые входят в цепь P, и вместо удаленных ребер добавить ребра из цепи P, которые первоначально не входили в паросочетание M. Это новое паросочетание можно определить как M^P, где ^ обозначает симметрическую разность множеств M и P, т. е в новое множество паросочетаний войдут те ребра, которые входят или в множество M, или в множество P, но не в оба сразу. Паросочетание M будет максимальным тогда и только тогда, когда не будет существовать чередующейся цепи относительно M. Сначала рассмотрим способ построения чередующихся цепей относительно паросочетания М. Рассмотрим двудольный граф G с множеством вершин разбитым на два подмножества V1 и V2. Мы будем строить граф чередующейся цепи по уровням i = 0, 1, 2, …, используя процесс, подобный поиску в ширину. Граф чередующейся цепи уровня 0 содержит все непарные вершины из множества V1. На уровне с нечетным номером i добавляются новые вершины, смежные с вершинами уровня i - 1 и соединенные ребром, не входящим в паросочетание (это ребро тоже добавляется в строящийся граф). На уровне с четным номером i также добавляются новые вершины, смежные с вершинами уровня i - 1, но которые соединены ребром, входящим в паросочетание (это ребро тоже добавляется в граф чередующейся цепи). Процесс построения продолжается до тех пор, пока к графу чередующейся цепи можно присоединить новые вершины. Отметим, что нечетные вершины присоединяются к этому графу только на нечетном уровне. В построенном графе путь от любой вершины нечетного уровня до любой вершины уровня 0 является чередующейся цепью относительно М. Теперь можно описать алгоритм нахождения максимального паросочетания M для графа G=(V, E). 1. Сначала положим M=0 2. Далее ищем чередующуюся цепь P относительно M, и множество M заменяется на множество M^P 3. Шаг 2 выполняется до тех пор, пока существуют чередующиеся цепи относительно M Если таких цепей нет, то M — максимальное паросочетание. Определения Граф <M,N> называется двудольным, если множество его вершин разбито на два подмножества MB и ME и у любой дуги начало лежит в множестве MB, а конец в множестве ME. Множество дуг J ⊂ N называется паросочетанием, если у входящих в него дуг все начала и все концы различны. Назовем размером паросочетания мощность этого множества. Нас будет интересовать задача построения максимального паросочетания, т.е. паросочетания максимального размера. Эта задача интересна тем, что в ней проявляется принцип двойственности (однажды нам уже встречавшийся, когда мы рассматривали экстремальные задачи на перестановках). Именно, кроме названной задачи на максимум, будет введена еще одна задача — на минимум, причем значение целевой функции в задаче на минимум на любом допустимом решении оказывается не меньше, чем значение в задаче на максимум. Нам удастся построить одновременно допустимые решения для обеих задач с совпадающими значениями целевых функций, и из этого совпадения будет следовать, что оба решения оптимальны, т.е. на них достигаются соответственно максимум и минимум целевых функций. Итак, нужна задача на минимум. Назовем множество вершин Mc ⊂ M вершинным покрытием графа (используется также термин контрольное множество), если каждая дуга графа инцидентна какой-либо вершине из этого множества. Естественно назвать размером покрытия его мощность и ставить задачу о поиске минимального покрытия. Мы докажем, что эти две задачи находятся в двойственности. доказательство будет не совсем обычным — его основу составляет тот факт, что некий алгоритм завершает свою работу за конечное число шагов. Естественно. что нам нужно сначала познакомиться с этим алгоритмом. К счастью, он нужен не только для доказательства теоремы, он очень эффективно строит максимальное паросочетание. Матричное представление двудольного графа Представление двудольного графа обычной картинкой оказыввается не очень удобен: в «венике» дуг, идущих из одного множества в другое, трудно разбираться. Лучше нарисовать матрицу b[MB,ME], элементами которой будут пометки для дуг и пустые места в остальных случаях. Вы видите слева матричное изображение графа, в котором MB = A..H, ME = 1..9, а в элементах соответствующих дугам стоит «пулька» — серый кружок. В этом графе 13 дуг. Вершинное покрытие будет изображаться штриховкой строк и столбцов матрицы, соответствующих вершинам из покрытия. Если покрытие будет неполным и не все дуги будут им покрыты (назовем его предпокрытием), мы это легко обнаружим — какая-нибудь пулька будет лежать в незаштрихованной клетке. Справа изображено предпокрытие размера 5. Пульки с красными пометками составляют паросочетание, также размера 5. Забегая вперед, скажем, что элементам паросочетания поставлены в соответствие элементы предпокрытия, горизонтальна или вертикальна черточка на пульке зависит от того, в каком из двух множеств вершин лежит вершина, покрывающая данную дугу. Мы предложим алгоритм, в котором на каждой итерации будет либо увеличиваться размер паросочетания, либо одна из горизонтальных линий будет заменяться вертикальной (при увеличении паросочетания все вертикальные линии будут заменены горизонтальными). Естественно, что число таких замен не может превосходить размера паросочетания. Алгоритм завершается, когда предпокрытие станет покрытием (рисунок слева) Историю процесса можно изобразить графически (рисунок справа), путем, в котором итерации первого типа изображаются горизонтальными сдвигами, а второго типа — вертикальными. Решетка из точек показывает область, в которой должен лежать этот путь. Сразу видно, что число шагов ограничено квадратом размера получаемого паросочетания. Построение максимального паросочетания СОСТОЯНИЕ описываемого вычислительного процесса будет определяться текущим паросочетанием J и его разбиением на два подмножества J = J_B ∪ J_E По этим двум множествам строится предпокрытие M_C = M_B ∪ M_E где M_B — множество начал дуг из J_B, а M_E — множество концов дуг из J_E. Таким образом, размер паросочетания и предпокрытия совпадают. Каждой дуге, входящей в множество J_E, сопоставляется дуга с тем же концом, называемая ее дублером, и положительное число, называемое ее рангом. ПЕРВОНАЧАЛЬНО множество J пусто, поэтому никаких вопросов о том, откуда берется ранги и дублеры, не возникает, при появлении элементов всё, что требуется появится. АЛГОРИТМ представляет собой цикл, выполняемый до тех пор, пока в графе есть хотя бы одна дуга, не покрываемая подпокрытием (это и означает, что предпокрытие не является покрытием). while EXISTS_UNCOVERED_ARC(j0) do TREAT_ARC(j0) od; В поиске непокрытой дуги ничего особенного нет, нам существено, что делается в псевдооператоре TREAT_ARC(j0). В нем можно выделить четыре случая, в зависимостри от того, инцидентны ли начало и конец j0 каким-либо дугам из паросочетания. TREAT_ARC(j0) ≡ iB := iBeg(j0); iE := iEnd(j0); if IS_FREE_BEG(iE) THEN if IS_FREE_END(iB) THEN ADD_ARC_TO_J(j0); else COVER_J(j0); fi else if IS_FREE_END(iE) THEN CHAIN_CORRECTION_OF_J(j0); else COVER_J_MOD(j0); fi fi Вот мы и пришли к самому главному. 1. Самый простой случай описывается блоком ADD_ARC_TO_J(j0) — ничто не мешает добавить дугу j0 к паросочетанию. Нетривиально, что при таком добавлении все дуги паросочетания переносятся в множество J_B с соответствующим изменением всей сопутствующей информации. 2. Блок COVER_J(j0) — это уже настоящая работа. Алгоритм выполняет этот блок в том случае, когда в паросочетании есть дуга j1 с тем же концом, что и j0. Точнее, дуга j1 содержится в множестве J_B — это ясно из того, что дуга j0 не покрыта. Ну, так покроем ее, переведя дугу j1 из J_B в J_B. Дугу j0 назначим ее дублером, а ранг положим равным 1. Разумеется, при этом изменении структуры паросочетания пересчитывается вся сопровождающая информации. 3. Блок COVER_J_MOD(j0) очень похож на предыдущий. Алгоритм выполняет этот блок в том случае, когда в паросочетании есть дуга j1 с тем же концом, что и j0, и дуга j2 с тем же началом, что и j0. Как раньше, дуга j1 содержится в множестве J_B;, а дуга j2 — в множестве J_E. Дуге j2 назначен какой-то положительный ранг k. Переведем дугу j1 из J_B в J_E, назначив j0 ее дублером, а k+1 ее рангом. Благодаря рангам, мы видим, что из дуг, переведенных в J_E составляется своеобразный лес: в каждом дереве этого леса корнем (вершиной) яявляется дуга нулевого ранга, к ней прицеплены дуги первого ранга, и т. д. 4. Блок CHAIN_CORRECTION_OF_J(j0) выполняет самую изящную операцию. Он завершает цепочку исправления. Дело в том, что второй блок вводит в рассмотрение не использованный ранее конец дуги. Трудность в том, что для введения в паросочетание новой дуги нужно еще и неиспользованное начало. Когда не удается найти такие начало и конец в одной дуге, их находят в разных дугах и выполняют обмены, возможно многочисленные. В блоках 2 и 3 строятся такие цепочки замен, но завершение построения возникает, когда срабатывает блок 4. Обратимся к формальному описанию. Алгоритм выполняет этот блок в том случае, когда в паросочетании есть дуга j2 с тем же началом, что и j0 и с не встречавшимся ранее концом. Дуга j2 находится в множестве J_E, ей j2 назначен какой-то положительный ранг k. Начитая от нее идет цепь нечетной звенности, 2k+1, в которой на четных местах стоят дуги из паросочетания (множество J_Out), а на нечетных новые дуги (множество J_In). Преобразуем паросочетание J := J∪J_In\J_Out отчего паросочетание станет на одну дугу больше. Как в случае 1, все дуги переведем в J_B. Очевидно, что этот алгоритм может работать до тех пор, пока есть дуги, не покрытые предпокрытием. Вместе с тем, как мы видели, при работе этого алгоритма наблюдается некоторая монотонность: время от времени размер паросочетания увеличивается на единицу, число шагов между этими увеличениями не превосходит текущего размера паросочетания, и размер паросочетания ограничен. Значит, на каком-то шаге предпокрытие станет покрытием, и мы получим паросочетание и покрытие одного размера. Теорема о максимальном паросочетании Теорема. Размер максимального паросочетания равен размеру минимального вершинного покрытия. Доказательство. Размер любого паросочетания не превосходит размера любого покрытия, так как на каждую дугу паросочетания требуется по одной покрывающей ее вершине, и по условию все эти вершины различны. Отсюда следует, что размер максимального паросочетания не превосходит размера минимального покрытия. Поскольку есть алгоритм, который строит паросочетание и покрытие одного размера, на них достигаются соответственно максимум и минимум. Следствия из теоремы о максимальном паросочетании Из этой теоремы легко получаются как простые следствия несколько важных «именных» теорем. Первое следствие связано с именем норвежского математика Ойстейна Оре (1899-1968). Пусть задан двудольный граф <M,N>, где M = MB ∪ ME. Обозначим через Γ(I) множество концов дуг, начинающихся в I. Назовем дефицитом графа величину δ = max { |I| − |Γ(I)| | J⊂MB }. Следствие 1 (теорема Кёнига-Оре). Размер максимального паросочетания равен разности мощности множества начал и дефицита графа. Доказательство. Можно искать вершинное покрытие в виде пары ( MB \ I,Γ(I) ) (каждая дуга либ о кончается в Γ(I), либо начинается не в I). Если так, то размер минимального покрытия равен min { |MB \ I| + |Γ(I)| } = |MB| − max { |I| − |Γ(I)| } = |MB| − δ. Второе следствие было получено раньше, оно выглядит проще и легко получается из предыдущего. Связано оно с именем американского математика Филипа Холла (19041982) и часто называется теоремой Холла о системе различных представителей — Холл формулировал ее в других терминах. Следствие 2 (теорема Кёнига-Холла). Для того чтобы размер максимального паросочетания равнялся мощности множества начал, необходимо и достаточно чтобы для любого множества I размер Γ(I) был не меньше размера I. Доказательство. Утверждение прямо вытекает из предыдущего.