В статье описывается один из сильно полиномиальных алгоритмов решения задачи о поиске потока минимальной стоимости.
Алгоритм
Приведенный алгоритм основан на идее алгоритма Клейна отмены цикла отрицательного веса. Выбор цикла минимального среднего веса вместо случайного делает алгоритм сильно полиномиальным.
Определение: |
Сильно полиномиальными (англ. strongly polynomial) в контексте данной задачи называются алгоритмы, чья сложность полиномиально зависит от [math]V[/math] и [math]E[/math]. |
Описание
Обозначим как [math]c_{f}(C)[/math] остаточную пропускную способность цикла [math]C[/math] при протекании в сети потока [math]f[/math].
Cтоимость цикла [math]C[/math] обозначим за [math]p(C)[/math], а длину (число входящих в него ребер) — за [math]\texttt{len}(C)[/math].
Определение: |
Средним весом (англ. mean weight) цикла будем называть отношение его стоимости к его длине [math]\mu (C)=\dfrac{p(C)}{\texttt{len}(C)}[/math] |
Данный алгоритм заключается в последовательной отмене циклов минимального среднего веса в остаточной сети посредством их насыщения. Алгоритм работает до тех пор, пока минимальный средний вес циклов не окажется положительным, что будет означать, что поток минимальной стоимости найден.
Более формально:
- Шаг [math]1[/math]. Рассмотрим некоторый поток [math]f[/math].
- Шаг [math]2[/math]. Найдем цикл [math]C[/math], обладающий наименьшим средним весом. Если [math]\mu (C) \geqslant 0[/math], то [math]f[/math] — поток минимальной стоимости и алгоритм завершается.
- Шаг [math]3[/math]. Отменим цикл [math]C[/math], пустив по нему максимально возможный поток: [math]f = f + c_{f}(C)\cdot f_{C}[/math]. Перейдем к шагу [math]1[/math].
Сложность
Для сетей с целочисленными стоимостями на ребрах [math]O(VE\cdot VE\log{CV})[/math], с вещественными — [math]O(VE\cdot VE^{2}\log{V})[/math].
В обоих случаях [math]O(VE)[/math] времени тратится на поиск цикла минимального среднего веса.
Псевдокод
func findMin
while f
C = c : M(c) = [math]\min\limits_c[/math] M(c) // M(C) — вес минимального цикла
if M(C) [math]\geqslant[/math] 0
return f // тогда мы нашли f — поток минимальной стоимости, алгоритм завершается
else
f += c_f * f(C) // иначе отменим цикл
Корректность
Пусть [math]f[/math] — поток минимальной стоимости. Введём на нашей сети функцию потенциалов [math]\varphi[/math].
Определение: |
Приведённой стоимостью (англ. reduced cost) ребра назовем следующую величину: [math]p_{\varphi}(uv)=\varphi(u) + p(uv) - \varphi(v)[/math]. |
Иными словами, приведённая стоимость — это сколько нужно потратить денег, чтобы перевезти единицу жидкости из [math]u[/math] в [math]v[/math] (её нужно купить в [math]u[/math], перевезти из [math]u[/math] в [math]v[/math] и продать в [math]v[/math]).
Лемма ([math]1[/math]): |
Если [math]f[/math] — поток минимальной стоимости, то [math]\exists \varphi[/math] такое, что [math]\forall uv: \; c_{f}(uv) \gt 0 \implies p_{\varphi}(uv) \geqslant 0[/math]. |
Доказательство: |
[math]\triangleright[/math] |
- Рассмотрим остаточную сеть — граф [math]G_{f}[/math]. В нем нет отрицательных циклов, так как [math]f[/math] — поток минимальной стоимости[1].
- Добавим вершину [math]a[/math] и проведем из нее ребро стоимости [math]0[/math] во все вершины графа [math]G_{f}[/math]. В качестве [math]\varphi(u)[/math] выберем стоимость минимального пути из [math]a[/math] в [math]u[/math].
- Рассмотрим теперь некоторое ребро [math]uv[/math]. Понятно, что [math]\varphi(v) \leqslant \varphi(u) + p(uv)[/math]. (Здесь сравниваются минимальный путь [math]a \rightsquigarrow v[/math] и путь [math]a \rightsquigarrow u \rightarrow v[/math]). Перенеся [math]\varphi(v)[/math] в другую часть неравенства, получаем [math]0 \leqslant \varphi(u) + p(uv) - \varphi(v)[/math] или [math]0 \leqslant p_{\varphi}(uv)[/math].
|
[math]\triangleleft[/math] |
Определение: |
Будем говорить, что поток [math]f[/math] — [math]\varepsilon[/math]-оптимальный (англ. [math]\varepsilon[/math]-optimal), если [math]\exists \varphi[/math] такая, что [math]\forall uv: c_{f}(uv) \gt 0 \implies p_{\varphi}(uv) \geqslant -\varepsilon[/math]. |
Лемма ([math]2[/math]): |
Если стоимости целочисленны и поток [math]f[/math] — [math]\varepsilon[/math]-оптимальный, где [math]\varepsilon \lt \dfrac{1}{V}[/math], то [math]f[/math] — поток минимальной стоимости. |
Доказательство: |
[math]\triangleright[/math] |
- Рассмотрим цикл в остаточной сети [math]C[/math]. Заметим, что [math]p(C)=p_{\varphi}(C)[/math] (для доказательства этого факта достаточно расписать [math]p_{\varphi}(C)[/math] по определению).
- Возьмем [math]\varphi[/math] такое, что стоимости всех ребер в [math]C[/math] не меньше [math]-\varepsilon[/math]. Тогда стоимость всего цикла [math]p_{\varphi}(C)\geqslant -V\cdot \varepsilon[/math] (в цикле не больше [math]V[/math] ребер). Таким образом, [math]p_{\varphi}(C) \gt -1[/math], то есть [math]p(C) \gt -1[/math]. Но исходные пропускные способности были целочисленными, поэтому [math]p(C) \geqslant 0[/math], а это означает, что в остаточной сети нет отрицательных циклов, и, соответственно, [math]f[/math] — поток минимальной стоимости.
|
[math]\triangleleft[/math] |
Обозначим за [math]\mu^{*}[/math] минимальную величину среди средних весов циклов для потока [math]f[/math], а за [math]\varepsilon^{*}[/math] минимальное [math]\varepsilon[/math] такое, что поток [math]f[/math] — [math]\varepsilon[/math]-оптимальный.
Лемма ([math]3[/math]): |
Если [math]f[/math] — поток не минимальной стоимости, то [math]\varepsilon^{*}=-\mu^{*}[/math]. |
Доказательство: |
[math]\triangleright[/math] |
- Пусть [math]C[/math] — цикл минимального среднего веса в остаточной сети.
- Покажем, что [math]\mu^{*} \geqslant -\varepsilon^{*}[/math].
- Поскольку поток [math]f[/math] является [math]\varepsilon^{*}[/math]-оптимальным, верно следующее: [math]p(C) = p_{\varphi}(C) \geqslant -\texttt{len}(C) \cdot \varepsilon^{*}[/math] или [math]\dfrac{p(C)}{\texttt{len}(C)} \geqslant -\varepsilon^{*} [/math], то есть [math]\mu(C)=\mu^{*} \geqslant -\varepsilon^{*}[/math].
- Теперь покажем, что [math]\mu^{*} \leqslant -\varepsilon^{*}[/math].
- Пусть [math]p'(uv)=p(uv)-\mu^{*}[/math] для любого [math]uv \in E_{f}[/math]. Логичным будет также обозначить для некоторого цикла [math]C[/math] за [math]\mu'(C)[/math] величину [math]\dfrac{p'(C)}{\texttt{len}(C)}[/math]. Таким образом, для любого цикла [math]C[/math], [math]\mu'(C)=\mu(C)-\mu^{*}\geqslant 0[/math].
- Далее проведем рассуждения, аналогичные доказательству леммы [math]1[/math].
- Добавим вершину [math]a[/math] и проведем из нее ребро стоимости [math]0[/math] во все вершины графа [math]G_{f}[/math]. В качестве [math]\varphi(u)[/math] выберем стоимость (считая стоимостью функцию [math]p'[/math]) минимального пути из [math]a[/math] в [math]u[/math].
- Таким образом, [math]\varphi(v) \leqslant \varphi(u) + p'(uv) = \varphi(u) + p(uv) - \mu^{*}[/math]. Отсюда получаем, что [math]p_{\varphi}(uv) \geqslant \mu^{*}[/math] для любого ребра [math]uv[/math] из остаточной сети [math]E_{f}[/math], что означает, что [math]f[/math] — [math](-\mu^{*})[/math]-оптимальный, и, по определению [math]\varepsilon^{*}[/math], [math]\varepsilon^{*} \leqslant -\mu^{*}[/math].
|
[math]\triangleleft[/math] |
Лемма ([math]4[/math]): |
Отмена цикла минимального среднего веса не увеличивает [math]\varepsilon^{*}[/math]. |
Доказательство: |
[math]\triangleright[/math] |
- Пусть [math]C[/math] — цикл минимального среднего веса, который мы хотим отменить на текущем шаге нашего алгоритма. Перед тем, как мы отменим этот цикл, любое ребро в остаточной сети, в том числе, любое входящее в цикл [math]C[/math] ребро [math]uv[/math] удовлетворяет свойству [math]\varepsilon^{*}[/math]-оптимальности: [math]p_{\varphi}(uv) \geqslant -\varepsilon^{*}[/math].
- По лемме [math]3[/math], [math]\varepsilon^{*}=-\mu^{*}[/math], то есть [math]p_{\varphi}(uv) \geqslant \mu^{*}[/math]. Но поскольку [math]\mu^{*}[/math] — средний вес цикла, то [math]p_{\varphi}(uv) = \mu^{*} = -\varepsilon^{*}[/math].
- По свойству антисимметричности потока, после отмены цикла [math]C[/math], в остаточной сети появятся ребра стоимости [math]\varepsilon[/math]. Таким образом, свойство [math]p_{\varphi}(uv) \geqslant -\varepsilon[/math] все еще выполняется.
|
[math]\triangleleft[/math] |
Определение: |
Допустимым графом (англ. admissible graph) будем называть такой подграф остаточной сети, что он включает только ребра отрицательной приведенной стоимости. [math]H=\{uv \in E_{f}\;|\; p_{\varphi}(uv) \lt 0\}[/math] |
Лемма ([math]5[/math]): |
Пусть [math]f[/math] — некоторый поток, а [math]f'[/math] — поток после [math]E[/math] отмен циклов минимального среднего веса. Тогда [math]\varepsilon'^{*} \leqslant \left(1-\dfrac{1}{V}\right)\varepsilon^{*}[/math], где [math]\varepsilon'^{*}[/math] — минимальное [math]\varepsilon[/math] такое, что поток [math]f'[/math] [math]\varepsilon[/math]-оптимальный. |
Доказательство: |
[math]\triangleright[/math] |
- Изначально любое ребро [math]uv[/math] удовлетворяет свойству [math]p_{\varphi}(uv) \geqslant -\varepsilon^{*}[/math]. Отмена цикла добавляет в остаточную сеть [math]G_{f}[/math] только ребра положительной приведенной стоимости (см. лемму [math]4[/math]) и удаляет из сети [math]G[/math] как минимум одно ребро. Рассмотрим два случая:
- Ни один из отмененных циклов не содержал ребер, обладающих неотрицательной приведенной стоимостью. Тогда каждая отмена цикла уменьшает размер допустимого графа [math]H[/math] и после [math]E[/math] отмен граф [math]H[/math] пуст, что означает, что [math]f'[/math] — оптимальный поток, то есть [math]\varepsilon'^{*}=0[/math].
- Некоторые из отмененных циклов содержали ребра неотрицательной приведенной стоимости. Пусть впервые такое случилось на [math]i[/math]-ой итерации, и, соответственно, [math]C_{i}[/math] — первый из таких циклов. Для [math]C_{i}[/math] имеем, что каждое его ребро обладает приведенной стоимостью как минимум [math]-\varepsilon_{i}^{*}[/math] (при этом [math]\varepsilon'^{*} \leqslant \varepsilon_{i}^{*} \leqslant \varepsilon^{*}[/math] по лемме [math]4[/math]), хотя бы одно из ребер [math]C_{i}[/math] обладает неотрицательной приведенной стоимостью и количество ребер в [math]C_{i}[/math] не превышает [math]V[/math]. Тогда средний вес этого цикла [math]\mu(C_{i}) = \mu_{i}^{*} \geqslant -\left(1-\dfrac{1}{V}\right)\varepsilon_{i}^{*} \geqslant - \left(1-\dfrac{1}{V}\right)\varepsilon^{*}[/math], и [math]\varepsilon'^{*} \leqslant \varepsilon_{i}^{*} = -\mu_{i}^{*} \leqslant \left(1-\dfrac{1}{V}\right)\varepsilon^{*}[/math].
|
[math]\triangleleft[/math] |
Определение: |
[math]\varepsilon[/math]-фиксированным (англ. [math]\varepsilon[/math]-fixed) будем называть ребро, поток через которое неизменен для любых [math]\varepsilon[/math]-оптимальных потоков в сети. |
Теорема: |
Пусть поток [math]f[/math] является [math]\varepsilon[/math]-оптимальным с функцией потенциалов [math]\varphi[/math]. Также пусть для некоторого ребра [math]uv \; \left|p_{\varphi}(uv)\right| \geqslant 2V\varepsilon[/math]. Тогда ребро [math]uv[/math] [math]\varepsilon[/math]-фиксировано. |
Доказательство: |
[math]\triangleright[/math] |
- По свойству антисимметричности, достаточно будет доказать теорему для случая [math]p_{\varphi}(uv) \geqslant 2V\varepsilon[/math].
- Рассмотрим такой поток [math]f'[/math], что [math]f'(uv) \neq f(uv)[/math]. Поскольку [math]p_{\varphi}(uv) \geqslant 2V\varepsilon \gt \varepsilon[/math], поток по ребру [math]uv[/math] должен быть как можно меньше, то есть [math]f(uv) = -c(uv)[/math], и тогда раз [math]f'(uv) \neq f(uv)[/math], то [math]f'(uv) \gt f(uv)[/math].
- Покажем теперь, что [math]f'[/math] не [math]\varepsilon[/math]-оптимальный.
- Обозначим за [math]G_{\gt }[/math] подграф [math]G[/math] такой, что [math]G_{\gt }=(V, \{uv \in E \;|\; f'(uv) \gt f(uv) \})[/math]. Рассмотрим некоторое ребро [math]uv[/math] в [math]G_{\gt }[/math]. Поскольку [math]f[/math] и [math]f'[/math] являются циркуляциями, в [math]G_{\gt }[/math] должен содержаться простой цикл [math]C[/math], проходящий через [math]uv[/math]. Поскольку все ребра в [math]C[/math] — остаточные, стоимость [math]C[/math] не меньше [math]p_{\varphi}(uv) - (\texttt{len}(C)-1)\varepsilon \geqslant 2V\varepsilon - (V-1)\varepsilon \gt V\varepsilon[/math].
- Теперь рассмотрим цикл [math]\overline{C}[/math], который получен из [math]C[/math] разворотом всех его ребер. Заметим, что [math]\overline{C}[/math] является циклом в [math]G_{\lt }=(V,\{uv \in E \;|\; f'(uv) \lt f(uv)\})[/math] и, соответственно, циклом в [math]G_{f}[/math]. По свойству антисимметричности, стоимость [math]\overline{C}[/math] меньше, чем [math]-V\varepsilon[/math] и, таким образом, [math]\mu(\overline{C}) \lt -\varepsilon[/math]. Откуда по лемме [math]3[/math] имеем, что [math]f'[/math] не [math]\varepsilon[/math]-оптимален.
|
[math]\triangleleft[/math] |
Лемма (доказательство оценки времени работы алгоритма в случае вещественных стоимостей): |
Пусть [math]k=VE(\lceil \log V + 1 \rceil)[/math]. Разобьем работу алгоритма на группы по [math]k[/math] последовательных итераций. Утверждается, что каждая группа фиксирует поток на независимом ребре [math]uv[/math], то есть итерации из другой группы не меняют величину [math]f(uv)[/math]. |
Доказательство: |
[math]\triangleright[/math] |
- Оценка времени работы следует непосредственно из этого утверждения.
- Чтобы доказать его, рассмотрим некоторую группу итераций. Пусть [math]f[/math] — поток до первой итерации, а [math]f'[/math] — после последней итерации этой группы. Обозначим за [math]\varepsilon'^{*}[/math] минимальное [math]\varepsilon[/math] такое, что поток [math]f'[/math] [math]\varepsilon[/math]-оптимальный, а за [math]\varphi'[/math] — функцию потенциалов такую, что [math]f'[/math] удовлетворяет свойству [math]\varepsilon'^{*}[/math]-оптимальности. Выбор [math]k[/math] и лемма [math]5[/math] дают нам следующее неравенство: [math]\varepsilon'^{*} \leqslant \varepsilon^{*} \left(1-\dfrac{1}{V} \right)^{V(\log V + 1)} \leqslant \dfrac{\varepsilon^{*}}{2V}[/math].
- Рассмотрим цикл [math]C[/math], отмененный на первой итерации рассматриваемой группы. Поскольку средний вес цикла [math]C[/math] равен [math]-\varepsilon^{*}[/math] (см. лемму [math]3[/math]), некоторое ребро [math]uv[/math] цикла [math]C[/math] должно иметь приведенную стоимость [math]p_{\varphi'}(uv) \leqslant -\varepsilon^{*} \leqslant -2V\varepsilon'^{*}[/math]. Таким образом, поток на ребре [math]uv[/math] не изменится при итерациях, происходящих после этой группы. Таким образом, по теореме каждая группа фиксирует поток на независимом ребре.
|
[math]\triangleleft[/math] |
Алгоритм поиска цикла минимального среднего веса
Наивный способ
Устроим двоичный поиск.
Установим нижнюю и верхнюю границы величины среднего веса цикла [math]l[/math] и [math]r[/math] соответственно, вычислим серединное значение [math]m[/math] и отнимем полученную величину [math]m[/math] от всех ребер сети. Если теперь в нашей сети есть отрицательный цикл (этот факт можно проверить при помощи алгоритма Форда-Беллмана), значит существует цикл с меньшим средним весом, чем [math]m[/math]. Тогда продолжим поиск среди значений в диапазоне от [math]l[/math] до [math]m[/math], иначе — от [math]m[/math] до [math]r[/math].
Тогда, если [math]C_{max}[/math] и [math]C_{min}[/math] — максимальная и минимальная возможные величины среднего веса цикла соответственно, такой алгоритм для вещественных значений весов ребер будет работать за [math]O\left(\log \dfrac{C_{max}-C_{min}}{\varepsilon} \cdot EV\right)[/math], где [math]\varepsilon[/math] — точность выбора среднего веса цикла.
При этом для целочисленных значений на ребрах точность выбора величины среднего веса цикла не может превысить [math]\dfrac{1}{V}[/math], что дает нам оценку [math]O\left(\log (V(C_{max}-C_{min})) \cdot EV\right)[/math].
Псевдокод
func findMinCycleBinarySearch (l, r)
m = (l + r) / 2
for e in edges
e.weight -= m
if [math]\exists[/math]C : M(C) < 0
findMinCycleBinarySearch (l, m)
else
findMinCycleBinarySearch (m, r)
Продвинутый алгоритм
Добавим к нашему графу вершину [math]s[/math] и ребра из нее во все остальные вершины.
Запустим алгоритм Форда-Беллмана и попросим его построить нам квадратную матрицу со следующим условием: [math]d[i][u][/math] — длина минимального пути от [math]s[/math] до [math]u[/math] ровно из [math]i[/math] ребер.
Тогда длина оптимального цикла [math]\mu^{*}[/math] минимального среднего веса вычисляется как [math]\min\limits_{u} {\max\limits_{k} {\dfrac{d[n][u]-d[k][u]}{n-k}}}[/math].
Достаточно будет доказать это правило для [math]\mu^{*}=0[/math], так как для других [math]\mu^{*}[/math] можно просто отнять эту величину от всех ребер и получить снова случай с [math]\mu^{*}=0[/math].
Чтобы найти цикл после построения матрицы [math]d[k][u][/math], запомним, при каких [math]u[/math] и [math]k[/math] достигается оптимальное значение [math]\mu^{*}[/math], и, используя [math]d[n][u][/math], поднимемся по указателям предков. Как только мы попадем в уже посещенную вершину — мы нашли цикл минимального среднего веса.
Этот алгоритм работает за [math]O(VE)[/math] [2].
Псевдокод
func findMinCycle()
Node s
Edge e
insert(s) // добавляем мнимую вершину [math]s[/math] и проводим рёбра нулевого веса в каждую вершину графа
for u in G
e.begin = s
e.end = u
e.weight = 0
fordBellman(s)
m = [math]\min\limits_{u} {\max\limits_{k} }[/math]((d[n][u] - d[k][u]) / (n - k))
См. также
Примечания
Источники информации