Венгерский алгоритм: задача о назначениях

Венгерский алгоритм - классический способ за полиномиальное время решить задачу о назначениях: распределить работников по работам так, чтобы суммарная стоимость была минимальной. Идея опубликована Гарольдом Куном в 1955 году (он сослался на работы венгров Кёнига и Эгервари - отсюда название), а в 1957 году Манкр показал оценку , позже улучшенную до . В современной формулировке это эталонный пример ЛП-двойственности: алгоритм одновременно строит допустимое назначение и допустимые двойственные переменные, а сильный двойственный результат гарантирует оптимальность.
Постановка задачи о назначениях
Дано работников, работ и матрица стоимостей , где - затраты, если работник выполнит работу . Нужно выбрать перестановку , минимизирующую
Если задача про максимум прибыли - переходим к минимуму через , где . Если работ больше, чем работников, или наоборот - добавляем фиктивные строки/столбцы с нулевой стоимостью.
Поставленная задача - частный случай минимального по весу совершенного паросочетания в полном двудольном графе , где левые вершины - работники, правые - работы, а вес ребра равен . Полный перебор перестановок даёт вариантов - для это уже , неприемлемо. Венгерский алгоритм закрывает задачу за .
Идея ЛП-двойственности
Запишем задачу как линейное программирование с переменными :
Полиэдр такой задачи - это политоп Биркгофа (двунаправленно стохастические матрицы), и его вершины - именно перестановочные матрицы. Поэтому ЛП-релаксация даёт целочисленный оптимум: задача о назначениях точно решается симплекс-методом, но в нём не гарантировано.
Двойственная задача: найти потенциалы такие, что
По теореме сильной двойственности оптимумы прямой и двойственной задач совпадают. Условие дополняющей нежёсткости: только если . Рёбра, на которых равенство достигнуто, называют жёсткими (tight); они образуют равенственный подграф . Если в нём существует совершенное паросочетание - это и есть оптимальное назначение.
Венгерский алгоритм поддерживает допустимые и постепенно увеличивает паросочетание в . Когда оно становится совершенным - оптимум найден.
Алгоритм по шагам
Классическая «школьная» формулировка работает прямо с матрицей и оперирует нулями: место занимает . Шаги:
- Редукция строк. Из каждой строки вычесть её минимум. В каждой строке появляется хотя бы один ноль.
- Редукция столбцов. Из каждого столбца вычесть его минимум. В каждом столбце появляется хотя бы один ноль.
- Покрытие нулей. Найти минимальное число линий (горизонтальных и вертикальных), покрывающих все нули матрицы. Если линий ровно - назначение возможно: выбрать независимых нулей (по одному в каждой строке и каждом столбце) и выписать перестановку .
- Обновление. Если линий меньше , пусть - минимум среди непокрытых элементов. Вычесть из всех непокрытых строк и прибавить к покрытым столбцам (или, эквивалентно: вычесть из непокрытых элементов, прибавить к дважды покрытым, не трогать однократно покрытые). Это сохраняет двойственную допустимость, создаёт новый ноль и не теряет старых. Вернуться к шагу 3.
Поиск минимального покрытия нулей сводится к теореме Кёнига: число линий в покрытии равно размеру максимального паросочетания на нулях. То есть алгоритм Куна для невзвешенного двудольного графа здесь - внутренняя процедура.
Сложность: от к
Каждая итерация добавляет хотя бы одну новую жёсткую дугу или увеличивает паросочетание. Прямолинейная реализация Манкра 1957 года тратит на поиск паросочетания и на обновление, всего - итераций тоже .
Оптимизация до держит для каждого правого узла минимум по уже обработанным левым узлам и пересчитывает его за при добавлении нового левого узла. Тогда поиск увеличивающей цепи через жёсткий подграф вместе с обновлением потенциалов укладывается в на итерацию, а итераций ровно - по одной на каждую вершину левой доли. Итого:
Это та самая «Jonker–Volgenant»-реализация (1987), которая используется в большинстве библиотек, включая SciPy linear_sum_assignment.
Корректность
Алгоритм одновременно поддерживает три инварианта:
- Двойственная допустимость: после редукции и каждого обновления для всех . На покрытых строках/столбцах знак сохраняется явно, на непокрытых - за счёт правильного знака .
- Жёсткое паросочетание: текущее состоит только из жёстких рёбер ().
- Прогресс: за итерацию либо растёт , либо появляется новое жёсткое ребро. Поэтому через итераций (а в -варианте - через ровно внешних итераций) .
Когда , паросочетание совершенно, все его рёбра жёсткие, и
Правая часть - значение двойственной задачи, и по сильной двойственности оно совпадает с оптимумом прямой. Значит, найденное назначение оптимально.
Типовая задача 4 на 4
Матрица стоимостей:
Редукция строк (минимумы ):
Редукция столбцов (минимумы ):
Минимальное покрытие нулей - 4 линии (строки 2 и 4, столбцы 2 и 3). Назначение существует: например, , , , . Сумма . Это и есть оптимум.
Применения
- Распределение задач. Сотрудники на проекты, водители на маршруты, врачи на смены - везде, где у пары есть числовая «стоимость» и нужно покрыть все позиции.
- Шипп-планирование. Назначение судов на причалы, грузовиков на доки, контейнеров на платформы. Часто матрица не квадратная - её дополняют фиктивными столбцами.
- Computer vision matching. Сопоставление детекций между кадрами в трекинге (SORT, DeepSORT), ключевых точек, ассоциация лиц с треками. Стоимость - расстояние между признаками; алгоритм даёт глобальный оптимум.
- Экономика. Двусторонние рынки с трансфертами - модель Шепли-Шубика; венгерский алгоритм находит конкурентное равновесие.
Сравнение с потоковыми и аукционным алгоритмами
- Min-cost max-flow. Задача о назначениях - частный случай: исток → работники → работы → сток, пропускные способности 1, стоимости . SSP с потенциалами даёт . Гибче (другие ограничения, не-квадратные матрицы), но константа выше - базовый поток без стоимостей считается алгоритмом Эдмондса-Карпа.
- Аукционный алгоритм Бертсекаса (1979). Работники-«покупатели» итеративно повышают цены работ. в худшем случае, хорошо параллелится. Применяется в радарном трекинге.
- Венгерский (Куна-Манкр) - классика, лучшая средняя константа на квадратной плотной матрице, гарантированно.
Для до - почти всегда венгерский. Для и разреженных матриц - потоковые или аукцион.
Частые ошибки
- Забывают про двойную редукцию. Только строки или только столбцы - не работает: должна быть и горизонтальная, и вертикальная.
- Неправильное обновление при недостающем покрытии. Нужно вычитать из непокрытых строк (или элементов) и прибавлять к покрытым столбцам - иначе нарушится двойственная допустимость и алгоритм зациклится.
- Применяют к не-квадратной матрице без дополнения. Если , нужно дополнить фиктивными работниками/работами с нулевой (или для максимума) стоимостью. Иначе совершенного паросочетания не будет.
- Решают «максимум» как «минимум» без замены знака. Корректно: с . Просто менять знак нельзя: появятся отрицательные значения и редукция выдаст ерунду.
- Считают, что любое покрытие минимально. Покрытие должно быть минимальным по числу линий (по теореме Кёнига = размеру максимального паросочетания на нулях). Если линий , но они не минимальны, можно ошибочно решить, что назначение нашлось.
FAQ
Чем венгерский алгоритм отличается от алгоритма Куна? Алгоритм Куна решает невзвешенную задачу - найти максимальное паросочетание в двудольном графе, . Венгерский алгоритм работает со взвешенной задачей и минимизирует сумму стоимостей при покрытии всех вершин, . Кун - внутренняя процедура венгерского алгоритма на шаге поиска покрытия нулей.
Почему сложность именно , а не быстрее? Внешний цикл - итераций (по числу левых вершин). На каждой итерации поиск увеличивающей цепи через жёсткий подграф плюс обновление потенциалов стоят . Существуют асимптотически более быстрые методы для специальных классов матриц (например, для двоичных), но в общем случае - лучшая известная оценка для строго детерминированных алгоритмов.
Как обрабатывать прямоугольную матрицу ?
Дополнить меньшую сторону фиктивными вершинами с нулевой стоимостью до квадратной. После решения отбросить назначения на фиктивные элементы - они и так не несут затрат. Современные реализации (SciPy linear_sum_assignment) делают это автоматически.
Коротко
Венгерский алгоритм решает задачу о назначениях за : минимизирует сумму стоимостей при распределении работников по работам. Идея - ЛП-двойственность: алгоритм поддерживает допустимые двойственные переменные и постепенно увеличивает совершенное паросочетание в равенственном подграфе. Школьная формулировка с матрицей: вычитание минимумов из строк и столбцов, поиск минимального покрытия нулей линиями, обновление матрицы вычитанием минимума по непокрытым элементам. Корректность гарантируется сильной двойственностью ЛП. Применяется в логистике, computer vision, биоинформатике, экономике двусторонних рынков. На больших и разреженных задачах уступает потоковым и аукционным алгоритмам, но для плотных квадратных матриц до - стандарт.
Читайте также

Алгоритм Прима - как построить остовное дерево по шагам
Разбираем, как алгоритм Прима шаг за шагом строит минимальное остовное дерево графа: идея жадного выбора, лемма о разрезе и трассировка на конкретном примере.

Хроматический полином графа: как считать и применять
Что такое хроматический полином графа, как его вычислить через теорему об удалении и стягивании ребра, свойства коэффициентов и связь с хроматическим числом. Формулы и пошаговый пример.

Метод штрафных функций: оптимизация с ограничениями
Метод штрафных функций в оптимизации: внешние и внутренние штрафы, барьерные функции, сведение задачи с ограничениями к безусловной, выбор коэффициента штрафа и пошаговая схема решения.