Open
Graph Drawing
Framework

 v. 2023.09 (Elderberry)
 

MinimumCutStoerWagner.h
Go to the documentation of this file.
1 
32 #pragma once
33 
34 #include <ogdf/basic/ArrayBuffer.h>
35 #include <ogdf/basic/Graph.h>
36 #include <ogdf/basic/GraphCopy.h>
37 #include <ogdf/basic/GraphList.h>
38 #include <ogdf/basic/List.h>
39 #include <ogdf/basic/Math.h>
41 #include <ogdf/basic/basic.h>
43 
44 #include <functional>
45 #include <limits>
46 #include <utility>
47 
48 namespace ogdf {
49 
58 template<typename T = double>
61  virtual T call(const Graph& G) override {
62  EdgeArray<T> weights(G, 1);
63  return call(G, weights);
64  }
65 
67  virtual T call(const Graph& G, const EdgeArray<T>& weights) override {
68  m_minCut = std::numeric_limits<T>::max();
69  m_GC.init(G);
70  m_w.init(m_GC);
71  m_contractedNodes.init(m_GC);
72 
73  for (edge e : m_GC.edges) {
74  m_w[e] = weights[m_GC.original(e)];
75  OGDF_ASSERT(m_w[e] >= T {});
76  }
77  for (node v : m_GC.nodes) {
78  m_contractedNodes[v].pushBack(m_GC.original(v));
79  }
80 
81  mainLoop();
82 
83  return value();
84  }
85 
91  virtual const ArrayBuffer<edge>& edges() override {
92  if (!m_cutEdges.empty()) {
93  return m_cutEdges;
94  }
95 
96  NodeArray<bool> inPartition(m_GC.original(), false);
97 
98  for (node v : m_partition) {
99  inPartition[v] = true;
100  }
101 
102  for (node v : m_partition) {
103  for (adjEntry adj : v->adjEntries) {
104  if (!inPartition[adj->twinNode()]) {
105  m_cutEdges.push(adj->theEdge());
106  }
107  }
108  }
109  return m_cutEdges;
110  }
111 
113  virtual const ArrayBuffer<node>& nodes() override { return m_partition; }
114 
115  virtual T value() const override { return m_minCut; }
116 
117 protected:
120 
123 
126 
129 
132 
137 
139  void mainLoop() {
140  m_partition.clear();
141  m_cutEdges.clear();
142  while (m_GC.numberOfNodes() > 1) {
144  if (m_minCut == T {}) { // cannot get better so return early
145  return;
146  }
147  }
148  }
149 
151  T minimumCutPhase();
152 
157  void contraction(node t, node s);
158 };
159 
160 template<typename T>
162  OGDF_ASSERT(t != s);
163 
164  // Since nodes in #m_GC correspond to sets of nodes (due to the node contraction),
165  // the NodeArray #m_contractedNodes has to be updated.
166  // Hence append the list of contracted nodes of s to the list of t.
167  m_contractedNodes[t].conc(m_contractedNodes(s));
168 
169  // Redirect edges and delete node s
170  safeForEach(s->adjEntries, [&](adjEntry adj) {
171  edge e = adj->theEdge();
172  if (e->source() == t || e->target() == t) {
173  m_GC.delEdge(e);
174  } else if (e->source() == s) {
175  m_GC.moveSource(e, t);
176  } else {
177  m_GC.moveTarget(e, t);
178  }
179  });
180  m_GC.delNode(s);
181 
182  // NodeArray containing the first edge of parallel edges
183  NodeArray<edge> incident {m_GC, nullptr};
184 
185  // Delete parallel edges and add their weights
186  safeForEach(t->adjEntries, [&](adjEntry adj) {
187  node v {adj->twinNode()};
188  if (v != t) {
189  edge e {adj->theEdge()};
190  edge& f {incident[v]};
191  if (f == nullptr) {
192  f = e;
193  } else {
194  m_w[f] += m_w[e];
195  m_GC.delEdge(e);
196  }
197  }
198  });
199 }
200 
201 template<typename T>
203  /*
204  * This function computes the mincut of the current phase.
205  * First, nodes are explored successively in descending order of the sum of
206  * their incident edge weights; \a s and \a t are always the two last added nodes.
207  * Afterwards, the current mincut value \a cutOfThePhase is computed, which corresponds to the
208  * sum of the weights of those edges incident to node \a t.
209  * At the end, \a s and \a t are contracted and the \a cutOfThePhase is returned.
210  */
211 
212  // A priority queue containing the unexplored nodes.
213  // Priorities are the (negative) sum of edge weights incident to the explored nodes.
215  for (node v : m_GC.nodes) {
216  pq.push(v, T {});
217  }
218  std::function<void(node)> updatePQ {[&](node currentNode) {
219  OGDF_ASSERT(!pq.contains(currentNode));
220  for (adjEntry adj : currentNode->adjEntries) {
221  node v {adj->twinNode()};
222  // The code below is at it is due to numerical issues with T=double.
223  if (pq.contains(v)) {
224  T newPriority {pq.priority(v) - m_w[adj->theEdge()]};
225  if (newPriority < pq.priority(v)) {
226  pq.decrease(adj->twinNode(), newPriority);
227  }
228  }
229  }
230  }};
231 
232  // The start node can be chosen arbitrarily. It has no effect on the correctness of the algorithm.
233  node s {nullptr};
234  node t {pq.topElement()};
235  pq.pop();
236 
237  updatePQ(t);
238 
239  // Successively adding the most tightly connected node.
240  while (!pq.empty()) {
241  // Find the most tightly connected node and remove it from the priority queue
242  node currentNode {pq.topElement()};
243  pq.pop();
244 
245  // Push the current node to the 2-element list consisting of s and t
246  s = currentNode;
247  std::swap(s, t);
248 
249  // Update the priorities
250  updatePQ(currentNode);
251  }
252 
253  // Contains the mincut value according to the current phase.
254  T phaseCut {};
255  for (adjEntry adj : t->adjEntries) {
256  edge e {adj->theEdge()};
257  if (!e->isSelfLoop()) {
258  phaseCut += m_w[adj->theEdge()];
259  }
260  }
261 
262  // If the current \a phaseCut is strictly smaller than the global mincut value,
263  // the partition defining the mincut has to be updated.
264  if (phaseCut < m_minCut) {
265  m_partition.clear();
266  for (node v : m_contractedNodes[t]) {
267  m_partition.push(v);
268  }
269  }
270 
271  // Performing the node contraction of nodes \a s and \a t.
272  contraction(t, s);
273 
274  return phaseCut;
275 }
276 
277 }
ogdf::ArrayBuffer< edge >
ogdf
The namespace for all OGDF objects.
Definition: multilevelmixer.cpp:39
ArrayBuffer.h
Declaration and implementation of ArrayBuffer class.
Graph.h
Includes declaration of graph class.
ogdf::MinimumCutStoerWagner::value
virtual T value() const override
Definition: MinimumCutStoerWagner.h:115
OGDF_ASSERT
#define OGDF_ASSERT(expr)
Assert condition expr. See doc/build.md for more information.
Definition: basic.h:66
ogdf::pq_internal::PrioritizedArrayQueueBase< E, P, std::less< P >, PairingHeap, HashArray< E, PrioritizedQueue< E, P, std::less< P >, PairingHeap >::Handle, DefHashFunc< E > > >::pop
void pop()
Removes the topmost element from the queue.
Definition: PriorityQueue.h:341
ogdf::ArrayBuffer::empty
bool empty() const
Returns true if the buffer is empty, false otherwise.
Definition: ArrayBuffer.h:238
ogdf::MinimumCutStoerWagner::minimumCutPhase
T minimumCutPhase()
Computes and returns the value of the minimum cut of the current phase (iteration).
Definition: MinimumCutStoerWagner.h:202
PriorityQueue.h
Priority queue interface wrapping various heaps.
ogdf::pq_internal::PrioritizedArrayQueueBase< E, P, std::less< P >, PairingHeap, HashArray< E, PrioritizedQueue< E, P, std::less< P >, PairingHeap >::Handle, DefHashFunc< E > > >::push
void push(const E &element, const P &priority)
Adds a new element to the queue.
Definition: PriorityQueue.h:333
ogdf::MinimumCutStoerWagner::m_w
EdgeArray< T > m_w
An EdgeArray containing the corresponding edge weights.
Definition: MinimumCutStoerWagner.h:125
ogdf::MinimumCutModule
Serves as an interface for various methods to compute minimum cuts with or without edge weights.
Definition: MinimumCutModule.h:47
ogdf::MinimumCutStoerWagner::m_GC
GraphCopy m_GC
The modifiable version of the input graph (used for contractions)
Definition: MinimumCutStoerWagner.h:122
ogdf::MinimumCutStoerWagner::call
virtual T call(const Graph &G) override
Computes a minimum cut on graph G.
Definition: MinimumCutStoerWagner.h:61
ogdf::GraphCopy
Copies of graphs supporting edge splitting.
Definition: GraphCopy.h:391
ogdf::pq_internal::PrioritizedArrayQueueBase< E, P, std::less< P >, PairingHeap, HashArray< E, PrioritizedQueue< E, P, std::less< P >, PairingHeap >::Handle, DefHashFunc< E > > >::priority
const P & priority(const E &element) const
Definition: PriorityQueue.h:324
ogdf::MinimumCutStoerWagner::mainLoop
void mainLoop()
Computes minimum cut by invoking minimumCutPhase() O(|V|) times.
Definition: MinimumCutStoerWagner.h:139
ogdf::MinimumCutStoerWagner::call
virtual T call(const Graph &G, const EdgeArray< T > &weights) override
Computes a minimum cut on graph G with non-negative weights on edges.
Definition: MinimumCutStoerWagner.h:67
ogdf::safeForEach
void safeForEach(CONTAINER &container, std::function< void(typename CONTAINER::value_type)> func)
Calls (possibly destructive) func for each element of container.
Definition: list_templates.h:51
ogdf::MinimumCutStoerWagner::m_contractedNodes
NodeArray< List< node > > m_contractedNodes
Each node has a list containing the nodes with which it has been contracted. Because the GraphCopy m_...
Definition: MinimumCutStoerWagner.h:136
ogdf::adjEntry
AdjElement * adjEntry
The type of adjacency entries.
Definition: Graph_d.h:78
ogdf::pq_internal::PrioritizedArrayQueueBase< E, P, std::less< P >, PairingHeap, HashArray< E, PrioritizedQueue< E, P, std::less< P >, PairingHeap >::Handle, DefHashFunc< E > > >::contains
bool contains(const E &element) const
Returns whether this queue contains that key.
Definition: PriorityQueue.h:318
ogdf::AdjElement
Class for adjacency list elements.
Definition: Graph_d.h:142
ogdf::edge
EdgeElement * edge
The type of edges.
Definition: Graph_d.h:74
ogdf::GraphCopyBase::init
void init(const Graph &G)
Re-initializes the copy using G, creating copies for all nodes and edges in G.
Definition: GraphCopy.h:73
ogdf::AdjElement::theEdge
edge theEdge() const
Returns the edge associated with this adjacency entry.
Definition: Graph_d.h:160
ogdf::PriorityQueue::empty
bool empty() const
Checks whether the queue is empty.
Definition: PriorityQueue.h:211
ogdf::Graph::nodes
internal::GraphObjectContainer< NodeElement > nodes
The container containing all node objects.
Definition: Graph_d.h:932
ogdf::Graph::numberOfNodes
int numberOfNodes() const
Returns the number of nodes in the graph.
Definition: Graph_d.h:982
GraphList.h
Decralation of GraphElement and GraphList classes.
ogdf::PrioritizedMapQueue
Prioritized queue interface wrapper for heaps.
Definition: PriorityQueue.h:411
ogdf::MinimumCutStoerWagner::nodes
virtual const ArrayBuffer< node > & nodes() override
Returns a const-reference to the list of nodes belonging to one side of the bipartition.
Definition: MinimumCutStoerWagner.h:113
ogdf::NodeElement::adjEntries
internal::GraphObjectContainer< AdjElement > adjEntries
The container containing all entries in the adjacency list of this node.
Definition: Graph_d.h:271
ogdf::ArrayBuffer::push
void push(E e)
Puts a new element in the buffer.
Definition: ArrayBuffer.h:217
ogdf::Math::updateMin
void updateMin(T &min, const T &newValue)
Stores the minimum of min and newValue in min.
Definition: Math.h:102
GraphCopy.h
Declaration of graph copy classes.
MinimumCutModule.h
Declaration of ogdf::MinimumCutModule.
ogdf::internal::GraphRegisteredArray
RegisteredArray for nodes, edges and adjEntries of a graph.
Definition: Graph_d.h:658
ogdf::Graph
Data type for general directed graphs (adjacency list representation).
Definition: Graph_d.h:869
Math.h
Mathematical Helpers.
ogdf::pq_internal::PrioritizedQueue< E, P, std::less< P >, PairingHeap >::topElement
const E & topElement() const
Returns the topmost element in the queue.
Definition: PriorityQueue.h:286
ogdf::AdjElement::twinNode
node twinNode() const
Returns the associated node of the corresponding adjacency entry (shorthand for twin()->theNode()).
Definition: Graph_d.h:175
ogdf::Graph::edges
internal::GraphObjectContainer< EdgeElement > edges
The container containing all edge objects.
Definition: Graph_d.h:935
ogdf::pq_internal::PrioritizedArrayQueueBase< E, P, std::less< P >, PairingHeap, HashArray< E, PrioritizedQueue< E, P, std::less< P >, PairingHeap >::Handle, DefHashFunc< E > > >::decrease
void decrease(const E &element, const P &priority)
Decreases the priority of the given element.
Definition: PriorityQueue.h:351
ogdf::MinimumCutStoerWagner::m_minCut
T m_minCut
Stores the value of the minimum cut.
Definition: MinimumCutStoerWagner.h:119
basic.h
Basic declarations, included by all source files.
ogdf::MinimumCutStoerWagner::m_partition
ArrayBuffer< node > m_partition
Store one side of the computed bipartition.
Definition: MinimumCutStoerWagner.h:128
ogdf::EdgeElement
Class for the representation of edges.
Definition: Graph_d.h:363
List.h
Declaration of doubly linked lists and iterators.
ogdf::MinimumCutStoerWagner::m_cutEdges
ArrayBuffer< edge > m_cutEdges
Store cut edges if computed.
Definition: MinimumCutStoerWagner.h:131
ogdf::MinimumCutStoerWagner::contraction
void contraction(node t, node s)
Contracts the nodes s and t, i.e., s is collapsed to t. The edge (if existing) between s and t is del...
Definition: MinimumCutStoerWagner.h:161
ogdf::MinimumCutStoerWagner
Computes a minimum cut in a graph.
Definition: MinimumCutStoerWagner.h:59
ogdf::ArrayBuffer::clear
void clear()
Clears the buffer.
Definition: ArrayBuffer.h:103
ogdf::MinimumCutStoerWagner::edges
virtual const ArrayBuffer< edge > & edges() override
Computes the edges defining the computed mincut and returns them.
Definition: MinimumCutStoerWagner.h:91
ogdf::NodeElement
Class for the representation of nodes.
Definition: Graph_d.h:240
ogdf::GraphCopyBase::original
const Graph & original() const
Returns a reference to the original graph.
Definition: GraphCopy.h:105
ogdf::internal::EdgeArrayBase2
RegisteredArray for edges of a graph, specialized for EdgeArray<edge>.
Definition: Graph_d.h:716