Open
Graph Drawing
Framework

 v. 2023.09 (Elderberry)
 

Loading...
Searching...
No Matches
HeavyPathDecomposition.h
Go to the documentation of this file.
1
32#pragma once
33
34#include <ogdf/basic/Math.h>
36
37#include <vector>
38
39namespace ogdf {
40namespace steiner_tree {
41
46template<typename T>
48private:
52
53 std::vector<std::vector<node>> chains;
54 std::vector<std::vector<node>> chainsOfTerminals;
61 std::vector<node> fatherOfChain;
62
63 std::vector<std::vector<T>> longestDistToSteinerAncestorOnChain;
64 std::vector<std::vector<T>> longestDistToSteinerAncestorSegTree;
65
70 void buildMaxSegmentTree(std::vector<T>& segmentTree, const int nodeIndex, const int left,
71 const int right, const std::vector<T>& baseArray) const {
72 if (left == right) { // leaf
74 return;
75 }
76
77 int middle = (left + right) >> 1;
80
83
85 }
86
91 T getMaxSegmentTree(const std::vector<T>& segmentTree, const int nodeIndex, const int left,
92 const int right, const int queryLeft, const int queryRight) const {
93 if (queryLeft > queryRight || left > queryRight || queryLeft > right) {
94 return 0;
95 }
96
97 if (queryLeft <= left && right <= queryRight) { // included
98 return segmentTree[nodeIndex];
99 }
100
101 int middleIndex = (left + right) >> 1;
104
105 T maxValue(0);
106 if (queryLeft <= middleIndex) {
107 Math::updateMax(maxValue,
109 queryRight));
110 }
111 if (queryRight > middleIndex) {
112 Math::updateMax(maxValue,
115 }
116
117 return maxValue;
118 }
119
124 T distanceToAncestor(node v, node ancestor) const {
125 if (ancestor == nullptr) {
126 return distanceToRoot[v];
127 }
128 return distanceToRoot[v] - distanceToRoot[ancestor];
129 }
130
138 for (int i = 0; i < (int)chains.size(); ++i) {
139 longestDistToSteinerAncestorOnChain[i].resize((int)chains[i].size());
140 for (int j = 0; j < (int)chains[i].size(); ++j) {
143 if (j > 0) {
146 }
147 }
148 }
149 }
150
158 for (int i = 0; i < (int)chains.size(); ++i) {
159 longestDistToSteinerAncestorSegTree[i].resize(4 * (int)chains[i].size());
160
163 for (int j = 0; j < (int)chains[i].size(); ++j) {
166 }
167
169 (int)chains[i].size() - 1, distanceToSteinerAncestor_byPosition);
170 }
171 }
172
178 weightOfSubtree[v] = 1;
179 node heaviestSon = nullptr;
181
182 for (adjEntry adj : v->adjEntries) {
183 edge e = adj->theEdge();
184 node son = adj->twinNode();
185
186 if (weightOfSubtree[son] != 0) { // the parent
187 continue;
188 }
189
190 nodeLevel[son] = nodeLevel[v] + 1;
191 distanceToRoot[son] = distanceToRoot[v] + tree.weight(e);
192
194
199 }
200 }
201
202 if (heaviestSon == nullptr) { // it's leaf => new chain
203 OGDF_ASSERT((v->degree() <= 1));
204
205 std::vector<node> new_chain;
206 chains.push_back(new_chain);
207 chainsOfTerminals.push_back(new_chain);
208
209 fatherOfChain.push_back(nullptr);
210 chainOfNode[v] = (int)chains.size() - 1;
211 } else {
213 }
214
215 chains[chainOfNode[v]].push_back(v);
216 chainsOfTerminals[chainOfNode[v]].push_back(v);
217 positionOnChain[v] = (int)chains[chainOfNode[v]].size() - 1;
218 }
219
225 node binarySearchUpmostTerminal(node v, const std::vector<node>& chainOfTerminals) const {
226 int left = 0, middle, right = (int)chainOfTerminals.size() - 1;
227 while (left <= right) {
228 middle = (left + right) >> 1;
229
231 right = middle - 1;
232 } else {
233 left = middle + 1;
234 }
235 }
236
237 if (left == (int)chainOfTerminals.size()) {
238 return nullptr;
239 }
240 return chainOfTerminals[left];
241 }
242
253 T& fromLowestToAncestor) const {
255 while (closestSteinerAncestor[chains[chainOfNode[x]][0]] != nullptr
257 >= nodeLevel[ancestor]) {
260
261 if (!chainsOfTerminals[chainOfNode[x]].empty()
264 }
266 }
267
268 // search the upmost terminal on the current chain that has level >= level[ancestor]
272 upmostTerminalLastChain = nullptr;
273 }
274 if (upmostTerminalLastChain != nullptr) {
276 }
277
278 if (upmostTerminalLastChain != nullptr) {
281 static_cast<int>(chains[chainOfNode[x]].size()) - 1,
283 }
284
286 }
287
288public:
291 , chainOfNode {tree, -1}
292 , positionOnChain {tree, -1}
293 , weightOfSubtree {tree, 0}
294 , nodeLevel {tree, 0}
295 , distanceToRoot {tree, 0}
297 OGDF_ASSERT(!tree.empty());
298 node root = tree.firstNode();
299
300 dfsHeavyPathDecomposition(root, nullptr);
301 fatherOfChain[chainOfNode[root]] = nullptr;
302
303 // reverse the obtained chains
304 int numberOfChains = static_cast<int>(chains.size());
305 for (int i = 0; i < numberOfChains; ++i) {
306 reverse(chains[i].begin(), chains[i].end());
307 reverse(chainsOfTerminals[i].begin(), chainsOfTerminals[i].end());
308 for (node v : chains[i]) {
309 positionOnChain[v] = (int)chains[i].size() - 1 - positionOnChain[v];
310 }
311 }
312
315 }
316
322 while (chainOfNode[x] != chainOfNode[y]) {
325 : -1;
328 : -1;
329
332 } else {
334 }
335 }
336
337 if (nodeLevel[x] <= nodeLevel[y]) {
338 return x;
339 }
340 return y;
341 }
342
360};
361
362}
363}
Extends the GraphCopy concept to weighted graphs.
Mathematical Helpers.
Class for adjacency list elements.
Definition Graph_d.h:79
INDEX size() const
Returns the size (number of elements) of the array.
Definition Array.h:297
Class for the representation of edges.
Definition Graph_d.h:300
Doubly linked lists (maintaining the length of the list).
Definition List.h:1435
Dynamic arrays indexed with nodes.
Definition NodeArray.h:125
Class for the representation of nodes.
Definition Graph_d.h:177
int degree() const
Returns the degree of the node (indegree + outdegree).
Definition Graph_d.h:220
internal::GraphObjectContainer< AdjElement > adjEntries
The container containing all entries in the adjacency list of this node.
Definition Graph_d.h:208
An implementation of the heavy path decomposition on trees.
List< node > terminals
list of terminals of the desc tree
NodeArray< int > chainOfNode
the index of a node's chain
NodeArray< int > nodeLevel
the level of a node in the tree
NodeArray< int > positionOnChain
position of a node on his chain
void buildMaxSegmentTree(std::vector< T > &segmentTree, const int nodeIndex, const int left, const int right, const std::vector< T > &baseArray) const
builds a max segment tree on the baseArray
std::vector< node > fatherOfChain
the first node from bottom up that does not belong to the chain
std::vector< std::vector< T > > longestDistToSteinerAncestorOnChain
the max of the interval 0..i for every i on chains
void computeBottleneckOnBranch(node x, node ancestor, T &longestPathDistance, T &fromLowestToAncestor) const
computes for the path from x to ancestor the maximum distance (sum of edges) between any two consecut...
std::vector< std::vector< node > > chains
list of chains of nodes corresponding to the decomposition
T getMaxSegmentTree(const std::vector< T > &segmentTree, const int nodeIndex, const int left, const int right, const int queryLeft, const int queryRight) const
extracts the maximum on the required interval
std::vector< std::vector< node > > chainsOfTerminals
list of chains only of terminals corresponding to the decomposition
NodeArray< T > distanceToRoot
the length of the edge to his father
const EdgeWeightedGraphCopy< T > & tree
constant ref to the tree to be decomposed
NodeArray< node > closestSteinerAncestor
the highest-level Steiner ancestor of the current node
void dfsHeavyPathDecomposition(node v, node closestSteinerUpNode)
performs the heavy path decomposition on the tree belonging to the class updates the fields of the cl...
node lowestCommonAncestor(node x, node y) const
computes the lowest common ancestor of nodes x and y using the hpd
T getBottleneckSteinerDistance(node x, node y) const
computes in the bottleneck distance between terminals x and y
HeavyPathDecomposition(const EdgeWeightedGraphCopy< T > &treeEWGraphCopy)
T distanceToAncestor(node v, node ancestor) const
computes the sum of all edges on the path from v to ancestor v must be in ancestor's subtree
const NodeArray< bool > isTerminal
isTerminal of the desc tree
void computeLongestDistToSteinerAncestorOnChain()
creates for every chain an array with the maximum of every prefix of a fictive array which keeps for ...
std::vector< std::vector< T > > longestDistToSteinerAncestorSegTree
segment tree for segment maxs on every chain
NodeArray< int > weightOfSubtree
weight of the subtree rooted in one node
node binarySearchUpmostTerminal(node v, const std::vector< node > &chainOfTerminals) const
performs a binary search on chainOfTerminals, searches for the closest node to the root on chainOfTer...
void computeLongestDistToSteinerAncestorSegTree()
creates for every chain a segment tree built on a fictive array which keeps for every node the sum of...
Reverse< T > reverse(T &container)
Provides iterators for container to make it easily iterable in reverse.
Definition Reverse.h:74
#define OGDF_ASSERT(expr)
Assert condition expr. See doc/build.md for more information.
Definition basic.h:41
static MultilevelBuilder * getDoubleFactoredZeroAdjustedMerger()
void updateMax(T &max, const T &newValue)
Stores the maximum of max and newValue in max.
Definition Math.h:90
The namespace for all OGDF objects.