Open
Graph Drawing
Framework

 v. 2023.09 (Elderberry)
 

Loading...
Searching...
No Matches
MaxFlowSTPlanarItaiShiloach.h
Go to the documentation of this file.
1
35#pragma once
36
38#include <ogdf/basic/Graph.h>
40#include <ogdf/basic/basic.h>
42
43#include <limits>
44
45namespace ogdf {
46
48
51template<typename TCap>
53private:
59 TCap unshiftedPriority(edge e) { return m_prioritizedEdges->priority(e) - TCap(1); }
60
65 TCap unshiftedTopPriority() { return m_prioritizedEdges->topPriority() - TCap(1); }
66
72 TCap shiftPriority(TCap priority) {
73 OGDF_ASSERT(priority < std::numeric_limits<TCap>::max());
74 return priority + TCap(1);
75 }
76
80 enum class NodeType { New, Path, Done };
81
88
90
93
96
99
102
105
108
109public:
114
124 TCap computeValue(const EdgeArray<TCap>& originalCapacities, const node& source,
125 const node& target) {
126 OGDF_ASSERT(source != target);
127 OGDF_ASSERT(isSTPlanar(*this->m_G, source, target));
128
129 // initialize auxiliary structures
130
131 m_partialFlow = (TCap)0;
132
133 this->m_s = &source;
134 this->m_t = &target;
135 this->m_cap = &originalCapacities;
136 this->m_flow->init(*this->m_G, (TCap)0);
138
139 // establish s-t-planarity
140 ConstCombinatorialEmbedding embedding(*this->m_G);
141#ifdef OGDF_DEBUG
142 embedding.consistencyCheck();
143#endif
144 adjEntry secondCommonAdj;
145 m_commonFaceAdj = embedding.findCommonFace(*this->m_s, *this->m_t, secondCommonAdj);
146 OGDF_ASSERT(m_commonFaceAdj != nullptr);
147
148 m_pred.init(*this->m_G, nullptr);
149 m_status.init(*this->m_G, NodeType::New);
150 m_visited.init(*this->m_G, false);
151 m_edgeCounter.init(*this->m_G, 0);
152 m_status[*this->m_s] = NodeType::Path;
153 m_status[*this->m_t] = NodeType::Path;
154
155 delete m_prioritizedEdges;
156 m_prioritizedEdges = new PrioritizedMapQueue<edge, TCap>(*this->m_G);
157
158 // saturate all paths
159
160 edge lastSaturated = nullptr;
161 while (findUppermostPath(lastSaturated)) {
162 lastSaturated = m_prioritizedEdges->topElement();
164 m_prioritizedEdges->pop();
165
166 (*this->m_flow)[lastSaturated] = (*this->m_cap)[lastSaturated];
167
168 m_pred[lastSaturated->target()] = nullptr;
169 OGDF_ASSERT(m_status[lastSaturated->target()] == NodeType::Path);
170 OGDF_ASSERT(m_status[lastSaturated->source()] == NodeType::Path);
171 }
172
173 return m_partialFlow;
174 }
175
184 // the flow value is only computed if the edge is deleted
185 while (!m_prioritizedEdges->empty()) {
186 edge e = m_prioritizedEdges->topElement();
187 dropEdge(e);
188 }
189 }
190
191 // use methods from super class
193 using MaxFlowModule<TCap>::computeFlow;
196 using MaxFlowModule<TCap>::init;
197
198private:
204 bool findUppermostPath(const edge saturatedEdge) {
205 node v;
206 adjEntry initialAdj;
207
208 if (saturatedEdge == nullptr) {
209 v = *this->m_s;
210 initialAdj = m_commonFaceAdj;
211 } else {
212 OGDF_ASSERT(!saturatedEdge->isSelfLoop());
213 OGDF_ASSERT(saturatedEdge->target() != *this->m_s);
214 v = saturatedEdge->source();
215 initialAdj = saturatedEdge->adjSource()->cyclicSucc();
216 }
217
218 OGDF_ASSERT(v != *this->m_t);
219
220 for (adjEntry adj = initialAdj; m_edgeCounter[v] < v->degree(); adj = adj->cyclicSucc()) {
221 m_edgeCounter[v]++;
222 edge e = adj->theEdge();
223
224 bool visited = m_visited[e];
225 m_visited[e] = true;
226
227 if (!visited && e->target() != v && m_status[e->target()] != NodeType::Done) {
228 EdgePathType pathType = getPathType(e);
230
231 if (pathType == EdgePathType::NoPath) {
232 // extend the path
233 appendEdge(e);
234 adj = e->adjTarget();
235 v = e->target();
236 } else if (pathType == EdgePathType::TargetPath) {
237 // merge path
238 node w = e->target();
239
240 // remove tangling target path
241 edge f;
242 while (m_pred[w] != nullptr) {
243 f = m_pred[w];
244 w = f->source();
245 dropEdge(f);
246 }
247
249 appendEdge(e);
250
251 return true;
252 } else {
253 // remove source path cycle
255 node w = e->target();
256
257 node formerSource;
258 while (e->source() != w) {
259 formerSource = e->source();
260 if (e->target() != w) {
261 dropEdge(e);
262 }
263 e = m_pred[formerSource]->adjSource()->theEdge();
264 }
265
266 dropEdge(e);
267 adj = e->adjSource();
268 v = e->source();
269 }
270 }
271 }
272
273 // v is a deadend
274 if (v == *this->m_s) {
275 return false;
276 } else {
277 edge e = m_pred[v];
278 dropEdge(e);
279 return findUppermostPath(e);
280 }
281 }
282
288 void appendEdge(const edge e) {
289 node v = e->target();
290 OGDF_ASSERT(m_pred[v] == nullptr);
291
292 // update path predecessor
293 m_pred[v] = e;
295
296 // insert into priority queue while
297 // taking into account the partial flow
298 TCap value = m_partialFlow + (*this->m_cap)[e];
299 m_prioritizedEdges->push(e, shiftPriority(value));
300 }
301
308 void dropEdge(const edge e) {
309 node v = e->target();
310 OGDF_ASSERT(m_pred[v] == e);
312
313 // update path predecessor
314 m_pred[v] = nullptr;
315 m_status[v] = v == *this->m_t ? NodeType::Path : NodeType::Done;
316
317 // remove edge from priority queue
318 TCap modCap = unshiftedPriority(e);
319 m_prioritizedEdges->decrease(e, std::numeric_limits<TCap>::min());
320#ifdef OGDF_DEBUG
321 edge f = m_prioritizedEdges->topElement();
322#endif
323 m_prioritizedEdges->pop();
324
325 // determine the flow on this edge
326 (*this->m_flow)[e] = m_partialFlow - (modCap - (*this->m_cap)[e]);
327
328 OGDF_ASSERT(e == f);
329 }
330
338 node v = e->source();
339 node w = e->target();
340
341 EdgePathType result =
343
344 while (result == EdgePathType::Unknown) {
345 if (v == e->target() || w == *this->m_s) {
347 } else if (m_pred[v] == nullptr || m_pred[w] == nullptr) {
349 } else if (m_pred[w]->source() == *this->m_s) {
351 } else {
352 OGDF_ASSERT(w != m_pred[w]->source());
353 OGDF_ASSERT(v != m_pred[v]->source());
354
355 w = m_pred[w]->source();
356 v = m_pred[v]->source();
357 }
358 }
359
360 return result;
361 }
362};
363
364}
Declaration of CombinatorialEmbedding and face.
Includes declaration of graph class.
Interface for Max Flow Algorithms.
Priority queue interface wrapping various heaps.
Basic declarations, included by all source files.
Class for adjacency list elements.
Definition Graph_d.h:143
adjEntry cyclicSucc() const
Returns the cyclic successor in the adjacency list.
Definition Graph_d.h:355
edge theEdge() const
Returns the edge associated with this adjacency entry.
Definition Graph_d.h:161
Combinatorial embeddings of planar graphs.
void consistencyCheck() const
Asserts that this embedding is consistent.
adjEntry findCommonFace(const node v, const node w, bool left=true) const
Identifies a common face of two nodes and returns the respective adjacency entry.
Class for the representation of edges.
Definition Graph_d.h:364
adjEntry adjSource() const
Returns the corresponding adjacancy entry at source node.
Definition Graph_d.h:408
adjEntry adjTarget() const
Returns the corresponding adjacancy entry at target node.
Definition Graph_d.h:411
bool isSelfLoop() const
Returns true iff the edge is a self-loop (source node = target node).
Definition Graph_d.h:420
node target() const
Returns the target node of the edge.
Definition Graph_d.h:402
node source() const
Returns the source node of the edge.
Definition Graph_d.h:399
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.
Computes a max flow in s-t-planar network via uppermost paths.
void dropEdge(const edge e)
Removes a single edge from the current path.
TCap unshiftedPriority(edge e)
To work with unsigned, we need a priority shifting of the elements in the priority queue.
NodeType
Each node has a certain type depending on its participation in any path.
TCap computeValue(const EdgeArray< TCap > &originalCapacities, const node &source, const node &target)
Computes the maximal flow from source to sink.
EdgeArray< bool > m_visited
Whether each edge has was visited.
~MaxFlowSTPlanarItaiShiloach()
Free allocated ressources.
TCap m_partialFlow
The flow reached thus far (monotonically increasing).
void computeFlowAfterValue()
Computes the actual flow on each edge.
EdgePathType getPathType(const edge e) const
Performs an alternating backtracking from source and target to determine whether the new node is part...
NodeArray< edge > m_pred
The predecessor of each node in the currently uppermost path.
TCap unshiftedTopPriority()
see unshiftedPriority
PrioritizedMapQueue< edge, TCap > * m_prioritizedEdges
A priority queue for storing all edges currently in a path.
EdgePathType
Each edge may be part of the source or target path.
NodeArray< int > m_edgeCounter
The number of edges visited from each node.
NodeArray< NodeType > m_status
The status of each node.
bool findUppermostPath(const edge saturatedEdge)
Establishes the next uppermost path.
void appendEdge(const edge e)
Appends an edge to the current path.
TCap shiftPriority(TCap priority)
see unshiftedPriority
Class for the representation of nodes.
Definition Graph_d.h:241
int degree() const
Returns the degree of the node (indegree + outdegree).
Definition Graph_d.h:284
Prioritized queue interface wrapper for heaps.
void init(const Base *base=nullptr)
Reinitializes the array. Associates the array with the matching registry of base.
RegisteredArray for edges of a graph, specialized for EdgeArray<edge>.
Definition Graph_d.h:717
RegisteredArray for nodes, edges and adjEntries of a graph.
Definition Graph_d.h:659
bool isSTPlanar(const Graph &graph, const node s, const node t)
Returns whether G is s-t-planar (i.e.
#define OGDF_ASSERT(expr)
Assert condition expr. See doc/build.md for more information.
Definition basic.h:52
The namespace for all OGDF objects.