Open
Graph Drawing
Framework

 v. 2023.09 (Elderberry)
 

Loading...
Searching...
No Matches
MaxFlowEdmondsKarp.h
Go to the documentation of this file.
1
33#pragma once
34
36
37namespace ogdf {
38
40
43template<typename TCap>
44class MaxFlowEdmondsKarp : public MaxFlowModule<TCap> {
45private:
49 NodeArray<adjEntry> pred(*this->m_G, nullptr); // edges from the predecessor
51 queue.pushBack(*this->m_s);
52
53 while (!queue.empty()) {
54 node v = queue.popFrontRet();
55 if (v == *this->m_t) {
56 // find minimum residual capacity value on s-t-path
57 TCap augmentVal = std::numeric_limits<TCap>::max();
58 for (node w = v; pred[w]; w = pred[w]->theNode()) {
59 const adjEntry adj = pred[w];
60 const edge e = adj->theEdge();
61 if (e->target() == w) { // real edge e = vw
62 if ((*this->m_cap)[e] - (*this->m_flow)[e] < augmentVal) {
63 augmentVal = (*this->m_cap)[e] - (*this->m_flow)[e];
64 }
65 } else { // virtual edge e = wv
66 if ((*this->m_flow)[e] < augmentVal) {
67 augmentVal = (*this->m_flow)[e];
68 }
69 }
70 }
71 // augment s-t-path by this value
72 for (node w = v; pred[w]; w = pred[w]->theNode()) {
73 const adjEntry adj = pred[w];
74 const edge e = adj->theEdge();
75 if (e->target() == w) { // real edge e = vw
76 (*this->m_flow)[e] += augmentVal;
77 } else { // virtual edge e = wv
78 (*this->m_flow)[e] -= augmentVal;
79 }
80 }
81 return true;
82 }
83 for (adjEntry adj : v->adjEntries) {
84 const node w = adj->twinNode();
85 if (w != (*this->m_s) && !pred[w]) // if not already visited
86 {
87 const edge e = adj->theEdge();
88 if (e->source() == v) { // real edge e = vw
89 if ((*this->m_et).greater((*this->m_cap)[e], (*this->m_flow)[e])) {
90 // reachable in residual graph
91 queue.pushBack(w);
92 pred[w] = adj;
93 }
94 } else { // virtual edge (adj) wv
95 if ((*this->m_et).greater((*this->m_flow)[e], (TCap)0)) {
96 // reachable in residual graph
97 queue.pushBack(w);
98 pred[w] = adj;
99 }
100 }
101 }
102 }
103 }
104
105 return false;
106 }
107
108public:
113
119 TCap computeValue(const EdgeArray<TCap>& cap, const node& s, const node& t) {
120 // clear old flow
121 this->m_flow->fill((TCap)0);
122 // store capacity, source and sink
123 this->m_cap = &cap;
124 this->m_s = &s;
125 this->m_t = &t;
127
128 if (*this->m_s == *this->m_t) {
129 return (TCap)0;
130 }
131
133 ;
134 }
135 TCap flowValue = 0;
136 for (adjEntry adj : s->adjEntries) {
137 edge e = adj->theEdge();
138 if (e->source() == s) {
139 flowValue += (*this->m_flow)[e];
140 } else {
141 flowValue -= (*this->m_flow)[e];
142 }
143 }
144 return flowValue;
145 }
146
149 void computeFlowAfterValue() { /* nothing to do here */
150 }
151
152 // use methods from super class
158};
159
160}
Interface for Max Flow Algorithms.
Class for adjacency list elements.
Definition Graph_d.h:79
edge theEdge() const
Returns the edge associated with this adjacency entry.
Definition Graph_d.h:97
Dynamic arrays indexed with edges.
Definition EdgeArray.h:125
void fill(const T &x)
Sets all array elements to x.
Definition EdgeArray.h:314
Class for the representation of edges.
Definition Graph_d.h:300
node target() const
Returns the target node of the edge.
Definition Graph_d.h:338
node source() const
Returns the source node of the edge.
Definition Graph_d.h:335
Doubly linked lists (maintaining the length of the list).
Definition List.h:1435
iterator pushBack(const E &x)
Adds element x at the end of the list.
Definition List.h:1531
bool empty() const
Returns true iff the list is empty.
Definition List.h:270
Computes a max flow via Edmonds-Karp.
bool augmentShortestSourceSinkPath()
If there is an augumenting path: do an interation step. Otherwise return false so that the algorithm ...
TCap computeValue(const EdgeArray< TCap > &cap, const node &s, const node &t)
Implementation of computeValue from the super class. The flow array is cleared, cap,...
void computeFlowAfterValue()
Implementation of computeFlowAfterValue from the super class. This does nothing, because the algorith...
const node * m_t
Pointer to the sink node.
virtual void init(const Graph &graph, EdgeArray< TCap > *flow=nullptr)
Initialize the problem with a graph and optional flow array. If no flow array is given,...
EdgeArray< TCap > * m_flow
Pointer to (extern) flow array.
void useEpsilonTest(const double &eps)
Change the used EpsilonTest from StandardEpsilonTest to a user given EpsilonTest.
bool isFeasibleInstance() const
Return whether the instance is feasible, i.e. the capacities are non-negative.
const Graph * m_G
Pointer to the given graph.
const node * m_s
Pointer to the source node.
const EdgeArray< TCap > * m_cap
Pointer to the given capacity array.
MaxFlowModule()
Empty Constructor.
TCap computeFlow(EdgeArray< TCap > &cap, node &s, node &t, EdgeArray< TCap > &flow)
Only a shortcut for computeValue and computeFlowAfterValue.
EpsilonTest * m_et
Pointer to the used EpsilonTest.
Dynamic arrays indexed with nodes.
Definition NodeArray.h:125
Class for the representation of nodes.
Definition Graph_d.h:177
internal::GraphObjectContainer< AdjElement > adjEntries
The container containing all entries in the adjacency list of this node.
Definition Graph_d.h:208
#define OGDF_ASSERT(expr)
Assert condition expr. See doc/build.md for more information.
Definition basic.h:41
static MultilevelBuilder * getDoubleFactoredZeroAdjustedMerger()
The namespace for all OGDF objects.