Open
Graph Drawing
Framework

 v. 2023.09 (Elderberry)
 

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 
45 namespace ogdf {
46 
48 
51 template<typename TCap>
53 private:
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 
109 public:
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
197 
198 private:
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);
229  OGDF_ASSERT(pathType != EdgePathType::Unknown);
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 
337  EdgePathType getPathType(const edge e) const {
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) {
346  result = EdgePathType::SourcePath;
347  } else if (m_pred[v] == nullptr || m_pred[w] == nullptr) {
348  result = EdgePathType::TargetPath;
349  } else if (m_pred[w]->source() == *this->m_s) {
350  result = EdgePathType::SourcePath;
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 }
ogdf
The namespace for all OGDF objects.
Definition: multilevelmixer.cpp:39
Graph.h
Includes declaration of graph class.
ogdf::MaxFlowModule< TCap >::isFeasibleInstance
bool isFeasibleInstance() const
Return whether the instance is feasible, i.e. the capacities are non-negative.
Definition: MaxFlowModule.h:148
OGDF_ASSERT
#define OGDF_ASSERT(expr)
Assert condition expr. See doc/build.md for more information.
Definition: basic.h:66
MaxFlowModule.h
Interface for Max Flow Algorithms.
PriorityQueue.h
Priority queue interface wrapping various heaps.
ogdf::ConstCombinatorialEmbedding::findCommonFace
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.
Definition: CombinatorialEmbedding.h:371
ogdf::MaxFlowSTPlanarItaiShiloach::m_prioritizedEdges
PrioritizedMapQueue< edge, TCap > * m_prioritizedEdges
A priority queue for storing all edges currently in a path.
Definition: MaxFlowSTPlanarItaiShiloach.h:104
ogdf::MaxFlowModule< TCap >::m_t
const node * m_t
Pointer to the sink node.
Definition: MaxFlowModule.h:48
ogdf::MaxFlowSTPlanarItaiShiloach::m_pred
NodeArray< edge > m_pred
The predecessor of each node in the currently uppermost path.
Definition: MaxFlowSTPlanarItaiShiloach.h:98
ogdf::MaxFlowSTPlanarItaiShiloach
Computes a max flow in s-t-planar network via uppermost paths.
Definition: MaxFlowSTPlanarItaiShiloach.h:52
ogdf::MaxFlowSTPlanarItaiShiloach::~MaxFlowSTPlanarItaiShiloach
~MaxFlowSTPlanarItaiShiloach()
Free allocated ressources.
Definition: MaxFlowSTPlanarItaiShiloach.h:113
ogdf::MaxFlowSTPlanarItaiShiloach::m_edgeCounter
NodeArray< int > m_edgeCounter
The number of edges visited from each node.
Definition: MaxFlowSTPlanarItaiShiloach.h:95
ogdf::MaxFlowSTPlanarItaiShiloach::EdgePathType::Unknown
@ Unknown
ogdf::MaxFlowSTPlanarItaiShiloach::m_status
NodeArray< NodeType > m_status
The status of each node.
Definition: MaxFlowSTPlanarItaiShiloach.h:101
ogdf::MaxFlowSTPlanarItaiShiloach::EdgePathType::TargetPath
@ TargetPath
ogdf::MaxFlowSTPlanarItaiShiloach::EdgePathType::SourcePath
@ SourcePath
ogdf::MaxFlowSTPlanarItaiShiloach::NodeType::New
@ New
ogdf::AdjElement
Class for adjacency list elements.
Definition: Graph_d.h:142
ogdf::MaxFlowSTPlanarItaiShiloach::unshiftedTopPriority
TCap unshiftedTopPriority()
see unshiftedPriority
Definition: MaxFlowSTPlanarItaiShiloach.h:65
ogdf::MaxFlowModule< TCap >::m_s
const node * m_s
Pointer to the source node.
Definition: MaxFlowModule.h:47
ogdf::EdgeElement::isSelfLoop
bool isSelfLoop() const
Returns true iff the edge is a self-loop (source node = target node).
Definition: Graph_d.h:419
ogdf::NodeElement::degree
int degree() const
Returns the degree of the node (indegree + outdegree).
Definition: Graph_d.h:283
ogdf::MaxFlowModule< TCap >::m_G
const Graph * m_G
Pointer to the given graph.
Definition: MaxFlowModule.h:45
ogdf::MaxFlowSTPlanarItaiShiloach::dropEdge
void dropEdge(const edge e)
Removes a single edge from the current path.
Definition: MaxFlowSTPlanarItaiShiloach.h:308
ogdf::MaxFlowSTPlanarItaiShiloach::NodeType::Done
@ Done
ogdf::PrioritizedMapQueue
Prioritized queue interface wrapper for heaps.
Definition: PriorityQueue.h:411
ogdf::MaxFlowSTPlanarItaiShiloach::m_visited
EdgeArray< bool > m_visited
Whether each edge has was visited.
Definition: MaxFlowSTPlanarItaiShiloach.h:92
ogdf::MaxFlowSTPlanarItaiShiloach::unshiftedPriority
TCap unshiftedPriority(edge e)
To work with unsigned, we need a priority shifting of the elements in the priority queue.
Definition: MaxFlowSTPlanarItaiShiloach.h:59
ogdf::EdgeElement::source
node source() const
Returns the source node of the edge.
Definition: Graph_d.h:398
ogdf::internal::GraphRegisteredArray
RegisteredArray for nodes, edges and adjEntries of a graph.
Definition: Graph_d.h:658
ogdf::EdgeElement::adjSource
adjEntry adjSource() const
Returns the corresponding adjacancy entry at source node.
Definition: Graph_d.h:407
ogdf::MaxFlowSTPlanarItaiShiloach::findUppermostPath
bool findUppermostPath(const edge saturatedEdge)
Establishes the next uppermost path.
Definition: MaxFlowSTPlanarItaiShiloach.h:204
ogdf::MaxFlowSTPlanarItaiShiloach::computeFlowAfterValue
void computeFlowAfterValue()
Computes the actual flow on each edge.
Definition: MaxFlowSTPlanarItaiShiloach.h:183
ogdf::MaxFlowSTPlanarItaiShiloach::getPathType
EdgePathType getPathType(const edge e) const
Performs an alternating backtracking from source and target to determine whether the new node is part...
Definition: MaxFlowSTPlanarItaiShiloach.h:337
ogdf::MaxFlowSTPlanarItaiShiloach::shiftPriority
TCap shiftPriority(TCap priority)
see unshiftedPriority
Definition: MaxFlowSTPlanarItaiShiloach.h:72
ogdf::AdjElement::cyclicSucc
adjEntry cyclicSucc() const
Returns the cyclic successor in the adjacency list.
Definition: Graph_d.h:354
ogdf::ConstCombinatorialEmbedding
Combinatorial embeddings of planar graphs.
Definition: CombinatorialEmbedding.h:216
ogdf::MaxFlowSTPlanarItaiShiloach::NodeType::Path
@ Path
ogdf::EdgeElement::adjTarget
adjEntry adjTarget() const
Returns the corresponding adjacancy entry at target node.
Definition: Graph_d.h:410
basic.h
Basic declarations, included by all source files.
ogdf::MaxFlowSTPlanarItaiShiloach::m_partialFlow
TCap m_partialFlow
The flow reached thus far (monotonically increasing).
Definition: MaxFlowSTPlanarItaiShiloach.h:107
CombinatorialEmbedding.h
Declaration of CombinatorialEmbedding and face.
ogdf::MaxFlowSTPlanarItaiShiloach::NodeType
NodeType
Each node has a certain type depending on its participation in any path.
Definition: MaxFlowSTPlanarItaiShiloach.h:80
ogdf::MaxFlowModule
Definition: MaxFlowModule.h:41
ogdf::MaxFlowSTPlanarItaiShiloach::computeValue
TCap computeValue(const EdgeArray< TCap > &originalCapacities, const node &source, const node &target)
Computes the maximal flow from source to sink.
Definition: MaxFlowSTPlanarItaiShiloach.h:124
ogdf::MaxFlowSTPlanarItaiShiloach::EdgePathType
EdgePathType
Each edge may be part of the source or target path.
Definition: MaxFlowSTPlanarItaiShiloach.h:87
ogdf::EdgeElement
Class for the representation of edges.
Definition: Graph_d.h:363
ogdf::RegisteredArray< GraphRegistry< Key >, Value, WithDefault, Graph >::init
void init(const Graph *base=nullptr)
Reinitializes the array. Associates the array with the matching registry of base.
Definition: RegisteredArray.h:858
ogdf::MaxFlowModule< TCap >::m_cap
const EdgeArray< TCap > * m_cap
Pointer to the given capacity array.
Definition: MaxFlowModule.h:46
ogdf::EdgeElement::target
node target() const
Returns the target node of the edge.
Definition: Graph_d.h:401
ogdf::MaxFlowSTPlanarItaiShiloach::EdgePathType::NoPath
@ NoPath
ogdf::NodeElement
Class for the representation of nodes.
Definition: Graph_d.h:240
ogdf::MaxFlowSTPlanarItaiShiloach::m_commonFaceAdj
adjEntry m_commonFaceAdj
Definition: MaxFlowSTPlanarItaiShiloach.h:89
ogdf::isSTPlanar
bool isSTPlanar(const Graph &graph, const node s, const node t)
Returns whether G is s-t-planar (i.e.
Definition: extended_graph_alg.h:297
ogdf::MaxFlowSTPlanarItaiShiloach::appendEdge
void appendEdge(const edge e)
Appends an edge to the current path.
Definition: MaxFlowSTPlanarItaiShiloach.h:288
ogdf::MaxFlowModule< TCap >::m_flow
EdgeArray< TCap > * m_flow
Pointer to (extern) flow array.
Definition: MaxFlowModule.h:44
ogdf::internal::EdgeArrayBase2
RegisteredArray for edges of a graph, specialized for EdgeArray<edge>.
Definition: Graph_d.h:716
ogdf::ConstCombinatorialEmbedding::consistencyCheck
void consistencyCheck() const
Asserts that this embedding is consistent.