For faster navigation, this Iframe is preloading the Wikiwand page for Алгоритм Эдмондса — Карпа.

Алгоритм Эдмондса — Карпа

Материал из Википедии — свободной энциклопедии

Алгоритм Эдмондса — Карпа решает задачу нахождения максимального потока в транспортной сети. Алгоритм представляет собой частный случай метода Форда — Фалкерсона и работает за время в графе . Впервые был опубликован в 1970 году советским учёным Е. А. Диницом. Позже, в 1972 году, был независимо открыт Эдмондсом и Карпом.

Алгоритм Эдмондса — Карпа — это вариант алгоритма Форда — Фалкерсона, при котором на каждом шаге выбирают кратчайший дополняющий путь из в в остаточной сети (полагая, что каждое ребро имеет единичную длину). Кратчайший путь находится поиском в ширину.

  1. Обнуляем все потоки. Остаточная сеть изначально совпадает с исходной сетью.
  2. В остаточной сети находим кратчайший путь из источника в сток. Если такого пути нет, останавливаемся.
  3. Пускаем через найденный путь (он называется увеличивающим путём или увеличивающей цепью) максимально возможный поток:
    1. На найденном пути в остаточной сети ищем ребро с минимальной пропускной способностью .
    2. Для каждого ребра на найденном пути увеличиваем поток на , а в противоположном ему — уменьшаем на .
    3. Модифицируем остаточную сеть. Для всех рёбер на найденном пути, а также для противоположных им рёбер, вычисляем новую пропускную способность. Если она стала ненулевой, добавляем ребро к остаточной сети, а если обнулилась, стираем его.
  4. Возвращаемся на шаг 2.

Чтобы найти кратчайший путь в графе, используем поиск в ширину:

  1. Создаём очередь вершин О. Вначале О состоит из единственной вершины s.
  2. Отмечаем вершину s как посещённую, без родителя, а все остальные как непосещённые.
  3. Пока очередь не пуста, выполняем следующие шаги:
    1. Удаляем первую в очереди вершину u.
    2. Для всех дуг (u, v), исходящих из вершины u, для которых вершина v ещё не посещена, выполняем следующие шаги:
      1. Отмечаем вершину v как посещённую, с родителем u.
      2. Добавляем вершину v в конец очереди.
      3. Если v = t, выходим из обоих циклов: мы нашли кратчайший путь.
  4. Если очередь пуста, возвращаем ответ, что пути нет вообще и останавливаемся.
  5. Если нет, идём от t к s, каждый раз переходя к родителю. Возвращаем путь в обратном порядке.

В процессе работы алгоритм Эдмондса — Карпа будет находить каждый дополняющий путь за время . Ниже мы докажем, что общее число увеличений потока, выполняемое данным алгоритмом, составляет . Таким образом, сложность алгоритма Эдмондса — Карпа равна .

Доказательство

[править | править код]

Назовём расстоянием от вершины x до вершины у длину кратчайшего пути от x до y в остаточной сети, измеряемую числом рёбер. Если такого пути нет, будем считать расстояние бесконечным. Будем говорить, что y приблизилась к x (отдалилась от x), если расстояние от x до y уменьшилось (увеличилось). Будем говорить, что y ближе к x (дальше от x), чем z, если расстояние от x до y меньше (больше), чем расстояние от x до z.

Лемма. В ходе работы алгоритма ни одна вершина никогда не приближается к источнику. Доказательство. Пусть это не так, тогда при каком-то увеличении потока некоторые вершины приблизились к источнику. Назовём их неправильными. Выберем ту из неправильных вершин, которая после увеличения потока оказалась ближе всех к источнику (если таких больше одной, то любую из них). Обозначим выбранную вершину через v. Рассмотрим кратчайший путь от s до v. Обозначим предпоследнюю вершину на этом пути через u, таким образом, путь имеет вид . Поскольку u ближе к s, чем v, а v — ближайшая к s из неправильных вершин, то u — вершина правильная. Обозначив расстояния от s до u и v до и после увеличения потока соответственно через , , , , имеем:

,

откуда

Следовательно, до увеличения потока дуга (u, v) отсутствовала в остаточной сети. Чтобы оно появилось, увеличивающий путь должен был содержать дугу (v, u). Но в алгоритме Эдмондса — Карпа увеличивающий путь всегда кратчайший, следовательно,

,

что противоречит предыдущему неравенству. Значит, наше предположение было неверным. Лемма доказана.

Назовём критическим то из рёбер увеличивающего пути, у которого остаточная пропускная способность минимальна. Оценим, сколько раз некое ребро (u, v) может оказываться критическим. Пускай это произошло на итерации , а в следующий раз на итерации . Обозначая через расстояние от s до y на итерации t, имеем:

Заметим, что на итерации критическое ребро исчезает из остаточной сети. Чтобы к моменту итерации ребро (u, v) в ней вновь появилось, необходимо, чтобы на какой-то промежуточной итерации был выбран увеличивающий путь, содержащий ребро (v, u). Следовательно,

Используя ранее доказанную лемму, получаем:

Поскольку изначально (иначе v = s, но ребро, ведущее в s, не может появиться на кратчайшем пути из s в t), и всегда, когда конечно, оно меньше |V| (кратчайший путь не содержит циклов, и, следовательно, содержит менее |V| рёбер), ребро может оказаться критическим не более раз. Поскольку каждый увеличивающий путь содержит хотя бы одно критическое ребро, а всего рёбер, которые могут когда-то стать критическими, (все рёбра исходной сети и им противоположные), то мы можем увеличить путь не более |Е|·|V| раз. Следовательно, число итераций не превышает O(|E|·|V|), что и требовалось доказать.

Пусть задана сеть с истоком в вершине и стоком в вершине . На рисунке парой обозначен поток по этому ребру и его пропускная способность.

Поиск в ширину

[править | править код]

Опишем поиск в ширину на первом шаге.

  1. Очередь состоит из единственной вершины A. Посещена вершина A. Родителя нет.
  2. Очередь состоит (от начала к концу) из вершин B и D. Посещены вершины A, B, D. Вершины B, D имеют родителя А.
  3. Очередь состоит из вершин D и C. Посещены A, B, C, D. Вершины B, D имеют родителя А, вершина C — родителя B.
  4. Очередь состоит из вершин C, E, F. Посещены A, B, C, D, E, F. Вершины B, D имеют родителя А, вершина C — родителя B, вершины E, F — родителя D.
  5. Вершина C удаляется из очереди: рёбра из неё ведут только в уже посещённые вершины.
  6. Обнаруживается ребро (E,G) и цикл останавливается. В очереди вершины (F,G). Посещены все вершины. Вершины B,D имеют родителя А, вершина C — родителя B, вершины E,F — родителя D, вершина G — родителя E.
  7. Идём по родителя: . Возвращаем пройденный путь в обратном порядке: .

Заметим, что в очередь последовательно добавляли вершины, достижимые из A ровно за 1 шаг, ровно за 2 шага, ровно за 3 шага. Кроме того, родителем каждой вершины является вершина, достижимая из A ровно на 1 шаг быстрее.

Основной алгоритм

[править | править код]
Пропускная способность пути Путь












Отметим, что в процессе выполнения алгоритма длины дополняющих путей (на рисунках обозначены красным) не убывают. Это свойство выполняется благодаря тому, что мы ищем кратчайший дополняющий путь.

Алгоритм Диница

[править | править код]

Улучшенной версией алгоритма Эдмондса-Карпа является алгоритм Диница, требующий операций.

Назовём вспомогательной бесконтурной сетью графа G с источником s его подграф, содержащий только такие рёбра (u, v), для которых минимальное расстояние от s до v на единицу больше минимального расстояния от s до u.

Алгоритм Диница:

  1. Строим минимальную бесконтурную сеть остаточного графа.
  2. Пока в сети есть путь из s в t, выполнить следующие шаги:
    1. Находим кратчайший путь из s в t. Если его нет, выйти из цикла.
    2. На найденном пути в остаточной сети ищем ребро с минимальной пропускной способностью .
    3. Для каждого ребра на найденном пути увеличиваем поток на , а в противоположном ему — уменьшаем на .
    4. Удаляем все рёбра, достигшие насыщения.
    5. Удаляем все тупики (то есть вершины, кроме стока, откуда не выходит рёбер, и вершины, кроме источника, куда рёбер не входит) вместе со всеми инцидентными им рёбрами.
    6. Повторяем предыдущий шаг, пока есть что удалять.
  3. Если найденный поток ненулевой, добавляем его к общему потоку и возвращаемся на шаг 1.

Литература

[править | править код]
  • Томас Кормен и др. Алгоритмы: построение и анализ = INTRODUCTION TO ALGORITHMS. — 2-е изд. — М.: «Вильямс», 2006. — С. 1296. — ISBN 0-07-013151-1.
{{bottomLinkPreText}} {{bottomLinkText}}
Алгоритм Эдмондса — Карпа
Listen to this article

This browser is not supported by Wikiwand :(
Wikiwand requires a browser with modern capabilities in order to provide you with the best reading experience.
Please download and use one of the following browsers:

This article was just edited, click to reload
This article has been deleted on Wikipedia (Why?)

Back to homepage

Please click Add in the dialog above
Please click Allow in the top-left corner,
then click Install Now in the dialog
Please click Open in the download dialog,
then click Install
Please click the "Downloads" icon in the Safari toolbar, open the first download in the list,
then click Install
{{::$root.activation.text}}

Install Wikiwand

Install on Chrome Install on Firefox
Don't forget to rate us

Tell your friends about Wikiwand!

Gmail Facebook Twitter Link

Enjoying Wikiwand?

Tell your friends and spread the love:
Share on Gmail Share on Facebook Share on Twitter Share on Buffer

Our magic isn't perfect

You can help our automatic cover photo selection by reporting an unsuitable photo.

This photo is visually disturbing This photo is not a good choice

Thank you for helping!


Your input will affect cover photo selection, along with input from other users.

X

Get ready for Wikiwand 2.0 🎉! the new version arrives on September 1st! Don't want to wait?