Open
Graph Drawing
Framework

 v. 2023.09 (Elderberry)
 

SaveDynamic.h
Go to the documentation of this file.
1 
33 #pragma once
34 
38 #include <ogdf/tree/LCA.h>
39 
40 namespace ogdf {
41 namespace steiner_tree {
42 
48 //#define OGDF_SAVEDYNAMIC_CHANGE_TST
49 template<typename T>
50 class SaveDynamic : public Save<T> {
51 public:
58  explicit SaveDynamic(EdgeWeightedGraphCopy<T>& steinerTree)
59  : Save<T>()
60  , m_tree()
61  , m_treeEdge(m_tree, nullptr)
62  , m_steinerTree(&steinerTree)
63  , m_cTerminals(*m_steinerTree, nullptr) {
65  m_lca = new LCA(m_tree, m_root);
66  }
67 
68  virtual ~SaveDynamic() { delete m_lca; }
69 
78  virtual T gain(node u, node v, node w) const {
79  node save1 = lca(m_steinerTree->copy(u), m_steinerTree->copy(v));
80  node save2 = lca(m_steinerTree->copy(u), m_steinerTree->copy(w));
81  if (save1 == save2) {
82  save2 = lca(m_steinerTree->copy(v), m_steinerTree->copy(w));
83  }
84  return weight(save1) + weight(save2);
85  }
86 
94  virtual T saveWeight(node u, node v) const { return weight(saveEdge(u, v)); }
95 
103  virtual edge saveEdge(node u, node v) const {
104  OGDF_ASSERT(m_steinerTree->copy(u));
105  OGDF_ASSERT(m_steinerTree->copy(v));
106  node anc = lca(m_steinerTree->copy(u), m_steinerTree->copy(v));
107  OGDF_ASSERT(anc);
108  return m_treeEdge[anc];
109  }
110 
119  virtual void update(const Triple<T>& t) {
120 #ifdef OGDF_SAVEDYNAMIC_CHANGE_TST
121  edge se0 = saveEdge(t.s0(), t.s1());
122  edge se1 = saveEdge(t.s0(), t.s2());
123  edge se2 = saveEdge(t.s1(), t.s2());
124 #endif
125  // initialize the three terminal nodes
126  node s0 = m_steinerTree->copy(t.s0());
127  node s1 = m_steinerTree->copy(t.s1());
128  node s2 = m_steinerTree->copy(t.s2());
129 
130  // determine the save edges
131  node save1 = lca(s0, s1);
132  node save2 = lca(s0, s2);
133  if (save1 == save2) {
134  save2 = lca(s1, s2);
135  }
136 
137  node v0 = m_cTerminals[s0];
138  node v1 = m_cTerminals[s1];
139  node v2 = m_cTerminals[s2];
140 
141  int v0level = m_lca->level(v0);
142  int v1level = m_lca->level(v1);
143  int v2level = m_lca->level(v2);
144 
145  delete m_lca;
146 
147  node v = m_tree.newNode();
148  node currentNode = m_tree.newNode();
149 #ifdef OGDF_SAVEDYNAMIC_CHANGE_TST
150  const node newNode0 = v, newNode1 = currentNode;
151 #endif
152  OGDF_ASSERT(!m_treeEdge[currentNode]);
153  m_tree.newEdge(currentNode, v);
154  m_cTerminals[s0] = v;
155  m_cTerminals[s1] = v;
156  m_cTerminals[s2] = currentNode;
157 
158  while (v0) {
159  // bubble pointers such that level(v0) >= level(v1) >= level(v2)
160  if (v1level < v2level) {
161  std::swap(v1, v2);
162  std::swap(v1level, v2level);
163  }
164  if (v0level < v1level) {
165  std::swap(v0, v1);
166  std::swap(v0level, v1level);
167  }
168  if (v1level < v2level) {
169  std::swap(v1, v2);
170  std::swap(v1level, v2level);
171  }
172  // bubble pointers such that weight(v0) <= weight(v1), weight(v2)
173  if (weight(v1) > weight(v2)) {
174  std::swap(v1, v2);
175  std::swap(v1level, v2level);
176  }
177  if (weight(v0) > weight(v1)) {
178  std::swap(v0, v1);
179  std::swap(v0level, v1level);
180  }
181  // now v0 is the node with the least weight... if equal, with the highest level.
182 
183  if (v0 != save1 && v0 != save2) {
184  for (adjEntry adj : currentNode->adjEntries) {
185  edge e = adj->theEdge();
186  if (e->target() == currentNode) {
187  m_tree.delEdge(e);
188  break;
189  }
190  }
191  m_tree.newEdge(v0, currentNode);
192  currentNode = v0;
193  } // else: nothing to do since m_tree is binary and save1/save2 are LCAs
194 
195  // set v0 to its parent or to nullptr if there is no parent
196  v = v0;
197  v0 = nullptr;
198  edge e = nullptr;
199  for (adjEntry adj : v->adjEntries) {
200  e = adj->theEdge();
201  if (e->target() == v) {
202  v0 = e->source();
203  --v0level;
204  break;
205  }
206  }
207  OGDF_ASSERT(e != nullptr);
208  if (v1 == e->target()) {
209  v1 = e->source();
210  --v1level;
211  }
212  if (v2 == e->target()) {
213  v2 = e->source();
214  --v2level;
215  }
216  }
217  m_root = currentNode;
218  m_tree.delNode(save1);
219  m_tree.delNode(save2);
220 
221  m_lca = new LCA(m_tree, m_root);
222 
223 #ifdef OGDF_SAVEDYNAMIC_CHANGE_TST
224  edge newEdge0, newEdge1;
225  contractTripleInSteinerTree(t, *m_steinerTree, se0, se1, se2, newEdge0, newEdge1);
226  m_treeEdge[newNode0] = newEdge0;
227  m_treeEdge[newNode1] = newEdge1;
228 #endif
229  }
230 
231 protected:
239  node lca(node u, node v) const {
240  OGDF_ASSERT(u);
241  OGDF_ASSERT(v);
242  return m_lca->call(m_cTerminals[u], m_cTerminals[v]);
243  }
244 
246  T weight(edge e) const { return e ? m_steinerTree->weight(e) : 0; }
247 
249  T weight(node v) const { return weight(m_treeEdge[v]); }
250 
251 private:
255 #ifndef OGDF_SAVEDYNAMIC_CHANGE_TST
256  const
257 #endif
261 };
262 
263 }
264 }
ogdf
The namespace for all OGDF objects.
Definition: AugmentationModule.h:36
ogdf::LCA::level
int level(node v) const
Returns the level of a node. The level of the root is 0.
Definition: LCA.h:74
ogdf::steiner_tree::SaveDynamic::m_lca
LCA * m_lca
Data structure for calculating the LCAs.
Definition: SaveDynamic.h:260
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:143
ogdf::steiner_tree::Triple
This class represents a triple used by various contraction-based minimum Steiner tree approximations.
Definition: Triple.h:44
OGDF_ASSERT
#define OGDF_ASSERT(expr)
Assert condition expr. See doc/build.md for more information.
Definition: basic.h:54
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:249
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:119
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:78
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:58
ogdf::steiner_tree::SaveDynamic::m_tree
Graph m_tree
The weighted binary tree to represent the edge weight hierarchy.
Definition: SaveDynamic.h:252
Triple.h
Definition of a Triple used in contraction-based approximation algorithm for the minimum Steiner tree...
ogdf::steiner_tree::Save
This class serves as an interface for different approaches concerning the calculation of save edges.
Definition: Save.h:45
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:135
LCA.h
The Sparse Table Algorithm for the Least Common Ancestor problem as proposed by Bender and Farach-Col...
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:53
ogdf::AdjElement::theEdge
edge theEdge() const
Returns the edge associated with this adjacency entry.
Definition: Graph_d.h:153
ogdf::steiner_tree::SaveDynamic::m_steinerTree
const EdgeWeightedGraphCopy< T > * m_steinerTree
The underlying terminal spanning tree this weighted tree instance represents.
Definition: SaveDynamic.h:258
common_algorithms.h
Algorithms used by at least two functions of Steiner tree code or its internal helpers.
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::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:239
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:94
ogdf::EdgeElement::source
node source() const
Returns the source node of the edge.
Definition: Graph_d.h:391
ogdf::internal::GraphRegisteredArray
RegisteredArray for nodes, edges and adjEntries of a graph.
Definition: Graph_d.h:651
ogdf::LCA
Implements the <O(n log n), O(1)>-time "sparse table" algorithm by Bender and Farach-Colton to comput...
Definition: LCA.h:52
ogdf::Graph
Data type for general directed graphs (adjacency list representation).
Definition: Graph_d.h:862
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:50
ogdf::Graph::newNode
node newNode(int index=-1)
Creates a new node and returns it.
Definition: Graph_d.h:1056
ogdf::EdgeWeightedGraphCopy
Definition: EdgeWeightedGraphCopy.h:40
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:246
ogdf::EdgeElement
Class for the representation of edges.
Definition: Graph_d.h:356
ogdf::steiner_tree::SaveDynamic::~SaveDynamic
virtual ~SaveDynamic()
Definition: SaveDynamic.h:68
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:103
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:253
Save.h
Interface for various LCA methods.
ogdf::EdgeElement::target
node target() const
Returns the target node of the edge.
Definition: Graph_d.h:394
ogdf::steiner_tree::SaveDynamic::m_root
node m_root
The root node of the weighted binary tree.
Definition: SaveDynamic.h:254
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:1075
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:259
ogdf::NodeElement
Class for the representation of nodes.
Definition: Graph_d.h:233