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
SaveDynamic.h
Go to the documentation of this file.
1
33#pragma once
34
38#include <ogdf/tree/LCA.h>
39
40namespace ogdf {
41namespace steiner_tree {
42
48//#define OGDF_SAVEDYNAMIC_CHANGE_TST
49template<typename T>
50class SaveDynamic : public Save<T> {
51public:
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));
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();
149#ifdef OGDF_SAVEDYNAMIC_CHANGE_TST
150 const node newNode0 = v, newNode1 = currentNode;
151#endif
154 m_cTerminals[s0] = v;
155 m_cTerminals[s1] = v;
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 }
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 }
220
221 m_lca = new LCA(m_tree, m_root);
222
223#ifdef OGDF_SAVEDYNAMIC_CHANGE_TST
228#endif
229 }
230
231protected:
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
251private:
255#ifndef OGDF_SAVEDYNAMIC_CHANGE_TST
256 const
257#endif
261};
262
263}
264}
The Sparse Table Algorithm for the Least Common Ancestor problem as proposed by Bender and Farach-Col...
Interface for various LCA methods.
Definition of a Triple used in contraction-based approximation algorithm for the minimum Steiner tree...
Class for adjacency list elements.
Definition Graph_d.h:79
Class for the representation of edges.
Definition Graph_d.h:300
node target() const
Returns the target node of the edge.
Definition Graph_d.h:338
node source() const
Returns the source node of the edge.
Definition Graph_d.h:335
Data type for general directed graphs (adjacency list representation).
Definition Graph_d.h:521
edge newEdge(node v, node w)
Creates a new edge (v,w) and returns it.
virtual void delNode(node v)
Removes node v and all incident edges from the graph.
virtual void delEdge(edge e)
Removes edge e from the graph.
node newNode()
Creates a new node and returns it.
Implements the <O(n log n), O(1)>-time "sparse table" algorithm by Bender and Farach-Colton to comput...
Definition LCA.h:52
int level(node v) const
Returns the level of a node. The level of the root is 0.
Definition LCA.h:74
node call(node u, node v) const
Returns the LCA of two nodes u and v.
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
Dynamically updatable weighted Tree for determining save edges via LCA computation.
Definition SaveDynamic.h:50
Graph m_tree
The weighted binary tree to represent the edge weight hierarchy.
node lca(node u, node v) const
Returns the node in m_tree that is the LCA of two nodes.
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
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
virtual void update(const Triple< T > &t)
Updates the weighted tree data structure given a contracted triple.
NodeArray< node > m_cTerminals
Connects terminal nodes in the terminal spanning tree to their leafs in the weighted tree.
node m_root
The root node of the weighted binary tree.
SaveDynamic(EdgeWeightedGraphCopy< T > &steinerTree)
Builds a weighted binary tree based on the given terminal spanning tree.
Definition SaveDynamic.h:58
T weight(node v) const
Returns the associated weight of a node v in m_tree, or 0 if it is not associated.
T weight(edge e) const
Returns the weight of an edge in the terminal tree or 0.
LCA * m_lca
Data structure for calculating the LCAs.
virtual edge saveEdge(node u, node v) const
Determines the save edge between two nodes by a LCA query.
const EdgeWeightedGraphCopy< T > * m_steinerTree
The underlying terminal spanning tree this weighted tree instance represents.
NodeArray< edge > m_treeEdge
Maps each inner node of m_tree to an edge in m_steinerTree.
This class serves as an interface for different approaches concerning the calculation of save edges.
Definition Save.h:45
This class represents a triple used by various contraction-based minimum Steiner tree approximations.
Definition Triple.h:44
Algorithms used by at least two functions of Steiner tree code or its internal helpers.
#define OGDF_ASSERT(expr)
Assert condition expr. See doc/build.md for more information.
Definition basic.h:41
static MultilevelBuilder * getDoubleFactoredZeroAdjustedMerger()
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...
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...
The namespace for all OGDF objects.