Open
Graph Drawing
Framework

 v. 2023.09 (Elderberry)
 

SaveDynamic.h
Go to the documentation of this file.
1 
33 #pragma once
34 
35 #include <ogdf/basic/Graph.h>
36 #include <ogdf/basic/GraphList.h>
37 #include <ogdf/basic/basic.h>
40 #include <ogdf/tree/LCA.h>
41 
42 #include <utility>
43 
44 namespace ogdf::steiner_tree {
45 template<typename T>
46 class Triple;
47 } // namespace ogdf::steiner_tree
48 
49 namespace ogdf {
50 template<typename T>
51 class EdgeWeightedGraphCopy;
52 
53 namespace steiner_tree {
54 
60 //#define OGDF_SAVEDYNAMIC_CHANGE_TST
61 template<typename T>
62 class SaveDynamic : public Save<T> {
63 public:
70  explicit SaveDynamic(EdgeWeightedGraphCopy<T>& steinerTree)
71  : Save<T>()
72  , m_tree()
73  , m_treeEdge(m_tree, nullptr)
74  , m_steinerTree(&steinerTree)
75  , m_cTerminals(*m_steinerTree, nullptr) {
77  m_lca = new LCA(m_tree, m_root);
78  }
79 
80  virtual ~SaveDynamic() { delete m_lca; }
81 
90  virtual T gain(node u, node v, node w) const {
91  node save1 = lca(m_steinerTree->copy(u), m_steinerTree->copy(v));
92  node save2 = lca(m_steinerTree->copy(u), m_steinerTree->copy(w));
93  if (save1 == save2) {
94  save2 = lca(m_steinerTree->copy(v), m_steinerTree->copy(w));
95  }
96  return weight(save1) + weight(save2);
97  }
98 
106  virtual T saveWeight(node u, node v) const { return weight(saveEdge(u, v)); }
107 
115  virtual edge saveEdge(node u, node v) const {
116  OGDF_ASSERT(m_steinerTree->copy(u));
117  OGDF_ASSERT(m_steinerTree->copy(v));
118  node anc = lca(m_steinerTree->copy(u), m_steinerTree->copy(v));
119  OGDF_ASSERT(anc);
120  return m_treeEdge[anc];
121  }
122 
131  virtual void update(const Triple<T>& t) {
132 #ifdef OGDF_SAVEDYNAMIC_CHANGE_TST
133  edge se0 = saveEdge(t.s0(), t.s1());
134  edge se1 = saveEdge(t.s0(), t.s2());
135  edge se2 = saveEdge(t.s1(), t.s2());
136 #endif
137  // initialize the three terminal nodes
138  node s0 = m_steinerTree->copy(t.s0());
139  node s1 = m_steinerTree->copy(t.s1());
140  node s2 = m_steinerTree->copy(t.s2());
141 
142  // determine the save edges
143  node save1 = lca(s0, s1);
144  node save2 = lca(s0, s2);
145  if (save1 == save2) {
146  save2 = lca(s1, s2);
147  }
148 
149  node v0 = m_cTerminals[s0];
150  node v1 = m_cTerminals[s1];
151  node v2 = m_cTerminals[s2];
152 
153  int v0level = m_lca->level(v0);
154  int v1level = m_lca->level(v1);
155  int v2level = m_lca->level(v2);
156 
157  delete m_lca;
158 
159  node v = m_tree.newNode();
160  node currentNode = m_tree.newNode();
161 #ifdef OGDF_SAVEDYNAMIC_CHANGE_TST
162  const node newNode0 = v, newNode1 = currentNode;
163 #endif
164  OGDF_ASSERT(!m_treeEdge[currentNode]);
165  m_tree.newEdge(currentNode, v);
166  m_cTerminals[s0] = v;
167  m_cTerminals[s1] = v;
168  m_cTerminals[s2] = currentNode;
169 
170  while (v0) {
171  // bubble pointers such that level(v0) >= level(v1) >= level(v2)
172  if (v1level < v2level) {
173  std::swap(v1, v2);
174  std::swap(v1level, v2level);
175  }
176  if (v0level < v1level) {
177  std::swap(v0, v1);
178  std::swap(v0level, v1level);
179  }
180  if (v1level < v2level) {
181  std::swap(v1, v2);
182  std::swap(v1level, v2level);
183  }
184  // bubble pointers such that weight(v0) <= weight(v1), weight(v2)
185  if (weight(v1) > weight(v2)) {
186  std::swap(v1, v2);
187  std::swap(v1level, v2level);
188  }
189  if (weight(v0) > weight(v1)) {
190  std::swap(v0, v1);
191  std::swap(v0level, v1level);
192  }
193  // now v0 is the node with the least weight... if equal, with the highest level.
194 
195  if (v0 != save1 && v0 != save2) {
196  for (adjEntry adj : currentNode->adjEntries) {
197  edge e = adj->theEdge();
198  if (e->target() == currentNode) {
199  m_tree.delEdge(e);
200  break;
201  }
202  }
203  m_tree.newEdge(v0, currentNode);
204  currentNode = v0;
205  } // else: nothing to do since m_tree is binary and save1/save2 are LCAs
206 
207  // set v0 to its parent or to nullptr if there is no parent
208  v = v0;
209  v0 = nullptr;
210  edge e = nullptr;
211  for (adjEntry adj : v->adjEntries) {
212  e = adj->theEdge();
213  if (e->target() == v) {
214  v0 = e->source();
215  --v0level;
216  break;
217  }
218  }
219  OGDF_ASSERT(e != nullptr);
220  if (v1 == e->target()) {
221  v1 = e->source();
222  --v1level;
223  }
224  if (v2 == e->target()) {
225  v2 = e->source();
226  --v2level;
227  }
228  }
229  m_root = currentNode;
230  m_tree.delNode(save1);
231  m_tree.delNode(save2);
232 
233  m_lca = new LCA(m_tree, m_root);
234 
235 #ifdef OGDF_SAVEDYNAMIC_CHANGE_TST
236  edge newEdge0, newEdge1;
237  contractTripleInSteinerTree(t, *m_steinerTree, se0, se1, se2, newEdge0, newEdge1);
238  m_treeEdge[newNode0] = newEdge0;
239  m_treeEdge[newNode1] = newEdge1;
240 #endif
241  }
242 
243 protected:
251  node lca(node u, node v) const {
252  OGDF_ASSERT(u);
253  OGDF_ASSERT(v);
254  return m_lca->call(m_cTerminals[u], m_cTerminals[v]);
255  }
256 
258  T weight(edge e) const { return e ? m_steinerTree->weight(e) : 0; }
259 
261  T weight(node v) const { return weight(m_treeEdge[v]); }
262 
263 private:
267 #ifndef OGDF_SAVEDYNAMIC_CHANGE_TST
268  const
269 #endif
273 };
274 
275 }
276 }
ogdf
The namespace for all OGDF objects.
Definition: multilevelmixer.cpp:39
ogdf::LCA::level
int level(node v) const
Returns the level of a node. The level of the root is 0.
Definition: LCA.h:76
Graph.h
Includes declaration of graph class.
ogdf::steiner_tree::SaveDynamic::m_lca
LCA * m_lca
Data structure for calculating the LCAs.
Definition: SaveDynamic.h:272
ogdf::steiner_tree::contractTripleInSteinerTree
void contractTripleInSteinerTree(const Triple< T > &t, EdgeWeightedGraphCopy< T > &st, edge save0, edge save1, edge save2, edge &ne0, edge &ne1)
Updates the Steiner tree by deleting save edges, removing all direct connections between the terminal...
Definition: common_algorithms.h:159
ogdf::steiner_tree::Triple
This class represents a triple used by various contraction-based minimum Steiner tree approximations.
Definition: common_algorithms.h:48
OGDF_ASSERT
#define OGDF_ASSERT(expr)
Assert condition expr. See doc/build.md for more information.
Definition: basic.h:66
ogdf::steiner_tree::SaveDynamic::weight
T weight(node v) const
Returns the associated weight of a node v in m_tree, or 0 if it is not associated.
Definition: SaveDynamic.h:261
ogdf::Graph::delNode
virtual void delNode(node v)
Removes node v and all incident edges from the graph.
ogdf::steiner_tree::SaveDynamic::update
virtual void update(const Triple< T > &t)
Updates the weighted tree data structure given a contracted triple.
Definition: SaveDynamic.h:131
ogdf::steiner_tree::Triple::s2
node s2() const
Definition: Triple.h:54
ogdf::steiner_tree::Triple::s1
node s1() const
Definition: Triple.h:52
ogdf::steiner_tree::SaveDynamic::gain
virtual T gain(node u, node v, node w) const
Returns the gain (sum of save edge costs) of the given triple, calculated by an LCA query.
Definition: SaveDynamic.h:90
ogdf::LCA::call
node call(node u, node v) const
Returns the LCA of two nodes u and v.
ogdf::steiner_tree::SaveDynamic::SaveDynamic
SaveDynamic(EdgeWeightedGraphCopy< T > &steinerTree)
Builds a weighted binary tree based on the given terminal spanning tree.
Definition: SaveDynamic.h:70
ogdf::steiner_tree::SaveDynamic::m_tree
Graph m_tree
The weighted binary tree to represent the edge weight hierarchy.
Definition: SaveDynamic.h:264
ogdf::steiner_tree::Save
This class serves as an interface for different approaches concerning the calculation of save edges.
Definition: Save.h:50
ogdf::Graph::delEdge
virtual void delEdge(edge e)
Removes edge e from the graph.
ogdf::AdjElement
Class for adjacency list elements.
Definition: Graph_d.h:142
LCA.h
The Sparse Table Algorithm for the Least Common Ancestor problem as proposed by Bender and Farach-Col...
ogdf::steiner_tree
Definition: MinSteinerTreeMehlhorn.h:297
ogdf::steiner_tree::buildHeaviestEdgeInComponentTree
node buildHeaviestEdgeInComponentTree(const EdgeWeightedGraphCopy< T > &inputTree, NodeArray< node > &externalNodes, NodeArray< edge > &treeEdge, Graph &outputTree)
Given an edge-weighted tree, builds an auxiliary arborescence where each arc of the input tree is a n...
Definition: common_algorithms.h:69
ogdf::AdjElement::theEdge
edge theEdge() const
Returns the edge associated with this adjacency entry.
Definition: Graph_d.h:160
ogdf::steiner_tree::SaveDynamic::m_steinerTree
const EdgeWeightedGraphCopy< T > * m_steinerTree
The underlying terminal spanning tree this weighted tree instance represents.
Definition: SaveDynamic.h:270
common_algorithms.h
Algorithms used by at least two functions of Steiner tree code or its internal helpers.
GraphList.h
Decralation of GraphElement and GraphList classes.
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::steiner_tree::SaveDynamic::lca
node lca(node u, node v) const
Returns the node in m_tree that is the LCA of two nodes.
Definition: SaveDynamic.h:251
ogdf::steiner_tree::SaveDynamic::saveWeight
virtual T saveWeight(node u, node v) const
Determines the weight of the save edge between two nodes by a LCA query.
Definition: SaveDynamic.h:106
ogdf::EdgeElement::source
node source() const
Returns the source node of the edge.
Definition: Graph_d.h:398
ogdf::internal::GraphRegisteredArray
RegisteredArray for nodes, edges and adjEntries of a graph.
Definition: Graph_d.h:658
ogdf::LCA
Implements the <O(n log n), O(1)>-time "sparse table" algorithm by Bender and Farach-Colton to comput...
Definition: LCA.h:54
ogdf::Graph
Data type for general directed graphs (adjacency list representation).
Definition: Graph_d.h:869
ogdf::steiner_tree::Triple::s0
node s0() const
Definition: Triple.h:50
ogdf::steiner_tree::SaveDynamic
Dynamically updatable weighted Tree for determining save edges via LCA computation.
Definition: SaveDynamic.h:62
basic.h
Basic declarations, included by all source files.
ogdf::Graph::newNode
node newNode(int index=-1)
Creates a new node and returns it.
Definition: Graph_d.h:1064
ogdf::EdgeWeightedGraphCopy
Definition: EdgeWeightedGraphCopy.h:44
ogdf::steiner_tree::SaveDynamic::weight
T weight(edge e) const
Returns the weight of an edge in the terminal tree or 0.
Definition: SaveDynamic.h:258
ogdf::EdgeElement
Class for the representation of edges.
Definition: Graph_d.h:363
ogdf::steiner_tree::SaveDynamic::~SaveDynamic
virtual ~SaveDynamic()
Definition: SaveDynamic.h:80
ogdf::steiner_tree::SaveDynamic::saveEdge
virtual edge saveEdge(node u, node v) const
Determines the save edge between two nodes by a LCA query.
Definition: SaveDynamic.h:115
ogdf::steiner_tree::SaveDynamic::m_treeEdge
NodeArray< edge > m_treeEdge
Maps each inner node of m_tree to an edge in m_steinerTree.
Definition: SaveDynamic.h:265
Save.h
Interface for various LCA methods.
ogdf::EdgeElement::target
node target() const
Returns the target node of the edge.
Definition: Graph_d.h:401
ogdf::steiner_tree::SaveDynamic::m_root
node m_root
The root node of the weighted binary tree.
Definition: SaveDynamic.h:266
ogdf::Graph::newEdge
edge newEdge(node v, node w, int index=-1)
Creates a new edge (v,w) and returns it.
Definition: Graph_d.h:1083
ogdf::steiner_tree::SaveDynamic::m_cTerminals
NodeArray< node > m_cTerminals
Connects terminal nodes in the terminal spanning tree to their leafs in the weighted tree.
Definition: SaveDynamic.h:271
ogdf::NodeElement
Class for the representation of nodes.
Definition: Graph_d.h:240