Open
Graph Drawing
Framework

 v. 2023.09 (Elderberry)
 

MinSteinerTreeMehlhorn.h
Go to the documentation of this file.
1 
33 #pragma once
34 
35 #include <ogdf/basic/List.h>
37 #include <ogdf/graphalg/Voronoi.h>
39 
40 namespace ogdf {
41 
52 template<typename T>
54 public:
56 
58 
68  static void calculateCompleteGraph(const EdgeWeightedGraph<T>& wG, const List<node>& terminals,
69  const Voronoi<T>& voronoi, EdgeArray<edge>& bridges,
70  EdgeWeightedGraphCopy<T>& completeTerminalGraph);
71 
72 protected:
81  virtual T computeSteinerTree(const EdgeWeightedGraph<T>& G, const List<node>& terminals,
82  const NodeArray<bool>& isTerminal, EdgeWeightedGraphCopy<T>*& finalSteinerTree) override;
83 
94  void reinsertShortestPaths(EdgeWeightedGraphCopy<T>& completeTerminalGraph,
95  const Voronoi<T>& voronoi, const NodeArray<edge>& mstPred, const EdgeArray<edge>& bridges,
96  EdgeWeightedGraphCopy<T>& finalSteinerTree, const EdgeWeightedGraph<T>& wG);
97 
105  void insertPath(node u, const Voronoi<T>& voronoi, EdgeWeightedGraphCopy<T>& finalSteinerTree,
106  const EdgeWeightedGraph<T>& wG);
107 
111  struct MehlhornTriple {
114  T value;
116  };
117 
121  class MehlhornTripleBucketMaxFunc : public BucketFunc<MehlhornTriple> {
122  public:
124 
125  int getBucket(const MehlhornTriple& MT) {
126  int source_index = MT.u->index();
127  int target_index = MT.v->index();
128  OGDF_ASSERT(source_index != target_index);
129  if (source_index < target_index) {
130  return target_index;
131  } else {
132  return source_index;
133  }
134  }
135  };
136 
140  class MehlhornTripleBucketMinFunc : public BucketFunc<MehlhornTriple> {
141  public:
143 
144  int getBucket(const MehlhornTriple& MT) {
145  int source_index = MT.u->index();
146  int target_index = MT.v->index();
147  OGDF_ASSERT(source_index != target_index);
148  if (source_index < target_index) {
149  return source_index;
150  } else {
151  return target_index;
152  }
153  }
154  };
155 };
156 
157 template<typename T>
159  const List<node>& terminals, const NodeArray<bool>& isTerminal,
160  EdgeWeightedGraphCopy<T>*& finalSteinerTree) {
161  EdgeWeightedGraphCopy<T> completeTerminalGraph;
162  EdgeArray<edge> bridges;
163  Voronoi<T> voronoi(G, G.edgeWeights(), terminals);
164 
165  calculateCompleteGraph(G, terminals, voronoi, bridges, completeTerminalGraph);
166 
167  NodeArray<edge> mstPred(completeTerminalGraph);
168  computeMinST(completeTerminalGraph, completeTerminalGraph.edgeWeights(), mstPred);
169 
170  finalSteinerTree = new EdgeWeightedGraphCopy<T>;
171  finalSteinerTree->setOriginalGraph(G);
172 
173  reinsertShortestPaths(completeTerminalGraph, voronoi, mstPred, bridges, *finalSteinerTree, G);
174 
175  T mstWeight = makeMinimumSpanningTree(*finalSteinerTree, finalSteinerTree->edgeWeights());
176  mstWeight -= MinSteinerTreeModule<T>::pruneAllDanglingSteinerPaths(*finalSteinerTree, isTerminal);
177 
178  return mstWeight;
179 }
180 
181 template<typename T>
183  const List<node>& terminals, const Voronoi<T>& voronoi, EdgeArray<edge>& bridges,
184  EdgeWeightedGraphCopy<T>& completeTerminalGraph) {
185  completeTerminalGraph.setOriginalGraph(wG);
186 
187  for (node v : terminals) {
188  completeTerminalGraph.newNode(v);
189  }
190  if (completeTerminalGraph.numberOfNodes() <= 1) {
191  bridges.init(completeTerminalGraph);
192  return;
193  }
194 
195  // extract complete graph edges
196  List<MehlhornTriple> triples;
197  for (edge e : wG.edges) {
198  MehlhornTriple triple;
199  triple.u = voronoi.seed(e->source());
200  triple.v = voronoi.seed(e->target());
201  if (triple.u != triple.v) {
202  triple.value =
203  voronoi.distance(e->source()) + voronoi.distance(e->target()) + wG.weight(e);
204  triple.bridge = e;
205  triples.pushBack(triple);
206  }
207  }
208 
211 
212  triples.bucketSort(0, wG.maxNodeIndex(), mtbMax);
213  triples.bucketSort(0, wG.maxNodeIndex(), mtbMin);
214 
215  int currentSource = triples.front().u->index();
216  int currentTarget = triples.front().v->index();
217  ListConstIterator<MehlhornTriple> minTriple = triples.begin();
218 
219  bridges.init(completeTerminalGraph);
220 
221  for (ListConstIterator<MehlhornTriple> mtIt = triples.begin().succ(); mtIt.valid(); ++mtIt) {
222  if (((*mtIt).u->index() == currentSource && (*mtIt).v->index() == currentTarget)
223  || ((*mtIt).u->index() == currentTarget && (*mtIt).v->index() == currentSource)) {
224  if ((*mtIt).value < (*minTriple).value) {
225  minTriple = mtIt;
226  }
227  } else {
228  // add new direct edge
229  edge tmp = completeTerminalGraph.newEdge(completeTerminalGraph.copy((*minTriple).u),
230  completeTerminalGraph.copy((*minTriple).v), (*minTriple).value);
231  bridges[tmp] = (*minTriple).bridge;
232 
233  currentSource = (*mtIt).u->index();
234  currentTarget = (*mtIt).v->index();
235  minTriple = mtIt;
236  }
237  }
238  // insert last triple
239  if (minTriple.valid()) {
240  edge tmp = completeTerminalGraph.newEdge(completeTerminalGraph.copy((*minTriple).u),
241  completeTerminalGraph.copy((*minTriple).v), (*minTriple).value);
242  bridges[tmp] = (*minTriple).bridge;
243  }
244 }
245 
246 template<typename T>
248  const Voronoi<T>& voronoi, const NodeArray<edge>& mstPred, const EdgeArray<edge>& bridges,
249  EdgeWeightedGraphCopy<T>& finalSteinerTree, const EdgeWeightedGraph<T>& wG) {
250  for (node u : completeTerminalGraph.nodes) {
251  if (mstPred[u] != nullptr) {
252  edge bridge = bridges[mstPred[u]];
253  node v = bridge->source();
254  node w = bridge->target();
255  insertPath(v, voronoi, finalSteinerTree, wG);
256  insertPath(w, voronoi, finalSteinerTree, wG);
257  edge e = finalSteinerTree.newEdge(finalSteinerTree.copy(v), finalSteinerTree.copy(w),
258  wG.weight(bridge));
259  finalSteinerTree.setEdge(bridge, e);
260  }
261  }
262 }
263 
264 template<typename T>
266  EdgeWeightedGraphCopy<T>& finalSteinerTree, const EdgeWeightedGraph<T>& wG) {
267  node currentSource;
268  node currentTarget = finalSteinerTree.copy(u);
269  if (!currentTarget) {
270  currentTarget = finalSteinerTree.newNode(u);
271  }
272  edge e = voronoi.predecessorEdge(u);
273  edge newE;
274  while (e && finalSteinerTree.chain(e).empty()) { // e is not in ST yet
275  if ((currentSource = finalSteinerTree.copy(
276  e->opposite(finalSteinerTree.original(currentTarget))))
277  == nullptr) {
278  currentSource =
279  finalSteinerTree.newNode(e->opposite(finalSteinerTree.original(currentTarget)));
280  }
281  if (finalSteinerTree.original(currentSource) == e->source()) {
282  newE = finalSteinerTree.newEdge(currentSource, currentTarget, wG.weight(e));
283  } else {
284  newE = finalSteinerTree.newEdge(currentTarget, currentSource, wG.weight(e));
285  }
286  finalSteinerTree.setEdge(e, newE);
287  currentTarget = currentSource;
288  e = voronoi.predecessorEdge(finalSteinerTree.original(currentTarget));
289  }
290 }
291 
292 namespace steiner_tree {
293 
294 template<typename T>
296  const EdgeWeightedGraph<T>& graph, const List<node>& terminals) {
297  EdgeArray<edge> bridges;
298  Voronoi<T> voronoi(graph, graph.edgeWeights(), terminals);
299 
300  MinSteinerTreeMehlhorn<T>::calculateCompleteGraph(graph, terminals, voronoi, bridges,
301  terminalSpanningTree);
302 
303  return makeMinimumSpanningTree(terminalSpanningTree, terminalSpanningTree.edgeWeights());
304 }
305 }
306 }
ogdf
The namespace for all OGDF objects.
Definition: AugmentationModule.h:36
ogdf::MinSteinerTreeMehlhorn::MehlhornTripleBucketMinFunc
Helper class to sort MehlhornTriples lexicographically.
Definition: MinSteinerTreeMehlhorn.h:140
ogdf::MinSteinerTreeMehlhorn
This class implements the Minimum Steiner Tree 2-approximation algorithm by Mehlhorn.
Definition: MinSteinerTreeMehlhorn.h:53
ogdf::MinSteinerTreeMehlhorn::MehlhornTripleBucketMinFunc::MehlhornTripleBucketMinFunc
MehlhornTripleBucketMinFunc()
Definition: MinSteinerTreeMehlhorn.h:142
OGDF_ASSERT
#define OGDF_ASSERT(expr)
Assert condition expr. See doc/build.md for more information.
Definition: basic.h:54
ogdf::EdgeWeightedGraph::weight
T weight(const edge e) const
Definition: EdgeWeightedGraph.h:58
ogdf::NodeElement::index
int index() const
Returns the (unique) node index.
Definition: Graph_d.h:267
ogdf::EdgeWeightedGraphCopy::setOriginalGraph
void setOriginalGraph(const Graph *wG) override
Associates the graph copy with G, but does not create any nodes or edges.
Definition: EdgeWeightedGraphCopy.h:158
ogdf::Voronoi
Computes Voronoi regions in an edge-weighted graph.
Definition: Voronoi.h:46
ogdf::MinSteinerTreeMehlhorn::MehlhornTriple
Represents a triple as specified in the algorithms description (see paper)
Definition: MinSteinerTreeMehlhorn.h:111
ogdf::computeMinST
T computeMinST(const Graph &G, const EdgeArray< T > &weight, EdgeArray< bool > &isInTree)
Computes a minimum spanning tree using Prim's algorithm.
Definition: extended_graph_alg.h:107
ogdf::MinSteinerTreeMehlhorn::calculateCompleteGraph
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.
Definition: MinSteinerTreeMehlhorn.h:182
ogdf::MinSteinerTreeMehlhorn::MehlhornTriple::u
node u
Definition: MinSteinerTreeMehlhorn.h:112
ogdf::MinSteinerTreeMehlhorn::MehlhornTriple::bridge
edge bridge
Definition: MinSteinerTreeMehlhorn.h:115
ogdf::ListIteratorBase::valid
bool valid() const
Returns true iff the iterator points to an element.
Definition: List.h:143
ogdf::EdgeWeightedGraphCopy::newEdge
edge newEdge(node u, node v, T weight)
Definition: EdgeWeightedGraphCopy.h:165
ogdf::Voronoi::predecessorEdge
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:75
ogdf::BucketFunc
Abstract base class for bucket functions.
Definition: basic.h:255
ogdf::steiner_tree::constructTerminalSpanningTreeUsingVoronoiRegions
T constructTerminalSpanningTreeUsingVoronoiRegions(EdgeWeightedGraphCopy< T > &terminalSpanningTree, const EdgeWeightedGraph< T > &graph, const List< node > &terminals)
Definition: MinSteinerTreeMehlhorn.h:295
EdgeWeightedGraphCopy.h
Extends the GraphCopy concept to weighted graphs.
ogdf::MinSteinerTreeModule
Serves as an interface for various methods to compute or approximate minimum Steiner trees on undirec...
Definition: MinSteinerTreeModule.h:59
MinSteinerTreeModule.h
Declaration of ogdf::MinSteinerTreeModule.
ogdf::MinSteinerTreeMehlhorn::reinsertShortestPaths
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...
Definition: MinSteinerTreeMehlhorn.h:247
ogdf::Graph::nodes
internal::GraphObjectContainer< NodeElement > nodes
The container containing all node objects.
Definition: Graph_d.h:924
ogdf::MinSteinerTreeMehlhorn::MehlhornTripleBucketMaxFunc::MehlhornTripleBucketMaxFunc
MehlhornTripleBucketMaxFunc()
Definition: MinSteinerTreeMehlhorn.h:123
ogdf::Graph::numberOfNodes
int numberOfNodes() const
Returns the number of nodes in the graph.
Definition: Graph_d.h:974
ogdf::EdgeWeightedGraph
Definition: EdgeWeightedGraph.h:39
ogdf::MinSteinerTreeModule::pruneAllDanglingSteinerPaths
static T pruneAllDanglingSteinerPaths(EdgeWeightedGraphCopy< T > &steinerTree, const NodeArray< bool > &isTerminal)
Prunes nonterminal leaves and their paths to terminal or branching nodes.
Definition: MinSteinerTreeModule.h:488
ogdf::GraphCopy::chain
const List< edge > & chain(edge e) const
Returns the list of edges coresponding to edge e.
Definition: GraphCopy.h:447
ogdf::EdgeWeightedGraph::edgeWeights
const EdgeArray< T > & edgeWeights() const
Definition: EdgeWeightedGraph.h:60
Voronoi.h
Definition of ogdf::Voronoi class template.
ogdf::MinSteinerTreeMehlhorn::MehlhornTripleBucketMinFunc::getBucket
int getBucket(const MehlhornTriple &MT)
Definition: MinSteinerTreeMehlhorn.h:144
ogdf::Graph::maxNodeIndex
int maxNodeIndex() const
Returns the largest used node index.
Definition: Graph_d.h:980
ogdf::EdgeElement::source
node source() const
Returns the source node of the edge.
Definition: Graph_d.h:391
ogdf::GraphCopyBase::newNode
node newNode(node vOrig)
Creates a new node in the graph copy with original node vOrig.
Definition: GraphCopy.h:185
ogdf::List
Doubly linked lists (maintaining the length of the list).
Definition: List.h:42
ogdf::internal::GraphRegisteredArray
RegisteredArray for nodes, edges and adjEntries of a graph.
Definition: Graph_d.h:651
ogdf::MinSteinerTreeMehlhorn::MehlhornTriple::value
T value
Definition: MinSteinerTreeMehlhorn.h:114
ogdf::MinSteinerTreeMehlhorn::MehlhornTriple::v
node v
Definition: MinSteinerTreeMehlhorn.h:113
ogdf::MinSteinerTreeMehlhorn::MehlhornTripleBucketMaxFunc::getBucket
int getBucket(const MehlhornTriple &MT)
Definition: MinSteinerTreeMehlhorn.h:125
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::MinSteinerTreeMehlhorn::computeSteinerTree
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.
Definition: MinSteinerTreeMehlhorn.h:158
ogdf::GraphCopy::setEdge
void setEdge(edge eOrig, edge eCopy)
sets eOrig to be the corresponding original edge of eCopy and vice versa
ogdf::Voronoi::distance
T distance(node v) const
Returns the distance between v and its Voronoi seed.
Definition: Voronoi.h:84
ogdf::Graph::edges
internal::GraphObjectContainer< EdgeElement > edges
The container containing all edge objects.
Definition: Graph_d.h:927
ogdf::EdgeWeightedGraphCopy::edgeWeights
const EdgeArray< T > & edgeWeights() const
Definition: EdgeWeightedGraphCopy.h:61
ogdf::makeMinimumSpanningTree
T makeMinimumSpanningTree(Graph &G, const EdgeArray< T > &weight)
Reduce a graph to its minimum spanning tree (MST) using Kruskal's algorithm.
Definition: extended_graph_alg.h:233
ogdf::EdgeWeightedGraphCopy
Definition: EdgeWeightedGraphCopy.h:40
ogdf::EdgeElement::opposite
node opposite(node v) const
Returns the adjacent node different from v.
Definition: Graph_d.h:406
ogdf::EdgeElement
Class for the representation of edges.
Definition: Graph_d.h:356
List.h
Declaration of doubly linked lists and iterators.
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::MinSteinerTreeMehlhorn::insertPath
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.
Definition: MinSteinerTreeMehlhorn.h:265
ogdf::ListIteratorBase
Encapsulates a pointer to a list element.
Definition: List.h:46
ogdf::MinSteinerTreeMehlhorn::MinSteinerTreeMehlhorn
MinSteinerTreeMehlhorn()
Definition: MinSteinerTreeMehlhorn.h:55
ogdf::MinSteinerTreeMehlhorn::MehlhornTripleBucketMaxFunc
Helper class to sort MehlhornTriples lexicographically.
Definition: MinSteinerTreeMehlhorn.h:121
ogdf::MinSteinerTreeMehlhorn::~MinSteinerTreeMehlhorn
virtual ~MinSteinerTreeMehlhorn()
Definition: MinSteinerTreeMehlhorn.h:57
ogdf::EdgeElement::target
node target() const
Returns the target node of the edge.
Definition: Graph_d.h:394
ogdf::NodeElement
Class for the representation of nodes.
Definition: Graph_d.h:233
ogdf::Voronoi::seed
node seed(node v) const
Returns the Voronoi seed of node v.
Definition: Voronoi.h:87
ogdf::List::pushBack
iterator pushBack(const E &x)
Adds element x at the end of the list.
Definition: List.h:1537
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