TTK
Loading...
Searching...
No Matches
DynamicGraph_Template.h
Go to the documentation of this file.
1#pragma once
2
3#include "DynamicGraph.h"
4
5#include <sstream>
6
7namespace ttk {
8 namespace ftr {
9
10 // DynamicGraph ----------------------------------
11
12 template <typename Type>
14
15 template <typename Type>
17
18 template <typename Type>
20 nodes_.resize(nbElmt_);
21 }
22
23 template <typename Type>
26
27 template <typename Type>
29 DynGraphNode<Type> *const n2) {
30 if(n1->parent_ == n2) {
31 removeEdge(n1);
32 return 1;
33 }
34
35 if(n2->parent_ == n1) {
36 removeEdge(n2);
37 return 2;
38 }
39
40 return 0;
41 }
42
43 template <typename Type>
45
46 std::stringstream res;
47
48 for(const auto &node : nodes_) {
49 if(1 or node.parent_) {
50 res << "id: " << &node - &nodes_[0];
51 if(node.parent_) {
52 res << ", parent: " << node.parent_ - &nodes_[0];
53 } else {
54 res << ", parent: X";
55 }
56 res << " root: " << findRoot(&node) - &nodes_[0];
57 res << " weight: " << (float)node.weight_;
58 res << " cArc: " << node.corArc_;
59 res << std::endl;
60 }
61 }
62 return res.str();
63 }
64
65 template <typename Type>
67 const std::function<std::string(std::size_t)> &printFunction) {
68
69 std::stringstream res;
70
71 for(const auto &node : nodes_) {
72 if(node.parent_) {
73 res << "id: " << printFunction(&node - &nodes_[0])
74 << " weight: " << (float)node.weight_;
75 if(node.parent_) {
76 res << ", parent: " << printFunction(node.parent_ - &nodes_[0]);
77 } else {
78 res << ", parent: X";
79 }
80 res << " root: " << printFunction(findRoot(&node) - &nodes_[0]);
81 }
82 }
83 return res.str();
84 }
85
86 template <typename Type>
88
89 std::stringstream res;
90 std::vector<DynGraphNode<Type> *> roots;
91 roots.reserve(nodes_.size());
92 for(const auto &n : nodes_) {
93 roots.emplace_back(n.findRoot());
94 }
95 std::sort(roots.begin(), roots.end());
96 const auto it = std::unique(roots.begin(), roots.end());
97 roots.erase(it, roots.end());
98 res << "nb nodes " << nodes_.size() << std::endl;
99 res << "nb cc " << roots.size() << std::endl;
100 return res.str();
101 }
102
103 // DynGraphNode ----------------------------------
104
105 template <typename Type>
107 if(!parent_)
108 return;
109
110 DynGraphNode<Type> *curNode = this;
111
112 DynGraphNode<Type> *parentNode = curNode->parent_;
113 Type parentWeight = curNode->weight_;
114
115 DynGraphNode<Type> *gParentNode = parentNode->parent_;
116 Type gParentWeight = parentNode->weight_;
117
118 curNode->parent_ = nullptr;
119
120 // Reverse all the node until the root
121 while(true) {
122 parentNode->parent_ = curNode;
123 parentNode->weight_ = parentWeight;
124
125 curNode = parentNode;
126 parentNode = gParentNode;
127 parentWeight = gParentWeight;
128
129 if(gParentNode) {
130 gParentWeight = gParentNode->weight_;
131 gParentNode = gParentNode->parent_;
132 } else {
133 // keep same arc than the current root
134 // if cur > this ?
135 corArc_ = curNode->corArc_;
136 break;
137 }
138 }
139 }
140
141 template <typename Type>
143 // the lastNode trick is used so we are sure to have a non null
144 // return even if another thread is touching these nodes.
145 DynGraphNode *curNode = const_cast<DynGraphNode<Type> *>(this);
146 DynGraphNode *lastNode = curNode;
147 while(curNode) {
148 lastNode = curNode;
149#ifdef TTK_ENABLE_OPENMP
150#pragma omp atomic read
151#endif
152 curNode = curNode->parent_;
153 }
154 return lastNode;
155 }
156
157 template <typename Type>
159 const auto root = findRoot();
160 return root != nullptr ? root->corArc_ : -1;
161 }
162
163 template <typename Type>
165 corArc_ = arcId;
166 }
167
168 template <typename Type>
169 std::tuple<DynGraphNode<Type> *, DynGraphNode<Type> *>
171
172 DynGraphNode *minNode = const_cast<DynGraphNode<Type> *>(this);
173 auto minW = minNode->weight_;
174 DynGraphNode *curNode = minNode->parent_;
175
176 if(!curNode)
177 return std::make_tuple(curNode, minNode);
178
179 while(curNode->parent_) {
180 if(curNode->weight_ < minW) {
181 minNode = curNode;
182 minW = minNode->weight_;
183 }
184 curNode = curNode->parent_;
185 }
186 return std::make_tuple(curNode, minNode);
188
189 template <typename Type>
191 const Type weight,
192 const idSuperArc corArc) {
193 evert();
194 auto nNodes = n->findMinWeightRoot();
195
196 if(std::get<0>(nNodes) != this) {
197 // The two nodes are in two different trees
198 parent_ = n;
199 weight_ = weight;
200 n->corArc_ = corArc;
201 return true;
202 }
203
204 // here the nodes are in the same tree
205
206 if(weight > std::get<1>(nNodes)->weight_) {
207 // We need replace the min edge by the new one as the current weight is
208 // higher
209
210 // add arc (Parsa like)
211 parent_ = n;
212 weight_ = weight;
213 // corArc_ = corArc;
214
215 // remove old
216 std::get<1>(nNodes)->parent_ = nullptr;
217 std::get<1>(nNodes)->corArc_ = corArc;
218 } else {
219 corArc_ = corArc;
220 }
221
222 return false;
223 }
224
225 template <typename Type>
227#ifndef TTK_ENABLE_KAMIKAZE
228 if(!parent_) {
229 Debug dbg{};
230 dbg.setDebugMsgPrefix("DynamicGraph");
231 dbg.printErr("DynGraph remove edge in root node");
232 return;
233 }
234#endif
235
236 parent_ = nullptr;
237 }
238
239 } // namespace ftr
240} // namespace ttk
Minimalist debugging class.
Definition Debug.h:88
void setDebugMsgPrefix(const std::string &prefix)
Definition Debug.h:364
void removeEdge(DynGraphNode< Type > *const n)
remove the link btwn n and its parent
long unsigned int idSuperArc
SuperArc index in vect_superArcs_.
The Topology ToolKit.
class representing a node of a tree and the link to its parent if not the root
void evert()
Make this node the root of its tree.
DynGraphNode * findRoot() const
Get representative node.
DynGraphNode * parent_
std::tuple< DynGraphNode< Type > *, DynGraphNode< Type > * > findMinWeightRoot() const
bool insertEdge(DynGraphNode *const n, const Type weight, const idSuperArc corArc)
void setRootArc(const idSuperArc arcId)