2 #ifndef ANDRES_GRAPH_MAX_FLOW_HXX
3 #define ANDRES_GRAPH_MAX_FLOW_HXX
12 #include "andres/graph/digraph.hxx"
13 #include "andres/graph/shortest-paths.hxx"
27 template<
class GRAPH,
class FLOW>
42 template<
class EDGE_WEIGHT_ITERATOR>
44 template<
class EDGE_WEIGHT_ITERATOR,
class SUBGRAPH_MASK>
46 template<
class EDGE_WEIGHT_ITERATOR,
class SUBGRAPH_MASK>
47 Flow operator()(
const GraphType&,
const SUBGRAPH_MASK&, EDGE_WEIGHT_ITERATOR,
const std::size_t,
const std::size_t);
50 template<
class EDGE_WEIGHT_ITERATOR>
51 void push(
const GraphType&, EDGE_WEIGHT_ITERATOR,
const std::size_t);
52 template<
class EDGE_WEIGHT_ITERATOR>
53 void pushBack(
const GraphType&, EDGE_WEIGHT_ITERATOR,
const std::size_t);
54 template<
class EDGE_WEIGHT_ITERATOR,
class SUBGRAPH_MASK>
55 void relabel(
const GraphType&,
const SUBGRAPH_MASK&, EDGE_WEIGHT_ITERATOR,
const std::size_t);
56 template<
class EDGE_WEIGHT_ITERATOR,
class SUBGRAPH_MASK>
57 void discharge(
const GraphType&,
const SUBGRAPH_MASK&, EDGE_WEIGHT_ITERATOR,
const std::size_t);
58 void gapRelabel(
const GraphType&,
const std::size_t);
60 std::vector<std::size_t> height_;
61 std::vector<std::size_t> labelCount_;
62 std::vector<Flow> excess_;
63 std::vector<Flow> flow_;
64 std::vector<bool> active_;
65 std::queue<std::size_t> queue_;
66 std::size_t sourceVertexIndex_;
67 std::size_t sinkVertexIndex_;
68 std::size_t pushCount_;
69 std::size_t relabelCount_;
74 template<
class GRAPH,
class FLOW>
96 template<
class GRAPH,
class FLOW>
97 template<
class EDGE_WEIGHT_ITERATOR>
101 EDGE_WEIGHT_ITERATOR edgeWeightIterator,
102 const std::size_t sourceVertexIndex,
103 const std::size_t sinkVertexIndex
111 sourceVertexIndex_(),
127 template<
class GRAPH,
class FLOW>
128 template<
class EDGE_WEIGHT_ITERATOR,
class SUBGRAPH_MASK>
132 const SUBGRAPH_MASK& mask,
133 EDGE_WEIGHT_ITERATOR edgeWeightIterator,
134 const std::size_t sourceVertexIndex,
135 const std::size_t sinkVertexIndex
143 sourceVertexIndex_(),
148 (*this)(graph, mask, edgeWeightIterator, sourceVertexIndex, sinkVertexIndex);
153 template<
class GRAPH,
class FLOW>
161 sourceVertexIndex_ = 0;
162 sinkVertexIndex_ = 0;
166 assert(queue_.empty());
173 template<
class GRAPH,
class FLOW>
176 return excess_[sinkVertexIndex_];
184 template<
class GRAPH,
class FLOW>
187 const std::size_t edgeIndex
189 assert(edgeIndex < flow_.size());
190 return flow_[edgeIndex];
197 template<
class GRAPH,
class FLOW>
207 template<
class GRAPH,
class FLOW>
210 return relabelCount_;
221 template<
class GRAPH,
class FLOW>
222 template<
class EDGE_WEIGHT_ITERATOR,
class SUBGRAPH_MASK>
226 const SUBGRAPH_MASK& mask,
227 EDGE_WEIGHT_ITERATOR edgeWeightIterator,
228 const std::size_t sourceVertexIndex,
229 const std::size_t sinkVertexIndex
231 assert(mask.vertex(sourceVertexIndex) && mask.vertex(sinkVertexIndex));
233 const std::size_t numberOfVertices = graph.numberOfVertices();
234 const std::size_t numberOfEdges = graph.numberOfEdges();
237 sourceVertexIndex_ = sourceVertexIndex;
238 sinkVertexIndex_ = sinkVertexIndex;
241 height_.resize(numberOfVertices);
242 excess_.resize(numberOfVertices);
243 active_.resize(numberOfVertices);
244 std::fill(height_.begin(), height_.end(), std::size_t());
245 std::fill(excess_.begin(), excess_.end(),
Flow());
246 std::fill(active_.begin(), active_.end(),
false);
247 height_[sourceVertexIndex] = numberOfVertices;
248 excess_[sourceVertexIndex] = std::numeric_limits<Flow>::max();
249 active_[sourceVertexIndex] =
true;
250 active_[sinkVertexIndex] =
true;
251 labelCount_.resize((2 * numberOfVertices) + 2);
252 std::fill(labelCount_.begin(), labelCount_.end(), std::size_t());
253 labelCount_[0] = numberOfVertices - 1;
254 labelCount_[numberOfVertices] = 1;
255 flow_.resize(numberOfEdges);
256 std::fill(flow_.begin(), flow_.end(),
Flow());
259 for(
EdgeIterator it = graph.edgesFromVertexBegin(sourceVertexIndex); it != graph.edgesFromVertexEnd(sourceVertexIndex); ++it) {
260 const std::size_t edgeIndex = *it;
261 if (mask.edge(edgeIndex)) {
262 const std::size_t v = graph.vertexOfEdge(edgeIndex, 1);
263 if (mask.vertex(v)) {
264 push(graph, edgeWeightIterator, edgeIndex);
269 while(!queue_.empty()) {
270 const std::size_t u = queue_.front();
273 discharge(graph, mask, edgeWeightIterator, u);
286 template<
class GRAPH,
class FLOW>
287 template<
class EDGE_WEIGHT_ITERATOR>
291 EDGE_WEIGHT_ITERATOR edgeWeightIterator,
292 const std::size_t edgeIndex
294 const std::size_t u = graph.vertexOfEdge(edgeIndex, 0);
295 const std::size_t v = graph.vertexOfEdge(edgeIndex, 1);
297 Flow pushAmount = std::min(excess_[u], edgeWeightIterator[edgeIndex] - flow_[edgeIndex]);
298 flow_[edgeIndex] += pushAmount;
299 excess_[u] -= pushAmount;
300 excess_[v] += pushAmount;
301 if (!active_[v] && excess_[v] > 0) {
314 template<
class GRAPH,
class FLOW>
315 template<
class EDGE_WEIGHT_ITERATOR>
317 MaxFlowPushRelabel<GRAPH, FLOW>::pushBack(
319 EDGE_WEIGHT_ITERATOR edgeWeightIterator,
320 const std::size_t edgeIndex
322 const std::size_t u = graph.vertexOfEdge(edgeIndex, 0);
323 const std::size_t v = graph.vertexOfEdge(edgeIndex, 1);
325 Flow pushAmount = std::min(excess_[v], flow_[edgeIndex]);
326 flow_[edgeIndex] -= pushAmount;
327 excess_[u] += pushAmount;
328 excess_[v] -= pushAmount;
329 if (!active_[u] && excess_[u] > 0) {
343 template<
class GRAPH,
class FLOW>
344 template<
class EDGE_WEIGHT_ITERATOR,
class SUBGRAPH_MASK>
346 MaxFlowPushRelabel<GRAPH, FLOW>::relabel(
348 const SUBGRAPH_MASK& mask,
349 EDGE_WEIGHT_ITERATOR edgeWeightIterator,
352 std::size_t minHeight = 2 * graph.numberOfVertices();
353 const std::size_t oldHeight = height_[u];
354 for(EdgeIterator it = graph.edgesFromVertexBegin(u); it != graph.edgesFromVertexEnd(u); ++it) {
355 const std::size_t edgeIndex = *it;
356 if (mask.edge(edgeIndex)) {
357 const std::size_t v = graph.vertexOfEdge(edgeIndex, 1);
358 if (mask.vertex(v)) {
359 if(edgeWeightIterator[edgeIndex] - flow_[edgeIndex] > 0) {
360 minHeight = std::min(minHeight, height_[v]);
365 for(EdgeIterator it = graph.edgesToVertexBegin(u); it != graph.edgesToVertexEnd(u); ++it) {
366 const std::size_t edgeIndex = *it;
367 if (mask.edge(edgeIndex)) {
368 const std::size_t v = graph.vertexOfEdge(edgeIndex, 0);
369 if (mask.vertex(v)) {
370 if(flow_[edgeIndex] > 0) {
371 minHeight = std::min(minHeight, height_[v]);
376 height_[u] = minHeight + 1;
377 if (!active_[u] && excess_[u] > 0) {
384 labelCount_[oldHeight]--;
385 labelCount_[height_[u]]++;
386 if (labelCount_[oldHeight] == 0) {
387 gapRelabel(graph, oldHeight);
398 template<
class GRAPH,
class FLOW>
399 template<
class EDGE_WEIGHT_ITERATOR,
class SUBGRAPH_MASK>
401 MaxFlowPushRelabel<GRAPH, FLOW>::discharge(
403 const SUBGRAPH_MASK& mask,
404 EDGE_WEIGHT_ITERATOR edgeWeightIterator,
407 while(excess_[u] > 0) {
408 for(EdgeIterator it = graph.edgesFromVertexBegin(u); it != graph.edgesFromVertexEnd(u); ++it) {
409 const std::size_t edgeIndex = *it;
410 if (mask.edge(edgeIndex)) {
411 const std::size_t v = graph.vertexOfEdge(edgeIndex, 1);
412 if (mask.vertex(v)) {
413 if(edgeWeightIterator[edgeIndex] - flow_[edgeIndex] > 0 && height_[u] > height_[v]) {
414 push(graph, edgeWeightIterator, edgeIndex);
419 for(EdgeIterator it = graph.edgesToVertexBegin(u); it != graph.edgesToVertexEnd(u); ++it) {
420 const std::size_t edgeIndex = *it;
421 if (mask.edge(edgeIndex)) {
422 const std::size_t v = graph.vertexOfEdge(edgeIndex, 0);
423 if (mask.vertex(v)) {
424 if(flow_[edgeIndex] > 0 && height_[u] > height_[v]) {
425 pushBack(graph, edgeWeightIterator, edgeIndex);
430 relabel(graph, mask, edgeWeightIterator, u);
439 template<
class GRAPH,
class FLOW>
441 MaxFlowPushRelabel<GRAPH, FLOW>::gapRelabel(
443 const std::size_t threshold
445 for(std::size_t i = 0; i < graph.numberOfVertices(); i++) {
446 if(height_[i] > threshold) {
447 height_[i] = std::max(height_[i], graph.numberOfVertices() + 1);;
459 template<
class GRAPH,
class FLOW>
466 template <
class EDGE_WEIGHT_ITERATOR>
468 template <
class EDGE_WEIGHT_ITERATOR,
class SUBGRAPH_MASK>
473 template<
class EDGE_WEIGHT_ITERATOR,
class SUBGRAPH_MASK>
474 Flow operator()(
const GraphType&,
const SUBGRAPH_MASK&,
const EDGE_WEIGHT_ITERATOR,
const std::size_t,
const std::size_t);
477 std::deque<std::size_t> augmentingPath_;
479 std::vector<Flow> flow_;
480 std::size_t sourceVertexIndex_;
481 std::size_t sinkVertexIndex_;
484 template <
class EDGE_WEIGHT_ITERATOR,
class SUBGRAPH_MASK>
488 const std::size_t numberOfEdges,
489 const std::vector<Flow>&
flow,
490 const EDGE_WEIGHT_ITERATOR& edgeWeightIterator,
491 const SUBGRAPH_MASK& subgraphMask
493 : numberOfEdges_(numberOfEdges),
495 edgeWeightIterator_(edgeWeightIterator),
496 subgraphMask_(subgraphMask)
498 bool vertex(
const std::size_t v)
const
499 {
return subgraphMask_.vertex(v); }
500 bool edge(
const std::size_t e)
const
501 {
return capacity(e) >
Flow() && inMask(e); }
502 Flow capacity(
const std::size_t e)
const
504 if(e >= numberOfEdges_) {
505 return flow_[e - numberOfEdges_];
508 return edgeWeightIterator_[e] - flow_[e];
513 const std::size_t numberOfEdges_;
514 const std::vector<Flow>& flow_;
515 const EDGE_WEIGHT_ITERATOR& edgeWeightIterator_;
516 const SUBGRAPH_MASK& subgraphMask_;
517 bool inMask(
const std::size_t e)
const
519 if(e >= numberOfEdges_) {
520 return subgraphMask_.edge(e - numberOfEdges_);
523 return subgraphMask_.edge(e);
531 template<
class GRAPH,
class FLOW>
537 sourceVertexIndex_(),
549 template<
class GRAPH,
class FLOW>
550 template<
class EDGE_WEIGHT_ITERATOR>
554 EDGE_WEIGHT_ITERATOR edgeWeightIterator,
555 const std::size_t sourceVertexIndex,
556 const std::size_t sinkVertexIndex
561 sourceVertexIndex_(),
576 template<
class GRAPH,
class FLOW>
577 template<
class EDGE_WEIGHT_ITERATOR,
class SUBGRAPH_MASK>
581 const SUBGRAPH_MASK& subgraphMask,
582 EDGE_WEIGHT_ITERATOR edgeWeightIterator,
583 const std::size_t sourceVertexIndex,
584 const std::size_t sinkVertexIndex
589 sourceVertexIndex_(),
593 (*this)(graph, subgraphMask, edgeWeightIterator, sourceVertexIndex, sinkVertexIndex);
598 template<
class GRAPH,
class FLOW>
601 augmentingPath_.clear();
604 sourceVertexIndex_ = 0;
605 sinkVertexIndex_ = 0;
613 template<
class GRAPH,
class FLOW>
624 template<
class GRAPH,
class FLOW>
627 const std::size_t edgeIndex
629 assert(edgeIndex < flow_.size());
630 return flow_[edgeIndex];
641 template<
class GRAPH,
class FLOW>
642 template<
class EDGE_WEIGHT_ITERATOR,
class SUBGRAPH_MASK>
646 const SUBGRAPH_MASK& subgraphMask,
647 const EDGE_WEIGHT_ITERATOR edgeWeightIterator,
648 const std::size_t sourceVertexIndex,
649 const std::size_t sinkVertexIndex
651 const std::size_t numberOfEdges = graph.numberOfEdges();
654 sourceVertexIndex_ = sourceVertexIndex;
655 sinkVertexIndex_ = sinkVertexIndex;
656 flow_.resize(numberOfEdges);
657 std::fill(flow_.begin(), flow_.end(),
Flow());
658 augmentingPath_.clear();
659 rgraph_.assign(graph.numberOfVertices());
660 for(std::size_t edge = 0; edge < numberOfEdges; ++edge) {
661 rgraph_.insertEdge(graph.vertexOfEdge(edge, 0), graph.vertexOfEdge(edge, 1));
663 for(std::size_t edge = 0; edge < numberOfEdges; ++edge) {
664 rgraph_.insertEdge(graph.vertexOfEdge(edge, 1), graph.vertexOfEdge(edge, 0));
666 ResidualMask<EDGE_WEIGHT_ITERATOR, SUBGRAPH_MASK> residualMask(numberOfEdges, flow_, edgeWeightIterator, subgraphMask);
671 Flow minResidualCapacity;
672 while(
spspEdges(rgraph_, residualMask, sourceVertexIndex_, sinkVertexIndex_, augmentingPath_)) {
673 minResidualCapacity = residualMask.capacity(augmentingPath_[0]);
674 for(std::deque<std::size_t>::iterator it = augmentingPath_.begin(); it < augmentingPath_.end(); ++it) {
675 if(residualMask.capacity(*it) < minResidualCapacity) {
676 minResidualCapacity = residualMask.capacity(*it);
679 for(std::deque<std::size_t>::iterator it = augmentingPath_.begin(); it < augmentingPath_.end(); ++it) {
680 if(*it < numberOfEdges) {
681 flow_[*it] += minResidualCapacity;
684 flow_[*it - numberOfEdges] -= minResidualCapacity;
690 for(std::size_t edge = 0; edge < numberOfEdges; ++edge) {
691 if(graph.vertexOfEdge(edge, 0) == sourceVertexIndex_) {
692 maxFlow_ += flow_[edge];
702 #endif // #ifndef ANDRES_GRAPH_MAX_FLOW_HXX