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/GraphCopy.h>
35 #include <ogdf/basic/Math.h>
38 
39 namespace ogdf {
40 
49 template<typename T = double>
52  virtual T call(const Graph& G) override {
53  EdgeArray<T> weights(G, 1);
54  return call(G, weights);
55  }
56 
58  virtual T call(const Graph& G, const EdgeArray<T>& weights) override {
59  m_minCut = std::numeric_limits<T>::max();
60  m_GC.init(G);
61  m_w.init(m_GC);
62  m_contractedNodes.init(m_GC);
63 
64  for (edge e : m_GC.edges) {
65  m_w[e] = weights[m_GC.original(e)];
66  OGDF_ASSERT(m_w[e] >= T {});
67  }
68  for (node v : m_GC.nodes) {
69  m_contractedNodes[v].pushBack(m_GC.original(v));
70  }
71 
72  mainLoop();
73 
74  return value();
75  }
76 
82  virtual const ArrayBuffer<edge>& edges() override {
83  if (!m_cutEdges.empty()) {
84  return m_cutEdges;
85  }
86 
87  NodeArray<bool> inPartition(m_GC.original(), false);
88 
89  for (node v : m_partition) {
90  inPartition[v] = true;
91  }
92 
93  for (node v : m_partition) {
94  for (adjEntry adj : v->adjEntries) {
95  if (!inPartition[adj->twinNode()]) {
96  m_cutEdges.push(adj->theEdge());
97  }
98  }
99  }
100  return m_cutEdges;
101  }
102 
104  virtual const ArrayBuffer<node>& nodes() override { return m_partition; }
105 
106  virtual T value() const override { return m_minCut; }
107 
108 protected:
111 
114 
117 
120 
123 
128 
130  void mainLoop() {
131  m_partition.clear();
132  m_cutEdges.clear();
133  while (m_GC.numberOfNodes() > 1) {
135  if (m_minCut == T {}) { // cannot get better so return early
136  return;
137  }
138  }
139  }
140 
142  T minimumCutPhase();
143 
148  void contraction(node t, node s);
149 };
150 
151 template<typename T>
153  OGDF_ASSERT(t != s);
154 
155  // Since nodes in #m_GC correspond to sets of nodes (due to the node contraction),
156  // the NodeArray #m_contractedNodes has to be updated.
157  // Hence append the list of contracted nodes of s to the list of t.
158  m_contractedNodes[t].conc(m_contractedNodes(s));
159 
160  // Redirect edges and delete node s
161  safeForEach(s->adjEntries, [&](adjEntry adj) {
162  edge e = adj->theEdge();
163  if (e->source() == t || e->target() == t) {
164  m_GC.delEdge(e);
165  } else if (e->source() == s) {
166  m_GC.moveSource(e, t);
167  } else {
168  m_GC.moveTarget(e, t);
169  }
170  });
171  m_GC.delNode(s);
172 
173  // NodeArray containing the first edge of parallel edges
174  NodeArray<edge> incident {m_GC, nullptr};
175 
176  // Delete parallel edges and add their weights
177  safeForEach(t->adjEntries, [&](adjEntry adj) {
178  node v {adj->twinNode()};
179  if (v != t) {
180  edge e {adj->theEdge()};
181  edge& f {incident[v]};
182  if (f == nullptr) {
183  f = e;
184  } else {
185  m_w[f] += m_w[e];
186  m_GC.delEdge(e);
187  }
188  }
189  });
190 }
191 
192 template<typename T>
194  /*
195  * This function computes the mincut of the current phase.
196  * First, nodes are explored successively in descending order of the sum of
197  * their incident edge weights; \a s and \a t are always the two last added nodes.
198  * Afterwards, the current mincut value \a cutOfThePhase is computed, which corresponds to the
199  * sum of the weights of those edges incident to node \a t.
200  * At the end, \a s and \a t are contracted and the \a cutOfThePhase is returned.
201  */
202 
203  // A priority queue containing the unexplored nodes.
204  // Priorities are the (negative) sum of edge weights incident to the explored nodes.
206  for (node v : m_GC.nodes) {
207  pq.push(v, T {});
208  }
209  std::function<void(node)> updatePQ {[&](node currentNode) {
210  OGDF_ASSERT(!pq.contains(currentNode));
211  for (adjEntry adj : currentNode->adjEntries) {
212  node v {adj->twinNode()};
213  // The code below is at it is due to numerical issues with T=double.
214  if (pq.contains(v)) {
215  T newPriority {pq.priority(v) - m_w[adj->theEdge()]};
216  if (newPriority < pq.priority(v)) {
217  pq.decrease(adj->twinNode(), newPriority);
218  }
219  }
220  }
221  }};
222 
223  // The start node can be chosen arbitrarily. It has no effect on the correctness of the algorithm.
224  node s {nullptr};
225  node t {pq.topElement()};
226  pq.pop();
227 
228  updatePQ(t);
229 
230  // Successively adding the most tightly connected node.
231  while (!pq.empty()) {
232  // Find the most tightly connected node and remove it from the priority queue
233  node currentNode {pq.topElement()};
234  pq.pop();
235 
236  // Push the current node to the 2-element list consisting of s and t
237  s = currentNode;
238  std::swap(s, t);
239 
240  // Update the priorities
241  updatePQ(currentNode);
242  }
243 
244  // Contains the mincut value according to the current phase.
245  T phaseCut {};
246  for (adjEntry adj : t->adjEntries) {
247  edge e {adj->theEdge()};
248  if (!e->isSelfLoop()) {
249  phaseCut += m_w[adj->theEdge()];
250  }
251  }
252 
253  // If the current \a phaseCut is strictly smaller than the global mincut value,
254  // the partition defining the mincut has to be updated.
255  if (phaseCut < m_minCut) {
256  m_partition.clear();
257  for (node v : m_contractedNodes[t]) {
258  m_partition.push(v);
259  }
260  }
261 
262  // Performing the node contraction of nodes \a s and \a t.
263  contraction(t, s);
264 
265  return phaseCut;
266 }
267 
268 }
ogdf::ArrayBuffer< edge >
ogdf
The namespace for all OGDF objects.
Definition: AugmentationModule.h:36
ogdf::MinimumCutStoerWagner::value
virtual T value() const override
Definition: MinimumCutStoerWagner.h:106
OGDF_ASSERT
#define OGDF_ASSERT(expr)
Assert condition expr. See doc/build.md for more information.
Definition: basic.h:54
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:339
ogdf::ArrayBuffer::empty
bool empty() const
Returns true if the buffer is empty, false otherwise.
Definition: ArrayBuffer.h:230
ogdf::MinimumCutStoerWagner::minimumCutPhase
T minimumCutPhase()
Computes and returns the value of the minimum cut of the current phase (iteration).
Definition: MinimumCutStoerWagner.h:193
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:331
ogdf::MinimumCutStoerWagner::m_w
EdgeArray< T > m_w
An EdgeArray containing the corresponding edge weights.
Definition: MinimumCutStoerWagner.h:116
ogdf::MinimumCutModule
Serves as an interface for various methods to compute minimum cuts with or without edge weights.
Definition: MinimumCutModule.h:45
ogdf::MinimumCutStoerWagner::m_GC
GraphCopy m_GC
The modifiable version of the input graph (used for contractions)
Definition: MinimumCutStoerWagner.h:113
ogdf::MinimumCutStoerWagner::call
virtual T call(const Graph &G) override
Computes a minimum cut on graph G.
Definition: MinimumCutStoerWagner.h:52
ogdf::GraphCopy
Copies of graphs supporting edge splitting.
Definition: GraphCopy.h:384
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:322
ogdf::MinimumCutStoerWagner::mainLoop
void mainLoop()
Computes minimum cut by invoking minimumCutPhase() O(|V|) times.
Definition: MinimumCutStoerWagner.h:130
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:58
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:49
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:127
ogdf::adjEntry
AdjElement * adjEntry
The type of adjacency entries.
Definition: Graph_d.h:71
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:316
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::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:66
ogdf::AdjElement::theEdge
edge theEdge() const
Returns the edge associated with this adjacency entry.
Definition: Graph_d.h:153
ogdf::PriorityQueue::empty
bool empty() const
Checks whether the queue is empty.
Definition: PriorityQueue.h:209
ogdf::Graph::nodes
internal::GraphObjectContainer< NodeElement > nodes
The container containing all node objects.
Definition: Graph_d.h:924
ogdf::Graph::numberOfNodes
int numberOfNodes() const
Returns the number of nodes in the graph.
Definition: Graph_d.h:974
ogdf::PrioritizedMapQueue
Prioritized queue interface wrapper for heaps.
Definition: PriorityQueue.h:409
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:104
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::ArrayBuffer::push
void push(E e)
Puts a new element in the buffer.
Definition: ArrayBuffer.h:209
ogdf::Math::updateMin
void updateMin(T &min, const T &newValue)
Stores the minimum of min and newValue in min.
Definition: Math.h:98
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:651
ogdf::Graph
Data type for general directed graphs (adjacency list representation).
Definition: Graph_d.h:862
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:284
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::Graph::edges
internal::GraphObjectContainer< EdgeElement > edges
The container containing all edge objects.
Definition: Graph_d.h:927
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:349
ogdf::MinimumCutStoerWagner::m_minCut
T m_minCut
Stores the value of the minimum cut.
Definition: MinimumCutStoerWagner.h:110
ogdf::MinimumCutStoerWagner::m_partition
ArrayBuffer< node > m_partition
Store one side of the computed bipartition.
Definition: MinimumCutStoerWagner.h:119
ogdf::EdgeElement
Class for the representation of edges.
Definition: Graph_d.h:356
ogdf::MinimumCutStoerWagner::m_cutEdges
ArrayBuffer< edge > m_cutEdges
Store cut edges if computed.
Definition: MinimumCutStoerWagner.h:122
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:152
ogdf::MinimumCutStoerWagner
Computes a minimum cut in a graph.
Definition: MinimumCutStoerWagner.h:50
ogdf::ArrayBuffer::clear
void clear()
Clears the buffer.
Definition: ArrayBuffer.h:95
ogdf::MinimumCutStoerWagner::edges
virtual const ArrayBuffer< edge > & edges() override
Computes the edges defining the computed mincut and returns them.
Definition: MinimumCutStoerWagner.h:82
ogdf::NodeElement
Class for the representation of nodes.
Definition: Graph_d.h:233
ogdf::GraphCopyBase::original
const Graph & original() const
Returns a reference to the original graph.
Definition: GraphCopy.h:98
ogdf::internal::EdgeArrayBase2
RegisteredArray for edges of a graph, specialized for EdgeArray<edge>.
Definition: Graph_d.h:709