Open
Graph Drawing
Framework

 v. 2023.09 (Elderberry)
 

Loading...
Searching...
No Matches
MinSteinerTreeMehlhorn.h
Go to the documentation of this file.
1
33#pragma once
34
35#include <ogdf/basic/Graph.h>
36#include <ogdf/basic/List.h>
37#include <ogdf/basic/basic.h>
42
43namespace ogdf {
44template<typename T>
45class EdgeWeightedGraph;
46
57template<typename T>
59public:
61
63
73 static void calculateCompleteGraph(const EdgeWeightedGraph<T>& wG, const List<node>& terminals,
74 const Voronoi<T>& voronoi, EdgeArray<edge>& bridges,
75 EdgeWeightedGraphCopy<T>& completeTerminalGraph);
76
77protected:
86 virtual T computeSteinerTree(const EdgeWeightedGraph<T>& G, const List<node>& terminals,
87 const NodeArray<bool>& isTerminal, EdgeWeightedGraphCopy<T>*& finalSteinerTree) override;
88
99 void reinsertShortestPaths(EdgeWeightedGraphCopy<T>& completeTerminalGraph,
100 const Voronoi<T>& voronoi, const NodeArray<edge>& mstPred, const EdgeArray<edge>& bridges,
101 EdgeWeightedGraphCopy<T>& finalSteinerTree, const EdgeWeightedGraph<T>& wG);
102
110 void insertPath(node u, const Voronoi<T>& voronoi, EdgeWeightedGraphCopy<T>& finalSteinerTree,
111 const EdgeWeightedGraph<T>& wG);
112
122
126 class MehlhornTripleBucketMaxFunc : public BucketFunc<MehlhornTriple> {
127 public:
129
130 int getBucket(const MehlhornTriple& MT) {
131 int source_index = MT.u->index();
132 int target_index = MT.v->index();
133 OGDF_ASSERT(source_index != target_index);
134 if (source_index < target_index) {
135 return target_index;
136 } else {
137 return source_index;
138 }
139 }
140 };
141
145 class MehlhornTripleBucketMinFunc : public BucketFunc<MehlhornTriple> {
146 public:
148
149 int getBucket(const MehlhornTriple& MT) {
150 int source_index = MT.u->index();
151 int target_index = MT.v->index();
152 OGDF_ASSERT(source_index != target_index);
153 if (source_index < target_index) {
154 return source_index;
155 } else {
156 return target_index;
157 }
158 }
159 };
160};
161
162template<typename T>
164 const List<node>& terminals, const NodeArray<bool>& isTerminal,
165 EdgeWeightedGraphCopy<T>*& finalSteinerTree) {
166 EdgeWeightedGraphCopy<T> completeTerminalGraph;
167 EdgeArray<edge> bridges;
168 Voronoi<T> voronoi(G, G.edgeWeights(), terminals);
169
170 calculateCompleteGraph(G, terminals, voronoi, bridges, completeTerminalGraph);
171
172 NodeArray<edge> mstPred(completeTerminalGraph);
173 computeMinST(completeTerminalGraph, completeTerminalGraph.edgeWeights(), mstPred);
174
175 finalSteinerTree = new EdgeWeightedGraphCopy<T>;
176 finalSteinerTree->setOriginalGraph(G);
177
178 reinsertShortestPaths(completeTerminalGraph, voronoi, mstPred, bridges, *finalSteinerTree, G);
179
180 T mstWeight = makeMinimumSpanningTree(*finalSteinerTree, finalSteinerTree->edgeWeights());
181 mstWeight -= MinSteinerTreeModule<T>::pruneAllDanglingSteinerPaths(*finalSteinerTree, isTerminal);
182
183 return mstWeight;
184}
185
186template<typename T>
188 const List<node>& terminals, const Voronoi<T>& voronoi, EdgeArray<edge>& bridges,
189 EdgeWeightedGraphCopy<T>& completeTerminalGraph) {
190 completeTerminalGraph.setOriginalGraph(wG);
191
192 for (node v : terminals) {
193 completeTerminalGraph.newNode(v);
194 }
195 if (completeTerminalGraph.numberOfNodes() <= 1) {
196 bridges.init(completeTerminalGraph);
197 return;
198 }
199
200 // extract complete graph edges
201 List<MehlhornTriple> triples;
202 for (edge e : wG.edges) {
203 MehlhornTriple triple;
204 triple.u = voronoi.seed(e->source());
205 triple.v = voronoi.seed(e->target());
206 if (triple.u != triple.v) {
207 triple.value =
208 voronoi.distance(e->source()) + voronoi.distance(e->target()) + wG.weight(e);
209 triple.bridge = e;
210 triples.pushBack(triple);
211 }
212 }
213
216
217 triples.bucketSort(0, wG.maxNodeIndex(), mtbMax);
218 triples.bucketSort(0, wG.maxNodeIndex(), mtbMin);
219
220 int currentSource = triples.front().u->index();
221 int currentTarget = triples.front().v->index();
222 ListConstIterator<MehlhornTriple> minTriple = triples.begin();
223
224 bridges.init(completeTerminalGraph);
225
226 for (ListConstIterator<MehlhornTriple> mtIt = triples.begin().succ(); mtIt.valid(); ++mtIt) {
227 if (((*mtIt).u->index() == currentSource && (*mtIt).v->index() == currentTarget)
228 || ((*mtIt).u->index() == currentTarget && (*mtIt).v->index() == currentSource)) {
229 if ((*mtIt).value < (*minTriple).value) {
230 minTriple = mtIt;
231 }
232 } else {
233 // add new direct edge
234 edge tmp = completeTerminalGraph.newEdge(completeTerminalGraph.copy((*minTriple).u),
235 completeTerminalGraph.copy((*minTriple).v), (*minTriple).value);
236 bridges[tmp] = (*minTriple).bridge;
237
238 currentSource = (*mtIt).u->index();
239 currentTarget = (*mtIt).v->index();
240 minTriple = mtIt;
241 }
242 }
243 // insert last triple
244 if (minTriple.valid()) {
245 edge tmp = completeTerminalGraph.newEdge(completeTerminalGraph.copy((*minTriple).u),
246 completeTerminalGraph.copy((*minTriple).v), (*minTriple).value);
247 bridges[tmp] = (*minTriple).bridge;
248 }
249}
250
251template<typename T>
253 const Voronoi<T>& voronoi, const NodeArray<edge>& mstPred, const EdgeArray<edge>& bridges,
254 EdgeWeightedGraphCopy<T>& finalSteinerTree, const EdgeWeightedGraph<T>& wG) {
255 for (node u : completeTerminalGraph.nodes) {
256 if (mstPred[u] != nullptr) {
257 edge bridge = bridges[mstPred[u]];
258 node v = bridge->source();
259 node w = bridge->target();
260 insertPath(v, voronoi, finalSteinerTree, wG);
261 insertPath(w, voronoi, finalSteinerTree, wG);
262 edge e = finalSteinerTree.newEdge(finalSteinerTree.copy(v), finalSteinerTree.copy(w),
263 wG.weight(bridge));
264 finalSteinerTree.setEdge(bridge, e);
265 }
266 }
267}
268
269template<typename T>
271 EdgeWeightedGraphCopy<T>& finalSteinerTree, const EdgeWeightedGraph<T>& wG) {
272 node currentSource;
273 node currentTarget = finalSteinerTree.copy(u);
274 if (!currentTarget) {
275 currentTarget = finalSteinerTree.newNode(u);
276 }
277 edge e = voronoi.predecessorEdge(u);
278 edge newE;
279 while (e && finalSteinerTree.chain(e).empty()) { // e is not in ST yet
280 if ((currentSource = finalSteinerTree.copy(
281 e->opposite(finalSteinerTree.original(currentTarget))))
282 == nullptr) {
283 currentSource =
284 finalSteinerTree.newNode(e->opposite(finalSteinerTree.original(currentTarget)));
285 }
286 if (finalSteinerTree.original(currentSource) == e->source()) {
287 newE = finalSteinerTree.newEdge(currentSource, currentTarget, wG.weight(e));
288 } else {
289 newE = finalSteinerTree.newEdge(currentTarget, currentSource, wG.weight(e));
290 }
291 finalSteinerTree.setEdge(e, newE);
292 currentTarget = currentSource;
293 e = voronoi.predecessorEdge(finalSteinerTree.original(currentTarget));
294 }
295}
296
297namespace steiner_tree {
298
299template<typename T>
301 const EdgeWeightedGraph<T>& graph, const List<node>& terminals) {
302 EdgeArray<edge> bridges;
303 Voronoi<T> voronoi(graph, graph.edgeWeights(), terminals);
304
305 MinSteinerTreeMehlhorn<T>::calculateCompleteGraph(graph, terminals, voronoi, bridges,
306 terminalSpanningTree);
307
308 return makeMinimumSpanningTree(terminalSpanningTree, terminalSpanningTree.edgeWeights());
309}
310}
311}
Extends the GraphCopy concept to weighted graphs.
Includes declaration of graph class.
Declaration of doubly linked lists and iterators.
Declaration of ogdf::MinSteinerTreeModule.
Definition of ogdf::Voronoi class template.
Basic declarations, included by all source files.
Abstract base class for bucket functions.
Definition basic.h:257
Class for the representation of edges.
Definition Graph_d.h:364
node opposite(node v) const
Returns the adjacent node different from v.
Definition Graph_d.h:414
node target() const
Returns the target node of the edge.
Definition Graph_d.h:402
node source() const
Returns the source node of the edge.
Definition Graph_d.h:399
edge newEdge(node u, node v, T weight)
void setOriginalGraph(const Graph *wG) override
Re-initializes the copy using G (which might be null), but does not create any nodes or edges.
const EdgeArray< T > & edgeWeights() const
T weight(const edge e) const
const EdgeArray< T > & edgeWeights() const
node newNode(node vOrig)
Creates a new node in the graph copy with original node vOrig.
Definition GraphCopy.h:191
const Graph & original() const
Returns a reference to the original graph.
Definition GraphCopy.h:104
const List< edge > & chain(edge e) const
Returns the list of edges coresponding to edge e.
Definition GraphCopy.h:453
edge copy(edge e) const override
Returns the first edge in the list of edges corresponding to edge e.
Definition GraphCopy.h:463
void setEdge(edge eOrig, edge eCopy)
sets eOrig to be the corresponding original edge of eCopy and vice versa
int maxNodeIndex() const
Returns the largest used node index.
Definition Graph_d.h:985
int numberOfNodes() const
Returns the number of nodes in the graph.
Definition Graph_d.h:979
internal::GraphObjectContainer< NodeElement > nodes
The container containing all node objects.
Definition Graph_d.h:929
internal::GraphObjectContainer< EdgeElement > edges
The container containing all edge objects.
Definition Graph_d.h:932
Doubly linked lists (maintaining the length of the list).
Definition List.h:1451
iterator pushBack(const E &x)
Adds element x at the end of the list.
Definition List.h:1547
Encapsulates a pointer to a list element.
Definition List.h:113
bool valid() const
Returns true iff the iterator points to an element.
Definition List.h:153
ListIteratorBase< E, isConst, isReverse > succ() const
Returns successor iterator.
Definition List.h:174
iterator begin()
Returns an iterator to the first element of the list.
Definition List.h:391
const_reference front() const
Returns a const reference to the first element.
Definition List.h:305
void bucketSort(int l, int h, BucketFunc< E > &f)
Sorts the list using bucket sort.
Definition List.h:1733
bool empty() const
Returns true iff the list is empty.
Definition List.h:286
Helper class to sort MehlhornTriples lexicographically.
Helper class to sort MehlhornTriples lexicographically.
This class implements the Minimum Steiner Tree 2-approximation algorithm by Mehlhorn.
void insertPath(node u, const Voronoi< T > &voronoi, EdgeWeightedGraphCopy< T > &finalSteinerTree, const EdgeWeightedGraph< T > &wG)
Inserts a shortest path corresponding to an edge in the complete terminal graph.
void reinsertShortestPaths(EdgeWeightedGraphCopy< T > &completeTerminalGraph, const Voronoi< T > &voronoi, const NodeArray< edge > &mstPred, const EdgeArray< edge > &bridges, EdgeWeightedGraphCopy< T > &finalSteinerTree, const EdgeWeightedGraph< T > &wG)
Swaps an edge in the complete terminal graph with the corresponding shortest path in the original gra...
static void calculateCompleteGraph(const EdgeWeightedGraph< T > &wG, const List< node > &terminals, const Voronoi< T > &voronoi, EdgeArray< edge > &bridges, EdgeWeightedGraphCopy< T > &completeTerminalGraph)
Builds a complete terminal graph.
virtual T computeSteinerTree(const EdgeWeightedGraph< T > &G, const List< node > &terminals, const NodeArray< bool > &isTerminal, EdgeWeightedGraphCopy< T > *&finalSteinerTree) override
Builds a minimum Steiner tree given a weighted graph and a list of terminals.
Serves as an interface for various methods to compute or approximate minimum Steiner trees on undirec...
static T pruneAllDanglingSteinerPaths(EdgeWeightedGraphCopy< T > &steinerTree, const NodeArray< bool > &isTerminal)
Prunes nonterminal leaves and their paths to terminal or branching nodes.
Class for the representation of nodes.
Definition Graph_d.h:241
int index() const
Returns the (unique) node index.
Definition Graph_d.h:275
void init(const Base *base=nullptr)
Reinitializes the array. Associates the array with the matching registry of base.
Computes Voronoi regions in an edge-weighted graph.
Definition Voronoi.h:49
T distance(node v) const
Returns the distance between v and its Voronoi seed.
Definition Voronoi.h:87
node seed(node v) const
Returns the Voronoi seed of node v.
Definition Voronoi.h:90
edge predecessorEdge(node v) const
Returns the edge incident to v and its predecessor. Note that the predecessor of a terminal is nullpt...
Definition Voronoi.h:78
RegisteredArray for edges of a graph, specialized for EdgeArray<edge>.
Definition Graph_d.h:717
RegisteredArray for nodes, edges and adjEntries of a graph.
Definition Graph_d.h:659
Declaration of extended graph algorithms.
T makeMinimumSpanningTree(Graph &G, const EdgeArray< T > &weight)
Reduce a graph to its minimum spanning tree (MST) using Kruskal's algorithm.
T computeMinST(const Graph &G, const EdgeArray< T > &weight, EdgeArray< bool > &isInTree)
Computes a minimum spanning tree using Prim's algorithm.
#define OGDF_ASSERT(expr)
Assert condition expr. See doc/build.md for more information.
Definition basic.h:52
T constructTerminalSpanningTreeUsingVoronoiRegions(EdgeWeightedGraphCopy< T > &terminalSpanningTree, const EdgeWeightedGraph< T > &graph, const List< node > &terminals)
The namespace for all OGDF objects.
Represents a triple as specified in the algorithms description (see paper)