Loading [MathJax]/extensions/tex2jax.js

Open
Graph Drawing
Framework

 v. 2023.09 (Elderberry)
 

All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Modules Pages
Loading...
Searching...
No Matches
MinimumCutStoerWagner.h
Go to the documentation of this file.
1
32#pragma once
33
35#include <ogdf/basic/Math.h>
38
39namespace ogdf {
40
49template<typename T = double>
52 virtual T call(const Graph& G) override {
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);
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
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
108protected:
111
114
117
120
123
128
130 void mainLoop() {
131 m_partition.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
151template<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
192template<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
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}
Declaration of graph copy classes.
Declaration of ogdf::MinimumCutModule.
Priority queue interface wrapping various heaps.
Mathematical Helpers.
Class for adjacency list elements.
Definition Graph_d.h:79
An array that keeps track of the number of inserted elements; also usable as an efficient stack.
Definition ArrayBuffer.h:56
void clear()
Clears the buffer.
Definition ArrayBuffer.h:95
void push(E e)
Puts a new element in the buffer.
bool empty() const
Returns true if the buffer is empty, false otherwise.
Dynamic arrays indexed with edges.
Definition EdgeArray.h:125
Class for the representation of edges.
Definition Graph_d.h:300
Copies of graphs supporting edge splitting.
Definition GraphCopy.h:254
void init(const Graph &G)
Re-initializes the copy using the graph G.
const Graph & original() const
Returns a reference to the original graph.
Definition GraphCopy.h:289
Data type for general directed graphs (adjacency list representation).
Definition Graph_d.h:521
int numberOfNodes() const
Returns the number of nodes in the graph.
Definition Graph_d.h:622
internal::GraphObjectContainer< NodeElement > nodes
The container containing all node objects.
Definition Graph_d.h:589
internal::GraphObjectContainer< EdgeElement > edges
The container containing all edge objects.
Definition Graph_d.h:592
Serves as an interface for various methods to compute minimum cuts with or without edge weights.
Dynamic arrays indexed with nodes.
Definition NodeArray.h:125
Class for the representation of nodes.
Definition Graph_d.h:177
internal::GraphObjectContainer< AdjElement > adjEntries
The container containing all entries in the adjacency list of this node.
Definition Graph_d.h:208
Prioritized queue interface wrapper for heaps.
AdjElement * adjEntry
The type of adjacency entries.
Definition Graph_d.h:72
EdgeElement * edge
The type of edges.
Definition Graph_d.h:68
#define OGDF_ASSERT(expr)
Assert condition expr. See doc/build.md for more information.
Definition basic.h:41
static MultilevelBuilder * getDoubleFactoredZeroAdjustedMerger()
void updateMin(T &min, const T &newValue)
Stores the minimum of min and newValue in min.
Definition Math.h:98
The namespace for all OGDF objects.
void safeForEach(CONTAINER &container, std::function< void(typename CONTAINER::value_type)> func)
Calls (possibly destructive) func for each element of container.
Computes a minimum cut in a graph.
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...
ArrayBuffer< node > m_partition
Store one side of the computed bipartition.
virtual T call(const Graph &G, const EdgeArray< T > &weights) override
Computes a minimum cut on graph G with non-negative weights on edges.
GraphCopy m_GC
The modifiable version of the input graph (used for contractions)
EdgeArray< T > m_w
An EdgeArray containing the corresponding edge weights.
ArrayBuffer< edge > m_cutEdges
Store cut edges if computed.
NodeArray< List< node > > m_contractedNodes
Each node has a list containing the nodes with which it has been contracted. Because the GraphCopy m_...
void mainLoop()
Computes minimum cut by invoking minimumCutPhase() O(|V|) times.
virtual const ArrayBuffer< node > & nodes() override
Returns a const-reference to the list of nodes belonging to one side of the bipartition.
T m_minCut
Stores the value of the minimum cut.
T minimumCutPhase()
Computes and returns the value of the minimum cut of the current phase (iteration).
virtual const ArrayBuffer< edge > & edges() override
Computes the edges defining the computed mincut and returns them.
virtual T value() const override
Returns the value of the last minimum cut computation.
virtual T call(const Graph &G) override
Computes a minimum cut on graph G.