Венгерский алгоритм решения задачи о назначениях — различия между версиями
Sementry (обсуждение | вклад) м |
Sementry (обсуждение | вклад) м (кое-что исправил) |
||
Строка 1: | Строка 1: | ||
− | Венгерский алгоритм, | + | Венгерский алгоритм — алгоритм, решающий задачу о назначениях за полиномиальное время. Оригинальная версия была придумана и разработана Х. Куном в 1955 году и имела асимптотику <tex> O(n^4) </tex>, но позже Эдмонс и Карп (а также, независимо от них, Томидзава) показали, что можно улучшить ее до <tex> O(n^3) </tex>. |
== Постановка задачи == | == Постановка задачи == | ||
Строка 11: | Строка 11: | ||
Если веса всех ребер графа, инцидентных какой-либо вершине, изменить на одно и то же число, то в новом графе оптимальное паросочетание будет состоять из тех же ребер, что и в старом. | Если веса всех ребер графа, инцидентных какой-либо вершине, изменить на одно и то же число, то в новом графе оптимальное паросочетание будет состоять из тех же ребер, что и в старом. | ||
|proof= | |proof= | ||
− | Полное паросочетание для каждой вершины содержит ровно одно ребро, инцидентное этой вершине. При изменении весов всех ребер, инцидентных | + | Полное паросочетание для каждой вершины содержит ровно одно ребро, инцидентное этой вершине. Указанная операция изменит на одно и то же число вес любого паросочетания. При изменении весов всех ребер, инцидентных данной вершине, на одно и то же число, выбранное ребро останется оптимальным. |
}} | }} | ||
Строка 19: | Строка 19: | ||
|statement= | |statement= | ||
Выделим в множествах <tex>X</tex> и <tex>Y</tex> подмножества <tex>X', Y'</tex>. Если прибавить ко всем весам ребер, инцидентных вершинам из <tex>X</tex>, прибавить, а потом от всех весов ребер, инцидентных вершинам из <tex>Y</tex>, отнять <tex>d = \min \{c(x, y)|x \in X', y \in Y\backslash Y'\}</tex>, то: | Выделим в множествах <tex>X</tex> и <tex>Y</tex> подмножества <tex>X', Y'</tex>. Если прибавить ко всем весам ребер, инцидентных вершинам из <tex>X</tex>, прибавить, а потом от всех весов ребер, инцидентных вершинам из <tex>Y</tex>, отнять <tex>d = \min \{c(x, y)|x \in X', y \in Y\backslash Y'\}</tex>, то: | ||
− | # | + | # Веса всех ребер графа останутся неотрицательными. |
# Веса ребер вида <tex>xy</tex>, где <tex>x \in X', y \in Y'</tex> или <tex>x \in X \backslash X', y \in Y \backslash Y'</tex>, не изменятся. | # Веса ребер вида <tex>xy</tex>, где <tex>x \in X', y \in Y'</tex> или <tex>x \in X \backslash X', y \in Y \backslash Y'</tex>, не изменятся. | ||
|proof= | |proof= | ||
Рассмотрим матрицу весов графа. Не умаляя общности, можно сказать, что множества <tex> X' </tex> и <tex> Y' </tex> состоят из первых элементов множеств <tex> X </tex> и <tex> Y </tex> соответственно (мы упорядочиваем множества по номерам вершин). Тогда вся матрица делится на 4 блока: | Рассмотрим матрицу весов графа. Не умаляя общности, можно сказать, что множества <tex> X' </tex> и <tex> Y' </tex> состоят из первых элементов множеств <tex> X </tex> и <tex> Y </tex> соответственно (мы упорядочиваем множества по номерам вершин). Тогда вся матрица делится на 4 блока: | ||
− | <table border = '1' bordercolor = 'black' rules = ' | + | <table border = '1' bordercolor = 'black' rules = 'all' cellpadding = '5'> |
<tr> | <tr> | ||
<td> </td> | <td> </td> | ||
Строка 42: | Строка 42: | ||
</table> | </table> | ||
− | Веса группы <tex> A </tex> будут сначала увеличены, а потом уменьшены на <tex> d </tex>, поэтому они не изменятся, веса группы <tex> D </tex> вообще изменяться не будут. Все веса группы <tex> B </tex> будут уменьшены на <tex> d </tex>, но <tex> d </tex> | + | Веса группы <tex> A </tex> будут сначала увеличены, а потом уменьшены на <tex> d </tex>, поэтому они не изменятся, веса группы <tex> D </tex> вообще изменяться не будут. Все веса группы <tex> B </tex> будут уменьшены на <tex> d </tex>, но <tex> d </tex> — минимум среди этих весов, поэтому они останутся неотрицательными. |
}} | }} | ||
Строка 63: | Строка 63: | ||
# Ищем в текущем графе полное паросочетание из ребер нулевого веса: | # Ищем в текущем графе полное паросочетание из ребер нулевого веса: | ||
# | # | ||
− | # | + | #* Если оно найдено, то желаемый результат достигнут, алгоритм закончен. |
− | # | + | #* В противном случае, покроем нули матрицы весов минимальным количеством строк и столбцов (это не что иное, как нахождение минимального контролирующего множества в двудольном графе). Теперь применим преобразование из леммы 2, взяв в качестве <tex> X' </tex> и <tex> Y' </tex> вершины левой и правой долей минимального контролирующего множества. Очевидно, после его выполнения в матрице весов появится новый нуль. После этого перейдем к шагу 1. |
== Анализ времени работы == | == Анализ времени работы == | ||
− | Поиск максимального паросочетания или минимального контролирующего множества в двудольном графе совершается за <tex> O(n^2) </tex> операций. При каждом повторении шагов 1-3 в матрице весов появляется новый нуль, который увеличивает размер максимального паросочетания хотя бы на 1, поэтому всего будет совершено <tex> O(n) </tex> итераций внешнего цикла. Поэтому суммарная асимптотика работы данного алгоритма | + | Поиск максимального паросочетания или минимального контролирующего множества в двудольном графе совершается за <tex> O(n^2) </tex> операций. При каждом повторении шагов 1-3 в матрице весов появляется новый нуль, который увеличивает размер максимального паросочетания хотя бы на 1, поэтому всего будет совершено <tex> O(n) </tex> итераций внешнего цикла. Поэтому суммарная асимптотика работы данного алгоритма — <tex> O(n^3) </tex>. |
== Ссылки == | == Ссылки == | ||
+ | * [http://ru.wikipedia.org/wiki/Венгерский_алгоритм Венгерский алготитм в Википедии] | ||
+ | * [http://rain.ifmo.ru/cat/view.php/vis/graph-flow-match/hungarian-2002 Визуализатор алгоритма] | ||
* [http://acm.mipt.ru/twiki/bin/view/Algorithms/HungarianAlgorithmCPP?sortcol=5&table=2&up=0 Реализация венгерского алгоритма на C++] | * [http://acm.mipt.ru/twiki/bin/view/Algorithms/HungarianAlgorithmCPP?sortcol=5&table=2&up=0 Реализация венгерского алгоритма на C++] | ||
− | |||
− | |||
== Литература == | == Литература == | ||
− | * Асанов М., Баранский В., Расин В. | + | * Асанов М., Баранский В., Расин В. — Дискретная математика: Графы, матроиды, алгоритмы — 2010, 368 стр. |
[[Категория: Задача о потоке минимальной стоимости]] | [[Категория: Задача о потоке минимальной стоимости]] |
Версия 01:24, 6 января 2012
Венгерский алгоритм — алгоритм, решающий задачу о назначениях за полиномиальное время. Оригинальная версия была придумана и разработана Х. Куном в 1955 году и имела асимптотику
, но позже Эдмонс и Карп (а также, независимо от них, Томидзава) показали, что можно улучшить ее до .Содержание
Постановка задачи
Пусть дан взвешенный полный двудольный граф
, нужно найти в нем полное паросочетание минимального веса. Вес паросочетания определяется как сумма весов его ребер.Некоторые полезные утверждения
Лемма: |
Если веса всех ребер графа, инцидентных какой-либо вершине, изменить на одно и то же число, то в новом графе оптимальное паросочетание будет состоять из тех же ребер, что и в старом. |
Доказательство: |
Полное паросочетание для каждой вершины содержит ровно одно ребро, инцидентное этой вершине. Указанная операция изменит на одно и то же число вес любого паросочетания. При изменении весов всех ребер, инцидентных данной вершине, на одно и то же число, выбранное ребро останется оптимальным. |
Далее будем рассматривать только графы с неотрицательной весовой функцией, так как, согласно этой лемме, задачу о назначениях на остальных графах можно свести к задаче о назначениях на них.
Лемма: | |||||||||
Выделим в множествах и подмножества . Если прибавить ко всем весам ребер, инцидентных вершинам из , прибавить, а потом от всех весов ребер, инцидентных вершинам из , отнять , то:
| |||||||||
Доказательство: | |||||||||
Рассмотрим матрицу весов графа. Не умаляя общности, можно сказать, что множества и состоят из первых элементов множеств и соответственно (мы упорядочиваем множества по номерам вершин). Тогда вся матрица делится на 4 блока: | |||||||||
Лемма: |
Если веса всех ребер графа неотрицательны и некоторое полное паросочетание состоит из ребер нулевого веса, то оно является оптимальным. |
Доказательство: |
Действительно, паросочетание с какими-то другими весами ребер имеет больший вес и оптимальным не является. |
Алгоритм
Доказанные ранее утверждения позволяют придумать схему алгоритма, решающего задачу о назначениях: нужно найти полное паросочетание из ребер нулевого веса в графе, полученном из исходного преобразованиями, описанными в первых двух леммах.
Алгоритм, решающий задачу, работает с графом, как с матрицей весов.
- Вычитаем из каждой строки значение ее минимального элемента. Теперь в каждой строке есть хотя бы один нулевой элемент.
- Вычитаем из каждого столбца значение его минимального элемента. Теперь в каждом столбце есть хотя бы один нулевой элемент.
- Ищем в текущем графе полное паросочетание из ребер нулевого веса:
-
- Если оно найдено, то желаемый результат достигнут, алгоритм закончен.
- В противном случае, покроем нули матрицы весов минимальным количеством строк и столбцов (это не что иное, как нахождение минимального контролирующего множества в двудольном графе). Теперь применим преобразование из леммы 2, взяв в качестве и вершины левой и правой долей минимального контролирующего множества. Очевидно, после его выполнения в матрице весов появится новый нуль. После этого перейдем к шагу 1.
Анализ времени работы
Поиск максимального паросочетания или минимального контролирующего множества в двудольном графе совершается за
операций. При каждом повторении шагов 1-3 в матрице весов появляется новый нуль, который увеличивает размер максимального паросочетания хотя бы на 1, поэтому всего будет совершено итераций внешнего цикла. Поэтому суммарная асимптотика работы данного алгоритма — .Ссылки
Литература
- Асанов М., Баранский В., Расин В. — Дискретная математика: Графы, матроиды, алгоритмы — 2010, 368 стр.