Open
Graph Drawing
Framework

 v. 2023.09 (Elderberry)
 

MinSTCutMaxFlow.h
Go to the documentation of this file.
1 
32 #pragma once
33 
36 
37 #include <memory>
38 
39 namespace ogdf {
40 
48 template<typename TCost>
49 class MinSTCutMaxFlow : public MinSTCutModule<TCost> {
51 
52 public:
68  explicit MinSTCutMaxFlow(bool treatAsUndirected = true,
70  bool primaryCut = true, bool calculateOtherCut = true,
71  EpsilonTest* epsilonTest = new EpsilonTest())
72  : m_mfModule(mfModule)
73  , m_treatAsUndirected(treatAsUndirected)
74  , m_primaryCut(primaryCut)
75  , m_calculateOtherCut(calculateOtherCut)
76  , m_et(epsilonTest) { }
77 
81  virtual bool call(const Graph& graph, const EdgeArray<TCost>& weight, node s, node t,
82  List<edge>& edgeList, edge e_st = nullptr) override;
83 
87  virtual bool call(const Graph& graph, node s, node t, List<edge>& edgeList,
88  edge e_st = nullptr) override {
89  EdgeArray<TCost> weight(graph, 1);
90  return call(graph, weight, s, t, edgeList, e_st);
91  }
92 
102  void call(const Graph& graph, const EdgeArray<TCost>& weights, const EdgeArray<TCost>& flow,
103  const node source, const node target);
104 
108  enum class cutType {
109  FRONT_CUT,
110  BACK_CUT,
111  NO_CUT
112  };
113 
117  void setEpsilonTest(EpsilonTest* et) { m_et.reset(et); }
118 
128  }
129 
133  bool isFrontCutEdge(const edge e) const {
135  return m_nodeSet[e->source()] == cutType::FRONT_CUT
136  && m_nodeSet[e->target()] != cutType::FRONT_CUT;
137  }
138 
142  bool isBackCutEdge(const edge e) const {
144  return m_nodeSet[e->target()] == cutType::BACK_CUT
145  && m_nodeSet[e->source()] != cutType::BACK_CUT;
146  }
147 
152  bool isInFrontCut(const node v) const {
154  return m_nodeSet[v] == cutType::FRONT_CUT;
155  }
156 
163  bool isInBackCut(const node v) const {
165  return m_nodeSet[v] == cutType::BACK_CUT;
166  }
167 
179  bool isOfType(const node v, cutType type) const { return m_nodeSet[v] == type; }
180 
181 private:
183  std::unique_ptr<MaxFlowModule<TCost>> m_mfModule;
185  bool m_treatAsUndirected = false;
187  bool m_primaryCut = true;
193  bool m_calculateOtherCut = true;
194 
195 
196  std::unique_ptr<EpsilonTest> m_et;
203 
211  void markCut(node startNode, bool frontCut, std::function<node(node)> origNode) {
212  List<node> queue;
213  queue.pushBack(startNode);
214  m_nodeSet[origNode(startNode)] = (frontCut ? cutType::FRONT_CUT : cutType::BACK_CUT);
215  frontCut ? m_frontCutCount++ : m_backCutCount++;
216 
217  while (!queue.empty()) {
218  const node v = queue.popFrontRet();
219  for (adjEntry adj : v->adjEntries) {
220  const node w = adj->twinNode();
221  const edge e = adj->theEdge();
222  if (m_nodeSet[origNode(w)] == cutType::NO_CUT
223  && (((frontCut ? e->source() : e->target()) == v
224  && m_et->less(m_flow[e], m_weight[e]))
225  || ((frontCut ? e->target() : e->source()) == v
226  && m_et->greater(m_flow[e], TCost(0))))) {
227  queue.pushBack(w);
228  m_nodeSet[origNode(w)] = (frontCut ? cutType::FRONT_CUT : cutType::BACK_CUT);
229  frontCut ? m_frontCutCount++ : m_backCutCount++;
230  }
231  }
232  }
233  }
234 
245  void computeCut(const Graph& graph, std::function<edge(edge)> origEdge,
246  std::function<node(node)> origNode, const node source, const node target,
247  List<edge>& edgeList) {
248  m_frontCutCount = 0;
249  m_backCutCount = 0;
250  m_totalCount = graph.numberOfNodes();
251 
252 
253  List<node> queue;
254  m_nodeSet.init(graph, cutType::NO_CUT);
255 
257  // front cut
258  markCut(source, true, origNode);
259  }
260 
262  // back cut
263  markCut(target, false, origNode);
264  }
265 
267  EdgeArray<bool> visited(graph, false);
268  node startNode = (m_primaryCut ? source : target);
269  adjEntry startAdj = startNode->firstAdj();
270  if (startAdj == nullptr) {
271  return;
272  }
273  if (startAdj->theEdge()->adjTarget() != startAdj) {
274  stack.push(startAdj->theEdge());
275  }
276  for (adjEntry adj = (m_primaryCut ? startAdj->cyclicSucc() : startAdj->cyclicPred());
277  adj != startAdj; adj = (m_primaryCut ? adj->cyclicSucc() : adj->cyclicPred())) {
278  if (adj->theEdge()->adjTarget() != adj) {
279  stack.push(adj->theEdge());
280  }
281  }
282  while (!stack.empty()) {
283  edge e = stack.popRet();
284  if (visited[origEdge(e)]) {
285  continue;
286  }
287  visited[origEdge(e)] = true;
288  if (m_nodeSet[origNode(e->source())] == cutType::FRONT_CUT
289  && m_nodeSet[origNode(e->target())] != cutType::FRONT_CUT) {
290  edgeList.pushBack(origEdge(e));
291 
292  if (m_gc->numberOfEdges() != 0) {
293  MinSTCutModule<TCost>::m_direction[origEdge(e)] = m_gc->copy(origEdge(e)) == e;
294  }
295  } else {
296  startAdj = e->adjTarget();
297  for (adjEntry adj = (m_primaryCut ? startAdj->cyclicSucc() : startAdj->cyclicPred());
298  adj != startAdj;
299  adj = (m_primaryCut ? adj->cyclicSucc() : adj->cyclicPred())) {
300  if (adj->theEdge()->adjTarget() != adj) {
301  stack.push(adj->theEdge());
302  }
303  }
304  }
305  }
306  }
307 };
308 
309 template<typename TCost>
310 bool MinSTCutMaxFlow<TCost>::call(const Graph& graph, const EdgeArray<TCost>& weight, node source,
311  node target, List<edge>& edgeList, edge e_st) {
312  MinSTCutModule<TCost>::m_direction.init(graph, -1);
313  delete m_gc;
314  m_gc = new GraphCopy(graph);
315 
316  if (e_st != nullptr) {
317  m_gc->delEdge(m_gc->copy(e_st));
318  }
319  node s = m_gc->copy(source);
320  node t = m_gc->copy(target);
321  List<edge> edges;
322  m_gc->allEdges(edges);
323  EdgeArray<edge> originalEdge(*m_gc, nullptr);
324  for (edge e : edges) {
325  if (m_treatAsUndirected) {
326  // a reversed edge is made and placed directly next to e
327  edge revEdge = m_gc->newEdge(e->target(), e->source());
328  m_gc->move(revEdge, e->adjTarget(), ogdf::Direction::before, e->adjSource(),
330  originalEdge[revEdge] = m_gc->original(e);
331  }
332  originalEdge[e] = m_gc->original(e);
333  }
334 
335  m_flow.init(*m_gc, -1);
336  m_weight.init(*m_gc, 1);
337  for (edge e : m_gc->edges) {
338  edge origEdge = originalEdge[e];
339  m_weight[e] = weight[origEdge];
340  OGDF_ASSERT(m_weight[e] >= 0);
341  }
342 
343  m_mfModule->init(*m_gc);
344  m_mfModule->computeFlow(m_weight, s, t, m_flow);
345 
346  computeCut(
347  graph, [&](edge e) -> edge { return originalEdge[e]; },
348  [&](node v) -> node { return m_gc->original(v); }, s, t, edgeList);
349 
350  return true;
351 }
352 
353 template<typename TCost>
354 void MinSTCutMaxFlow<TCost>::call(const Graph& graph, const EdgeArray<TCost>& weights,
355  const EdgeArray<TCost>& flow, const node source, const node target) {
356  delete m_gc;
357  m_gc = new GraphCopy();
358  m_flow = flow;
359  m_weight = weights;
360  List<edge> edgeList;
361  computeCut(
362  graph, [&](edge e) -> edge { return e; }, [&](node v) -> node { return v; }, source,
363  target, edgeList);
364 }
365 }
ogdf::ArrayBuffer
An array that keeps track of the number of inserted elements; also usable as an efficient stack.
Definition: Array.h:46
ogdf
The namespace for all OGDF objects.
Definition: AugmentationModule.h:36
ogdf::MinSTCutMaxFlow::setEpsilonTest
void setEpsilonTest(EpsilonTest *et)
Assigns a new epsilon test.
Definition: MinSTCutMaxFlow.h:117
ogdf::EpsilonTest
Definition: EpsilonTest.h:41
ogdf::MinSTCutMaxFlow::isFrontCutEdge
bool isFrontCutEdge(const edge e) const
Returns whether this edge is leaving the front cut.
Definition: MinSTCutMaxFlow.h:133
OGDF_ASSERT
#define OGDF_ASSERT(expr)
Assert condition expr. See doc/build.md for more information.
Definition: basic.h:54
ogdf::ArrayBuffer::empty
bool empty() const
Returns true if the buffer is empty, false otherwise.
Definition: ArrayBuffer.h:230
ogdf::MinSTCutMaxFlow::m_nodeSet
NodeArray< cutType > m_nodeSet
Definition: MinSTCutMaxFlow.h:197
ogdf::AdjElement::cyclicPred
adjEntry cyclicPred() const
Returns the cyclic predecessor in the adjacency list.
Definition: Graph_d.h:351
ogdf::List::popFrontRet
E popFrontRet()
Removes the first element from the list and returns it.
Definition: List.h:1581
ogdf::MinSTCutMaxFlow::frontCutIsComplementOfBackCut
bool frontCutIsComplementOfBackCut() const
Returns whether the front cut is the complement of the backcut.
Definition: MinSTCutMaxFlow.h:125
ogdf::MinSTCutMaxFlow::m_et
std::unique_ptr< EpsilonTest > m_et
Definition: MinSTCutMaxFlow.h:196
ogdf::MinSTCutMaxFlow::isBackCutEdge
bool isBackCutEdge(const edge e) const
Returns whether this edge is entering the back cut.
Definition: MinSTCutMaxFlow.h:142
ogdf::GraphCopy
Copies of graphs supporting edge splitting.
Definition: GraphCopy.h:384
ogdf::MinSTCutMaxFlow::m_flow
EdgeArray< TCost > m_flow
Definition: MinSTCutMaxFlow.h:198
ogdf::Direction::before
@ before
ogdf::MaxFlowGoldbergTarjan
Computes a max flow via Preflow-Push (global relabeling and gap relabeling heuristic).
Definition: MaxFlowGoldbergTarjan.h:53
ogdf::MinSTCutMaxFlow::MinSTCutMaxFlow
MinSTCutMaxFlow(bool treatAsUndirected=true, MaxFlowModule< TCost > *mfModule=new MaxFlowGoldbergTarjan< TCost >(), bool primaryCut=true, bool calculateOtherCut=true, EpsilonTest *epsilonTest=new EpsilonTest())
Constructor.
Definition: MinSTCutMaxFlow.h:68
ogdf::ArrayBuffer::popRet
E popRet()
Removes the newest element from the buffer and returns it.
Definition: ArrayBuffer.h:224
ogdf::MinSTCutMaxFlow::computeCut
void computeCut(const Graph &graph, std::function< edge(edge)> origEdge, std::function< node(node)> origNode, const node source, const node target, List< edge > &edgeList)
Partitions the nodes to front and back cut.
Definition: MinSTCutMaxFlow.h:245
ogdf::MinSTCutMaxFlow::m_calculateOtherCut
bool m_calculateOtherCut
iff true, the other (near to s for primaryCut == false, near to t for primaryCut == true) cut should ...
Definition: MinSTCutMaxFlow.h:193
ogdf::AdjElement
Class for adjacency list elements.
Definition: Graph_d.h:135
ogdf::edge
EdgeElement * edge
The type of edges.
Definition: Graph_d.h:67
ogdf::AdjElement::theEdge
edge theEdge() const
Returns the edge associated with this adjacency entry.
Definition: Graph_d.h:153
ogdf::MinSTCutMaxFlow::call
virtual bool call(const Graph &graph, const EdgeArray< TCost > &weight, node s, node t, List< edge > &edgeList, edge e_st=nullptr) override
The actual algorithm call.
Definition: MinSTCutMaxFlow.h:310
ogdf::Direction::after
@ after
ogdf::Graph::numberOfEdges
int numberOfEdges() const
Returns the number of edges in the graph.
Definition: Graph_d.h:977
MaxFlowGoldbergTarjan.h
Declaration and implementation of Goldberg-Tarjan max-flow algorithm with global relabeling and gap r...
ogdf::Graph::numberOfNodes
int numberOfNodes() const
Returns the number of nodes in the graph.
Definition: Graph_d.h:974
backward::Color::type
type
Definition: backward.hpp:1716
ogdf::NodeElement::adjEntries
internal::GraphObjectContainer< AdjElement > adjEntries
The container containing all entries in the adjacency list of this node.
Definition: Graph_d.h:264
ogdf::MinSTCutModule
Definition: MinSTCutModule.h:40
ogdf::MinSTCutMaxFlow::cutType::BACK_CUT
@ BACK_CUT
node is in back cut
ogdf::MinSTCutMaxFlow::m_primaryCut
bool m_primaryCut
true if the algorithm should search for the mincut nearest to s, false if it should be near to t.
Definition: MinSTCutMaxFlow.h:187
ogdf::ArrayBuffer::push
void push(E e)
Puts a new element in the buffer.
Definition: ArrayBuffer.h:209
ogdf::EdgeElement::source
node source() const
Returns the source node of the edge.
Definition: Graph_d.h:391
ogdf::node
NodeElement * node
The type of nodes.
Definition: Graph_d.h:63
ogdf::List< edge >
ogdf::internal::GraphRegisteredArray
RegisteredArray for nodes, edges and adjEntries of a graph.
Definition: Graph_d.h:651
ogdf::Graph
Data type for general directed graphs (adjacency list representation).
Definition: Graph_d.h:862
ogdf::MinSTCutMaxFlow::call
virtual bool call(const Graph &graph, node s, node t, List< edge > &edgeList, edge e_st=nullptr) override
The actual algorithm call.
Definition: MinSTCutMaxFlow.h:87
ogdf::AdjElement::twinNode
node twinNode() const
Returns the associated node of the corresponding adjacency entry (shorthand for twin()->theNode()).
Definition: Graph_d.h:168
ogdf::GraphCopy::copy
edge copy(edge e) const override
Returns the first edge in the list of edges corresponding to edge e.
Definition: GraphCopy.h:457
ogdf::AdjElement::cyclicSucc
adjEntry cyclicSucc() const
Returns the cyclic successor in the adjacency list.
Definition: Graph_d.h:347
ogdf::EdgeElement::adjTarget
adjEntry adjTarget() const
Returns the corresponding adjacancy entry at target node.
Definition: Graph_d.h:403
ogdf::MinSTCutMaxFlow::m_backCutCount
int m_backCutCount
Definition: MinSTCutMaxFlow.h:201
ogdf::MinSTCutMaxFlow::cutType::FRONT_CUT
@ FRONT_CUT
node is in front cut
ogdf::MinSTCutMaxFlow::cutType::NO_CUT
@ NO_CUT
node is not part of any cut
ogdf::MinSTCutModule::m_gc
GraphCopy * m_gc
Definition: MinSTCutModule.h:95
ogdf::MinSTCutMaxFlow::cutType
cutType
The three types of cuts.
Definition: MinSTCutMaxFlow.h:108
ogdf::MinSTCutMaxFlow::m_totalCount
int m_totalCount
Definition: MinSTCutMaxFlow.h:202
ogdf::MinSTCutMaxFlow::isOfType
bool isOfType(const node v, cutType type) const
Return whether this node is of the specified type.
Definition: MinSTCutMaxFlow.h:179
ogdf::MaxFlowModule
Definition: MaxFlowModule.h:40
ogdf::NodeElement::firstAdj
adjEntry firstAdj() const
Returns the first entry in the adjaceny list.
Definition: Graph_d.h:279
ogdf::MinSTCutMaxFlow::m_mfModule
std::unique_ptr< MaxFlowModule< TCost > > m_mfModule
the module used for calculating the maxflow
Definition: MinSTCutMaxFlow.h:183
ogdf::EdgeElement
Class for the representation of edges.
Definition: Graph_d.h:356
ogdf::MinSTCutMaxFlow::m_weight
EdgeArray< TCost > m_weight
Definition: MinSTCutMaxFlow.h:199
ogdf::MinSTCutMaxFlow::m_treatAsUndirected
bool m_treatAsUndirected
states whether or not edges are considered undirected while calculating the maxflow
Definition: MinSTCutMaxFlow.h:185
ogdf::MinSTCutMaxFlow::m_frontCutCount
int m_frontCutCount
Definition: MinSTCutMaxFlow.h:200
ogdf::RegisteredArray< GraphRegistry< EdgeElement >, 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::MinSTCutMaxFlow::markCut
void markCut(node startNode, bool frontCut, std::function< node(node)> origNode)
Mark the all nodes which are in the same cut partition as the startNode.
Definition: MinSTCutMaxFlow.h:211
ogdf::MinSTCutMaxFlow::isInBackCut
bool isInBackCut(const node v) const
Returns whether this node is part of the back cut.
Definition: MinSTCutMaxFlow.h:163
ogdf::EdgeElement::target
node target() const
Returns the target node of the edge.
Definition: Graph_d.h:394
MinSTCutModule.h
Template of base class of min-st-cut algorithms.
ogdf::NodeElement
Class for the representation of nodes.
Definition: Graph_d.h:233
ogdf::MinSTCutMaxFlow
Min-st-cut algorithm, that calculates the cut via maxflow.
Definition: MinSTCutMaxFlow.h:49
ogdf::List::pushBack
iterator pushBack(const E &x)
Adds element x at the end of the list.
Definition: List.h:1537
ogdf::internal::EdgeArrayBase2
RegisteredArray for edges of a graph, specialized for EdgeArray<edge>.
Definition: Graph_d.h:709
ogdf::MinSTCutMaxFlow::isInFrontCut
bool isInFrontCut(const node v) const
Returns whether this node is part of the front cut.
Definition: MinSTCutMaxFlow.h:152