Open
Graph Drawing
Framework

 v. 2023.09 (Elderberry)
 

MaxFlowSTPlanarItaiShiloach.h
Go to the documentation of this file.
1 
35 #pragma once
36 
40 
41 #include <limits>
42 
43 namespace ogdf {
44 
46 
49 template<typename TCap>
51 private:
57  TCap unshiftedPriority(edge e) { return m_prioritizedEdges->priority(e) - TCap(1); }
58 
63  TCap unshiftedTopPriority() { return m_prioritizedEdges->topPriority() - TCap(1); }
64 
70  TCap shiftPriority(TCap priority) {
71  OGDF_ASSERT(priority < std::numeric_limits<TCap>::max());
72  return priority + TCap(1);
73  }
74 
78  enum class NodeType { New, Path, Done };
79 
86 
88 
91 
94 
97 
100 
103 
106 
107 public:
112 
122  TCap computeValue(const EdgeArray<TCap>& originalCapacities, const node& source,
123  const node& target) {
124  OGDF_ASSERT(source != target);
125  OGDF_ASSERT(isSTPlanar(*this->m_G, source, target));
126 
127  // initialize auxiliary structures
128 
129  m_partialFlow = (TCap)0;
130 
131  this->m_s = &source;
132  this->m_t = &target;
133  this->m_cap = &originalCapacities;
134  this->m_flow->init(*this->m_G, (TCap)0);
136 
137  // establish s-t-planarity
138  ConstCombinatorialEmbedding embedding(*this->m_G);
139 #ifdef OGDF_DEBUG
140  embedding.consistencyCheck();
141 #endif
142  adjEntry secondCommonAdj;
143  m_commonFaceAdj = embedding.findCommonFace(*this->m_s, *this->m_t, secondCommonAdj);
144  OGDF_ASSERT(m_commonFaceAdj != nullptr);
145 
146  m_pred.init(*this->m_G, nullptr);
147  m_status.init(*this->m_G, NodeType::New);
148  m_visited.init(*this->m_G, false);
149  m_edgeCounter.init(*this->m_G, 0);
150  m_status[*this->m_s] = NodeType::Path;
151  m_status[*this->m_t] = NodeType::Path;
152 
153  delete m_prioritizedEdges;
154  m_prioritizedEdges = new PrioritizedMapQueue<edge, TCap>(*this->m_G);
155 
156  // saturate all paths
157 
158  edge lastSaturated = nullptr;
159  while (findUppermostPath(lastSaturated)) {
160  lastSaturated = m_prioritizedEdges->topElement();
162  m_prioritizedEdges->pop();
163 
164  (*this->m_flow)[lastSaturated] = (*this->m_cap)[lastSaturated];
165 
166  m_pred[lastSaturated->target()] = nullptr;
167  OGDF_ASSERT(m_status[lastSaturated->target()] == NodeType::Path);
168  OGDF_ASSERT(m_status[lastSaturated->source()] == NodeType::Path);
169  }
170 
171  return m_partialFlow;
172  }
173 
182  // the flow value is only computed if the edge is deleted
183  while (!m_prioritizedEdges->empty()) {
184  edge e = m_prioritizedEdges->topElement();
185  dropEdge(e);
186  }
187  }
188 
189  // use methods from super class
195 
196 private:
202  bool findUppermostPath(const edge saturatedEdge) {
203  node v;
204  adjEntry initialAdj;
205 
206  if (saturatedEdge == nullptr) {
207  v = *this->m_s;
208  initialAdj = m_commonFaceAdj;
209  } else {
210  OGDF_ASSERT(!saturatedEdge->isSelfLoop());
211  OGDF_ASSERT(saturatedEdge->target() != *this->m_s);
212  v = saturatedEdge->source();
213  initialAdj = saturatedEdge->adjSource()->cyclicSucc();
214  }
215 
216  OGDF_ASSERT(v != *this->m_t);
217 
218  for (adjEntry adj = initialAdj; m_edgeCounter[v] < v->degree(); adj = adj->cyclicSucc()) {
219  m_edgeCounter[v]++;
220  edge e = adj->theEdge();
221 
222  bool visited = m_visited[e];
223  m_visited[e] = true;
224 
225  if (!visited && e->target() != v && m_status[e->target()] != NodeType::Done) {
226  EdgePathType pathType = getPathType(e);
227  OGDF_ASSERT(pathType != EdgePathType::Unknown);
228 
229  if (pathType == EdgePathType::NoPath) {
230  // extend the path
231  appendEdge(e);
232  adj = e->adjTarget();
233  v = e->target();
234  } else if (pathType == EdgePathType::TargetPath) {
235  // merge path
236  node w = e->target();
237 
238  // remove tangling target path
239  edge f;
240  while (m_pred[w] != nullptr) {
241  f = m_pred[w];
242  w = f->source();
243  dropEdge(f);
244  }
245 
247  appendEdge(e);
248 
249  return true;
250  } else {
251  // remove source path cycle
253  node w = e->target();
254 
255  node formerSource;
256  while (e->source() != w) {
257  formerSource = e->source();
258  if (e->target() != w) {
259  dropEdge(e);
260  }
261  e = m_pred[formerSource]->adjSource()->theEdge();
262  }
263 
264  dropEdge(e);
265  adj = e->adjSource();
266  v = e->source();
267  }
268  }
269  }
270 
271  // v is a deadend
272  if (v == *this->m_s) {
273  return false;
274  } else {
275  edge e = m_pred[v];
276  dropEdge(e);
277  return findUppermostPath(e);
278  }
279  }
280 
286  void appendEdge(const edge e) {
287  node v = e->target();
288  OGDF_ASSERT(m_pred[v] == nullptr);
289 
290  // update path predecessor
291  m_pred[v] = e;
293 
294  // insert into priority queue while
295  // taking into account the partial flow
296  TCap value = m_partialFlow + (*this->m_cap)[e];
297  m_prioritizedEdges->push(e, shiftPriority(value));
298  }
299 
306  void dropEdge(const edge e) {
307  node v = e->target();
308  OGDF_ASSERT(m_pred[v] == e);
310 
311  // update path predecessor
312  m_pred[v] = nullptr;
313  m_status[v] = v == *this->m_t ? NodeType::Path : NodeType::Done;
314 
315  // remove edge from priority queue
316  TCap modCap = unshiftedPriority(e);
317  m_prioritizedEdges->decrease(e, std::numeric_limits<TCap>::min());
318 #ifdef OGDF_DEBUG
319  edge f = m_prioritizedEdges->topElement();
320 #endif
321  m_prioritizedEdges->pop();
322 
323  // determine the flow on this edge
324  (*this->m_flow)[e] = m_partialFlow - (modCap - (*this->m_cap)[e]);
325 
326  OGDF_ASSERT(e == f);
327  }
328 
335  EdgePathType getPathType(const edge e) const {
336  node v = e->source();
337  node w = e->target();
338 
339  EdgePathType result =
341 
342  while (result == EdgePathType::Unknown) {
343  if (v == e->target() || w == *this->m_s) {
344  result = EdgePathType::SourcePath;
345  } else if (m_pred[v] == nullptr || m_pred[w] == nullptr) {
346  result = EdgePathType::TargetPath;
347  } else if (m_pred[w]->source() == *this->m_s) {
348  result = EdgePathType::SourcePath;
349  } else {
350  OGDF_ASSERT(w != m_pred[w]->source());
351  OGDF_ASSERT(v != m_pred[v]->source());
352 
353  w = m_pred[w]->source();
354  v = m_pred[v]->source();
355  }
356  }
357 
358  return result;
359  }
360 };
361 
362 }
ogdf
The namespace for all OGDF objects.
Definition: AugmentationModule.h:36
ogdf::MaxFlowModule< TCap >::isFeasibleInstance
bool isFeasibleInstance() const
Return whether the instance is feasible, i.e. the capacities are non-negative.
Definition: MaxFlowModule.h:147
OGDF_ASSERT
#define OGDF_ASSERT(expr)
Assert condition expr. See doc/build.md for more information.
Definition: basic.h:54
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:362
ogdf::MaxFlowSTPlanarItaiShiloach::m_prioritizedEdges
PrioritizedMapQueue< edge, TCap > * m_prioritizedEdges
A priority queue for storing all edges currently in a path.
Definition: MaxFlowSTPlanarItaiShiloach.h:102
ogdf::MaxFlowModule< TCap >::m_t
const node * m_t
Pointer to the sink node.
Definition: MaxFlowModule.h:47
ogdf::MaxFlowSTPlanarItaiShiloach::m_pred
NodeArray< edge > m_pred
The predecessor of each node in the currently uppermost path.
Definition: MaxFlowSTPlanarItaiShiloach.h:96
ogdf::MaxFlowSTPlanarItaiShiloach
Computes a max flow in s-t-planar network via uppermost paths.
Definition: MaxFlowSTPlanarItaiShiloach.h:50
ogdf::MaxFlowSTPlanarItaiShiloach::~MaxFlowSTPlanarItaiShiloach
~MaxFlowSTPlanarItaiShiloach()
Free allocated ressources.
Definition: MaxFlowSTPlanarItaiShiloach.h:111
ogdf::MaxFlowSTPlanarItaiShiloach::m_edgeCounter
NodeArray< int > m_edgeCounter
The number of edges visited from each node.
Definition: MaxFlowSTPlanarItaiShiloach.h:93
ogdf::MaxFlowSTPlanarItaiShiloach::EdgePathType::Unknown
@ Unknown
ogdf::MaxFlowSTPlanarItaiShiloach::m_status
NodeArray< NodeType > m_status
The status of each node.
Definition: MaxFlowSTPlanarItaiShiloach.h:99
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:135
ogdf::MaxFlowSTPlanarItaiShiloach::unshiftedTopPriority
TCap unshiftedTopPriority()
see unshiftedPriority
Definition: MaxFlowSTPlanarItaiShiloach.h:63
ogdf::MaxFlowModule< TCap >::m_s
const node * m_s
Pointer to the source node.
Definition: MaxFlowModule.h:46
ogdf::EdgeElement::isSelfLoop
bool isSelfLoop() const
Returns true iff the edge is a self-loop (source node = target node).
Definition: Graph_d.h:412
ogdf::NodeElement::degree
int degree() const
Returns the degree of the node (indegree + outdegree).
Definition: Graph_d.h:276
ogdf::MaxFlowModule< TCap >::m_G
const Graph * m_G
Pointer to the given graph.
Definition: MaxFlowModule.h:44
ogdf::MaxFlowSTPlanarItaiShiloach::dropEdge
void dropEdge(const edge e)
Removes a single edge from the current path.
Definition: MaxFlowSTPlanarItaiShiloach.h:306
ogdf::MaxFlowSTPlanarItaiShiloach::NodeType::Done
@ Done
ogdf::PrioritizedMapQueue
Prioritized queue interface wrapper for heaps.
Definition: PriorityQueue.h:409
ogdf::MaxFlowSTPlanarItaiShiloach::m_visited
EdgeArray< bool > m_visited
Whether each edge has was visited.
Definition: MaxFlowSTPlanarItaiShiloach.h:90
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:57
ogdf::EdgeElement::source
node source() const
Returns the source node of the edge.
Definition: Graph_d.h:391
ogdf::internal::GraphRegisteredArray
RegisteredArray for nodes, edges and adjEntries of a graph.
Definition: Graph_d.h:651
ogdf::EdgeElement::adjSource
adjEntry adjSource() const
Returns the corresponding adjacancy entry at source node.
Definition: Graph_d.h:400
ogdf::MaxFlowSTPlanarItaiShiloach::findUppermostPath
bool findUppermostPath(const edge saturatedEdge)
Establishes the next uppermost path.
Definition: MaxFlowSTPlanarItaiShiloach.h:202
ogdf::MaxFlowSTPlanarItaiShiloach::computeFlowAfterValue
void computeFlowAfterValue()
Computes the actual flow on each edge.
Definition: MaxFlowSTPlanarItaiShiloach.h:181
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:335
ogdf::MaxFlowSTPlanarItaiShiloach::shiftPriority
TCap shiftPriority(TCap priority)
see unshiftedPriority
Definition: MaxFlowSTPlanarItaiShiloach.h:70
ogdf::AdjElement::cyclicSucc
adjEntry cyclicSucc() const
Returns the cyclic successor in the adjacency list.
Definition: Graph_d.h:347
ogdf::ConstCombinatorialEmbedding
Combinatorial embeddings of planar graphs.
Definition: CombinatorialEmbedding.h:207
ogdf::MaxFlowSTPlanarItaiShiloach::NodeType::Path
@ Path
ogdf::EdgeElement::adjTarget
adjEntry adjTarget() const
Returns the corresponding adjacancy entry at target node.
Definition: Graph_d.h:403
ogdf::MaxFlowSTPlanarItaiShiloach::m_partialFlow
TCap m_partialFlow
The flow reached thus far (monotonically increasing).
Definition: MaxFlowSTPlanarItaiShiloach.h:105
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:78
ogdf::MaxFlowModule
Definition: MaxFlowModule.h:40
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:122
ogdf::MaxFlowSTPlanarItaiShiloach::EdgePathType
EdgePathType
Each edge may be part of the source or target path.
Definition: MaxFlowSTPlanarItaiShiloach.h:85
ogdf::EdgeElement
Class for the representation of edges.
Definition: Graph_d.h:356
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:849
ogdf::MaxFlowModule< TCap >::m_cap
const EdgeArray< TCap > * m_cap
Pointer to the given capacity array.
Definition: MaxFlowModule.h:45
ogdf::EdgeElement::target
node target() const
Returns the target node of the edge.
Definition: Graph_d.h:394
ogdf::MaxFlowSTPlanarItaiShiloach::EdgePathType::NoPath
@ NoPath
ogdf::NodeElement
Class for the representation of nodes.
Definition: Graph_d.h:233
ogdf::MaxFlowSTPlanarItaiShiloach::m_commonFaceAdj
adjEntry m_commonFaceAdj
Definition: MaxFlowSTPlanarItaiShiloach.h:87
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:287
ogdf::MaxFlowSTPlanarItaiShiloach::appendEdge
void appendEdge(const edge e)
Appends an edge to the current path.
Definition: MaxFlowSTPlanarItaiShiloach.h:286
ogdf::MaxFlowModule< TCap >::m_flow
EdgeArray< TCap > * m_flow
Pointer to (extern) flow array.
Definition: MaxFlowModule.h:43
ogdf::internal::EdgeArrayBase2
RegisteredArray for edges of a graph, specialized for EdgeArray<edge>.
Definition: Graph_d.h:709
ogdf::ConstCombinatorialEmbedding::consistencyCheck
void consistencyCheck() const
Asserts that this embedding is consistent.