Опубликован: 05.01.2015 | Доступ: свободный | Студентов: 2177 / 0 | Длительность: 63:16:00
Лекция 22:

Потоки в сетях

< Лекция 21 || Лекция 22: 123456789101112

Потоки минимальной стоимости

В наличии многочисленных решений для конкретной задачи о максимальном потоке нет ничего удивительного. Но при этом возникает вопрос: можно ли ввести дополнительные критерии, чтобы выбрать один из них? Например, понятно, что существует множество решений для задач вычисления потоков в сети с единичными пропускными способностями, представленных на рис. 22.22. Возможно, для нас лучше решение, использующее наименьшее количество ребер или кратчайшие пути. А возможно, нам нужно знать, существует ли решение, использующее непересекающиеся пути. Эти задачи сложнее, чем стандартная задача о максимальном потоке, они описываются более общей моделью, известной как задача о потоке минимальной стоимости (mincost flow problem).

Как и в случае задачи о максимальном потоке, существует множество эквивалентных способов постановки задачи о потоке минимальной стоимости. В этом разделе мы подробно рассмотрим стандартную формулировку этой задачи, а различные сведения к другим задачам изучим в разделе 22.7.

Конкретно, мы воспользуемся моделью максимального потока минимальной стоимости (mincost-maxflow): введем тип ребра, который содержит целочисленную стоимость, используем стоимость ребра для естественного определения стоимости потока, а затем поставим задачу определения максимального потока минимальной стоимости. Мы не только получим эффективный алгоритм для этой задачи, но и построим модель ее решения, получившую широкое применение.

Определение 22.8. Стоимость потока (flow cost) через ребро в транспортной сети со стоимостями ребер равна произведению потока в этом ребре на стоимость. Стоимость (cost) потока есть сумма стоимостей потоков в ребрах этого потока.

Мы все так же считаем, что пропускные способности выражаются положительными целыми числами, меньшими M, а стоимости ребер - неотрицательными числами, меньшими C. (Отказ от использования отрицательных стоимостей мотивируется главным образом соображениями удобства, о чем будет сказано в разделе 22.7.) Как и ранее, мы присваиваем этим граничным значениям специальные обозначения, т.к. от них зависит время выполнения некоторых алгоритмов. С учетом этих простых предположений формулировка задачи, которую мы намереваемся решить, не представляет трудностей.

Максимальный поток минимальной стоимости. Пусть задана транспортная сеть со стоимостями ребер. Нужно найти такой максимальный поток, стоимость которого не больше стоимости любого другого максимального потока.

На рис. 22.40 показаны различные максимальные потоки в транспортной сети со стоимостями, в том числе и максимальный поток минимальной стоимости. Разумеется, трудоемкость минимизации стоимости не уступает поиску максимального потока, о котором речь шла в разделах 22.2 и 22.3. Стоимость добавляет новое измерение, а это существенно усложняет дело. Но все-таки мы можем справиться с этими трудностями с помощью обобщенного алгоритма, который похож на алгоритм расширения путей для задачи о максимальном потоке.

Есть много других задач, которые сводятся к задаче о максимальном потоке минимальной стоимости или эквивалентны ей. Например, интересна следующая постановка задачи, т.к. она охватывает задачу распределения товаров, которая была рассмотрена в начале данного раздела.

Допустимый поток минимальной стоимости. Напомним, что поток в сети, содержащей вершины с весами (предложение, если вес положительный, и спрос, если вес отрицательный), называется допустимым (feasible), если сумма весов вершин отрицательна, а разность между притоком и оттоком в каждой вершине равна нулю. Нужно найти в такой сети допустимый поток минимальной стоимости.

Чтобы описать сетевую модель для решения задачи о допустимом потоке минимальной стоимости, мы для краткости используем термин распределительная сеть (distribution network), который будет означать " транспортная сеть с пропускными способностями ребер, стоимостями ребер и весами предложения или спроса в вершинах " .

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

 Максимальные потоки в транспортных сетях со стоимостями

Рис. 22.40. Максимальные потоки в транспортных сетях со стоимостями

Все эти потоки имеют одну и ту же (максимальную) величину, но их стоимости (сумма произведений потоков в ребрах на стоимости этих ребер) различны. Максимальный поток в центре имеет минимальную стоимость (ни один максимальный поток не имеет меньшей стоимости).

Лемма 22.22. Задача о допустимом потоке минимальной стоимости и задача о максимальном потоке минимальной стоимости эквивалентны.

Доказательство. Непосредственно следует из такого же соответствия, как и в лемме 22.18 (см. также упражнение 22.76). $\blacksquare$

Вследствие этой эквивалентности и в силу того, что задача о допустимом потоке минимальной стоимости непосредственно моделирует задачи распределения товаров и многие другие приложения, мы употребляем для обозначения обеих задач термин поток минимальной стоимости (minicost flow) - даже в контекстах, где возможно упоминание любой из них. Сведения к другим задачам будут рассмотрены в разделе 22.7.

Для реализации стоимостей ребер в транспортных сетях добавим в класс EDGE из раздела 22.1 целочисленный приватный член данных pcost и функцию-элемент cost(), возвращающую значение стоимости клиенту. Программа 22.8 представляет собой клиентскую функцию, которая вычисляет стоимость потока в графе, построенном из указателей на такие ребра. Как и при работе с максимальными потоками, целесообразно реализовать функцию проверки, что значения притока и оттока согласованы в каждой вершине, а структуры данных непротиворечивы (см. упражнение 22.12).

Программа 22.8. Вычисление стоимости потока

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

  static int cost(Graph &G)
 { int x = 0;
   for (int v = 0; v < G.V(); v++)
  { typename Graph::adjIterator A(G, v);
    for (Edge* e = A.beg(); !A.end(); e = A.nxt())
   if (e->from(v) && e->costRto(e->w()) < C)
     x += e->flow()*e->costRto(e->w());
  }
   return x;
 }
   

Первым шагом при разработке алгоритмов для вычисления потока минимальной стоимости необходимо добавить стоимость ребер в определение остаточных сетей.

Определение 22.9. Пусть задан поток в транспортной сети со стоимостями ребер. Остаточная сеть (residual network) для этого потока содержит те же вершины, что и исходная сеть, и одно или два ребра для каждого ребра исходной сети и определяется следующим образом. Пусть для каждого ребра u-v в исходной сети f - его поток, с - его пропускная способность, а Х - стоимость. Если f положительно, в остаточную сеть включается ребро v-u с пропускной способностью f и стоимостью -х; если f меньше с, в остаточную сеть включается ребро u-v с пропускной способностью с - f и стоимостью х.

Это определение почти идентично определению 22.4, но имеет очень важное отличие. Ребра в остаточной сети, представляющие обратные ребра, имеют отрицательную стоимость. Чтобы реализовать это соглашение, мы используем следующую функцию-член в классе ребра:

  int costRto(int v)
 { return from(v) ? -pcost : pcost; }
   

Проход по обратным ребрам соответствует удалению потока из соответствующего ребра исходной сети, поэтому стоимость изменяется на соответствующую величину. Из-за отрицательных стоимостей ребер в этих сетях могут существовать циклы с отрицательной стоимостью. Понятие отрицательных циклов, которое выглядело надуманным при нашем знакомстве с ним в контексте алгоритмов вычисления кратчайшего пути, играет важную роль в алгоритмах вычисления потока минимальной стоимости, и в этом мы сейчас убедимся. Мы рассмотрим два алгоритма, основанных на следующем условии оптимальности.

Лемма 22.23. Максимальный поток является максимальным потоком минимальной стоимости тогда и только тогда, когда его остаточная сеть не содержит (ориентированный) цикл с отрицательной стоимостью.

Доказательство. Предположим, что имеется максимальный поток минимальной стоимости, остаточная сеть которого содержит цикл с отрицательной стоимостью. Пусть х - пропускная способность ребра с минимально пропускной способностью в этом цикле. Увеличим поток, добавляя х в ребра в потоке, соответствующие ребрам с положительной стоимостью в остаточной сети (прямые ребра) и вычитая х из ребер, соответствующих ребрам с отрицательной стоимостью в остаточной сети (обратные ребра). Эти модификации не изменяют разность между притоком и оттоком любой вершины, т.е. поток остается максимальным. Но они меняют стоимость сети на стоимость цикла, умноженную на х - отрицательное значение. Это противоречит предположению, что стоимость исходного потока минимальна.

Чтобы доказать обратное утверждение, предположим, что существует максимальный поток F без циклов отрицательной стоимости, стоимость которого не является минимальной, и рассмотрим любой максимальный поток M минимальной стоимости. Рассуждения из теоремы о разложении потоков (лемма 22.2) позволяют найти не более E ориентированных циклов таких, что добавление этих циклов к потоку F даст поток M. Но, поскольку F не содержит отрицательных циклов, эта операция не может снизить стоимость потока F, т.е. получено противоречие. Другими словами, мы должны быть иметь возможность преобразовать F в M, увеличивая потоки в циклах, однако это невозможно, т.к. нет циклов отрицательной стоимости, которые можно было бы использовать для снижения стоимости потока. $\blacksquare$

Из этой леммы непосредственно следует простой обобщенный алгоритм решения задачи о потоке минимальной стоимости, получивший название алгоритма вычеркивания циклов (cycle-canceling algorithm):

Найдите максимальный поток. Увеличьте поток в произвольном цикле с отрицательной стоимости в остаточной сети, и продолжайте эту процедуру, пока не останется ни одного такого цикла.

Этот метод объединяет механизмы, которые были разработаны на протяжении всей этой главы и предыдущей главы и обеспечивает построение эффективных алгоритмов решения широкого класса задач, вписывающихся в модель потока минимальной стоимости. Подобно нескольким другим уже знакомым нам обобщенным методам, он допускает несколько различных реализаций, поскольку методы отыскания начального максимального потока и отыскания циклов с отрицательной стоимости не описаны. На рис. 22.41 показан пример вычисления максимального потока минимальной стоимости, где используется вычеркивание циклов.

Поскольку мы уже разработали алгоритмы для вычисления максимального потока и поиска отрицательных циклов, мы сразу же получаем реализацию алгоритма вычеркивания циклов, представленную в программе 22.9. Мы используем любую реализацию вычисления максимального потока для нахождения начального максимального потока и алгоритм Беллмана-Форда для поиска отрицательных циклов (см. упражнение 22.108). К двум этим реализациям остается только добавить цикл увеличения потоков в циклах на графе.

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

Программа 22.9. Вычеркивание циклов

Этот класс решает задачу вычисления максимального потока минимальной стоимости методом вычеркивания отрицательных циклов. Он использует класс MAXFLOW для поиска максимального потока и приватную функцию-член negcyc (см. упражнение 22.108) для нахождения отрицательных циклов. Если отрицательный цикл существует, этот программный код находит такой цикл, вычисляет максимальную величину потока, который нужно протолкнуть через него, и делает это. Функция augment взята из программы 22.3 и была (предусмотрительно!) разработана для правильной работы в случаях, когда путь оказывается циклом.

  template <class Graph, class Edge>
  class MINCOST
 { const Graph &G;
   int s, t;
   vector<int> wt;
   vector <Edge *> st;
   int ST(int v) const;
   void augment(int, int);
   int negcyc(int);
   int negcyc();
 public:
   MINCOST(const Graph &G, int s, int t) : G(G),
  s(s), t(t), st(G.V()), wt(G.V())
  { MAXFLOW<Graph, Edge>(G, s, t);
    for (int x = negcyc(); x != -1; x = negcyc())
   { augment(x, x); }
  }
 };
   
 Остаточные сети (вычеркивание циклов)

Рис. 22.41. Остаточные сети (вычеркивание циклов)

Каждый из показанных здесь потоков представляет собой максимальный поток в транспортной сети в верхней части рисунка, но только поток, изображенный внизу, является максимальным потоком минимальной стоимости. Чтобы найти его, мы начинаем с произвольного максимального потока и увеличиваем поток по отрицательным циклам. Стоимость начального максимального потока (второй сверху) равна 22, но он не является максимальным потоком минимальной стоимости, т.к. остаточная сеть (показана справа) содержит три отрицательных цикла.

В этом примере мы увеличиваем поток по циклу 4-1-0-2-4 и получаем максимальный поток со стоимостью 21 (третий сверху), который еще содержит один отрицательный цикл. Увеличение потока по этому циклу дает поток минимальной стоимости (внизу). Обратите внимание, что увеличение потока по циклу 3-2-4-1-3 дало бы максимальный поток минимальной стоимости всего за один шаг.

Эта технология вычисления потока минимальной стоимости показана на рис. 22.42. На этом рисунке используется начальный поток, равный максимальному потоку - чтобы было ясно, что этот алгоритм просто вычисляет другой поток той же величины, но более низкой стоимости (в общем случае мы не знаем величину этого потока, поэтому после завершения работы в фиктивном ребре еще остается некоторый поток, который мы игнорируем). Из рисунка понятно, что некоторые расширяющие циклы содержат фиктивное ребро и увеличивают поток в сети, а другие циклы не содержат его и снижают стоимость. В конечном итоге мы получаем максимальный поток, и тогда все расширяющие циклы уменьшают стоимость, не меняя величины потока, как если бы мы начали сразу с максимального потока.

Первоначальное заполнение фиктивным потоком перед вычеркиванием циклов технически не более и не менее универсально, чем первоначальное заполнение максимальным потоком. Первый способ охватывает все алгоритмы вычисления максимального потока с помощью расширения путей, однако алгоритм расширения путей может вычислить не все максимальные потоки (см. упражнение 22.40). С одной стороны, эта технология может привести в утрате всех преимуществ сложного алгоритма вычисления максимального потока. С другой стороны, возможно, лучше снижать стоимость в процессе построения максимального потока. На практике широко используется инициализация фиктивным потоком из-за простоты ее реализации.

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

Лемма 22.24. Количество расширяющих циклов, необходимых для выполнения обобщенного алгоритма вычеркивания циклов, меньше ECM.

Доказательство. В худшем случае каждое ребро в начальном максимальном потоке имеет пропускную способность M, стоимость C и заполнено. Каждый цикл уменьшает эту стоимость не менее чем на 1. $\blacksquare$

Следствие. Время решения задачи о потоке минимальной стоимости в разреженной сети равно O(V3 CM).

Доказательство. Непосредственно следует из умножения количества расширяющих циклов в худшем случае на затраты на их поиск алгоритмом Беллмана-Форда в худшем случае (см. лемму 21.22). $\blacksquare$

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

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

 Вычеркивание циклов без начального максимального потока

Рис. 22.42. Вычеркивание циклов без начального максимального потока

Здесь показано вычисление максимального потока минимальной стоимости, начиная с первоначально нулевого потока, с помощью алгоритма вычеркивания циклов, который использует фиктивное ребро из стока в исток в остаточной сети с неограниченной пропускной способностью и неограниченной отрицательной стоимостью. Фиктивное ребро превращает любой расширяющий путь из 0 в 5 в отрицательный цикл (хотя он игнорируется при увеличении потока и вычислении его стоимости). Добавление по этому пути ведет к увеличению потока, как в алгоритмах расширения путей (три верхних ряда). При отсутствии циклов, в которые входит фиктивное ребро, в остаточной сети отсутствуют пути из истока в сток - значит, поток максимален (третий ряд сверху). С этого момента увеличение потока по отрицательному циклу снижает стоимость потока без изменения его величины (внизу).

В этом примере сначала вычисляется максимальный поток, а затем уменьшается его стоимость; но это не обязательно. Например, на втором шаге алгоритм мог бы увеличить поток в отрицательном цикле 1-4-5-3-1, а не в цикле 0-1-4-5-0. Поскольку каждое добавление либо увеличивает поток, либо уменьшает стоимость, алгоритм в любом случае продвигается к максимальному потоку минимальной стоимости.

Задача о потоке минимальной стоимости представляет собой наиболее общую модель решения задач из рассмотренных нами, и тем более удивительно, что ее можно решить с помощью столь простой реализации. Ввиду важности этой модели были разработаны и подробно изучены другие многочисленные реализации метода вычеркивания циклов и многие другие методы. Программа 22.9 является удивительной простой и эффективной базовой реализацией, однако в ней имеются два слабых места, которые могут ухудшить ее производительность. Во-первых, каждый поиск отрицательного цикла начинается с самого начала. Можно ли сохранить промежуточную информацию, полученную при поиске одного отрицательного цикла, которая может оказаться полезной при поиске следующего цикла? Во-вторых, программа 22.9 использует первый же отрицательный цикл, который находит алгоритм Беллмана-Форда. Можно ли мы направить поиск на выявление отрицательных циклов с особыми свойствами? В разделе 22.6 мы рассмотрим усовершенствованную реализацию, которая, оставаясь обобщенной, отвечает на оба эти вопроса.

Упражнения

22.105. Добавьте стоимости в класс допустимых потоков из упражнения 22.74. Для решения задачи о допустимых потоках минимальной стоимости воспользуйтесь классом MINCOST.

22.106. Приведите более точную верхнюю границу, чем ECM, для стоимости максимального потока в транспортной сети, не все ребра которой имеют максимальную пропускную способность и максимальную стоимость.

22.107. Докажите, что если все пропускные способности и стоимости выражены целыми числами, то задача о минимальной стоимости имеет решение, в котором все потоки имеют целочисленные значения.

22.108. Реализуйте функцию negcyc() для программы 22.9, воспользовавшись алгоритмом Беллмана-Форда (см. упражнение 21.134).

22.109. Замените в программе 22.9 инициализацию вычислением потока на инициализацию потоком в фиктивном ребре.

22.110. Приведите все возможные последовательности расширяющих циклов, которые могли бы быть показаны на рис. 22.41.

о 22.111. Приведите все возможные последовательности расширяющих циклов, которые могли бы быть показаны на рис. 22.42.

22.112. Покажите в стиле рис. 22.41 поток и остаточные сети после каждого расширения при использовании программы 22.9 (реализация алгоритма вычеркивания циклов) для отыскания потока минимальной стоимости в транспортной сети, изображенной на рис. 22.10. Ребра 0-2 и 0-3 имеют стоимость 2, ребра 2-5 и 3-5 - стоимость 3, ребро 1-4 - стоимость 4, а все остальные ребра - единичную стоимость. Предполагается, что максимальный поток вычисляется с помощью алгоритма, который использует кратчайшие расширяющие пути.

22.113. Выполните упражнение 22.112 в предположении, что программа начинает работу с максимальным потоком в фиктивном ребре из истока в сток, как показано на рис. 22.42.

22.114. Добавьте в решения упражнений 22.6 и 22.7 обработку стоимостей в транспортных сетях.

22.115. Добавьте в решения упражнений 22.9-22.11 обработку стоимостей в сетях. Назначьте каждому ребру стоимость, приблизительно пропорциональную евклидовому расстоянию между его вершинами.

< Лекция 21 || Лекция 22: 123456789101112
Бактыгуль Асаинова
Бактыгуль Асаинова

Здравствуйте прошла курсы на тему Алгоритмы С++. Но не пришел сертификат и не доступен.Где и как можно его скаачат?

Александра Боброва
Александра Боброва

Я прошла все лекции на 100%.

Но в https://www.intuit.ru/intuituser/study/diplomas ничего нет.

Что делать? Как получить сертификат?