TTK
Loading...
Searching...
No Matches
DynamicGraph.h
Go to the documentation of this file.
1
13
14#pragma once
15
16#include "FTRCommon.h"
17
18#include <set>
19#include <vector>
20
21namespace ttk {
22 namespace ftr {
23
24 template <typename Type>
25 struct DynGraphNode;
26
27 using idRoot = int;
28
29 template <typename Type>
30 class DynamicGraph : public Allocable {
31 protected:
32 std::vector<DynGraphNode<Type>> nodes_;
33
34 public:
36 ~DynamicGraph() override;
37
38 // Initialize functions
39 // --------------------
40
41 void setNumberOfNodes(const std::size_t nbNodes) {
42 setNumberOfElmt(nbNodes);
43 }
44
48 void alloc() override;
49
50 void init() override;
51
52 // Dyn Graph functions
53 // -------------------
54
56 DynGraphNode<Type> *getNode(const std::size_t nid) {
57 return &nodes_[nid];
58 }
59
60 const DynGraphNode<Type> *getNode(const std::size_t nid) const {
61 return &nodes_[nid];
62 }
63
65 std::size_t getNodeId(DynGraphNode<Type> *node) {
66 return std::distance(&(nodes_[0]), node);
67 }
68
69 void setSubtreeArc(const std::size_t nid, const idSuperArc arc) {
70 getNode(nid)->findRoot()->setRootArc(arc);
71 }
72
73 void setCorArc(const std::size_t nid, idSuperArc arc) {
74 getNode(nid)->setRootArc(arc);
75 }
76
77 idSuperArc getSubtreeArc(const std::size_t nid) const {
78 const auto node{getNode(nid)};
79 return node != nullptr ? node->findRootArc() : nullSuperArc;
80 }
81
82 idSuperArc getCorArc(const std::size_t nid) const {
83 return getNode(nid)->getCorArc();
84 }
85
86 // check whether or not this node is connected to others
87 bool isDisconnected(const DynGraphNode<Type> *const node) const {
88 return !node->hasParent();
89 }
90
91 // check whether or not this node is connected to others
92 bool isDisconnected(const std::size_t nid) {
93 return !getNode(nid)->hasParent();
94 }
95
98 return node->findRoot();
99 }
100
102 DynGraphNode<Type> *findRoot(const std::size_t nid) {
103 return findRoot(getNode(nid));
104 }
105
108 std::vector<DynGraphNode<Type> *>
109 findRoot(std::initializer_list<DynGraphNode<Type> *> nodes) {
110 std::vector<DynGraphNode<Type> *> roots;
111 roots.reserve(nodes.size());
112 for(auto *n : nodes) {
113 roots.emplace_back(findRoot(n));
114 }
115 std::sort(roots.begin(), roots.end());
116 const auto it = std::unique(roots.begin(), roots.end());
117 roots.erase(it, roots.end());
118 return roots;
119 }
120
122 std::vector<DynGraphNode<Type> *>
123 findRoot(std::initializer_list<std::size_t> nodesIds) {
124 std::vector<DynGraphNode<Type> *> roots;
125 roots.reserve(nodesIds.size());
126 for(auto n : nodesIds) {
127 roots.emplace_back(findRoot(n));
128 }
129 std::sort(roots.begin(), roots.end());
130 const auto it = std::unique(roots.begin(), roots.end());
131 roots.erase(it, roots.end());
132 return roots;
133 }
134
136 template <typename type>
137 std::set<DynGraphNode<Type> *>
138 findRoot(const std::vector<type> &nodesIds) {
139
140 std::set<DynGraphNode<Type> *> roots;
141 for(auto n : nodesIds) {
142 roots.emplace(findRoot(n));
143 }
144 return roots;
145 }
146
150 DynGraphNode<Type> *const n2,
151 const Type w,
152 const idSuperArc corArc) {
153 return n1->insertEdge(n2, w, corArc);
154 }
155
157 bool insertEdge(const std::size_t n1,
158 const std::size_t n2,
159 const Type w,
160 const idSuperArc corArc) {
161 return insertEdge(getNode(n1), getNode(n2), w, corArc);
162 }
163
166 n->removeEdge();
167 }
168
170 void removeEdge(const std::size_t nid) {
171 removeEdge(getNode(nid));
172 }
173
176 int removeEdge(DynGraphNode<Type> *const n1,
177 DynGraphNode<Type> *const n2);
178
181 int removeEdge(const std::size_t nid1, const std::size_t nid2) {
182 return removeEdge(getNode(nid1), getNode(nid2));
183 }
184
185 // Debug
186
187 std::string print();
188
189 std::string print(const std::function<std::string(std::size_t)> &);
190
191 std::string printNbCC();
192
193 void test();
194 };
195
196 // Same as dynamic graph but keep the number of subtrees at any time
197 // CAREFUL: this number is not protected for parallel modification, and
198 // this class is not made for parallel access.
199 template <typename Type>
200 class LocalForest : public DynamicGraph<Type> {
201 std::size_t nbCC_;
203
204 public:
205 LocalForest() : super(), nbCC_{0} {
206 }
207
208 void setNumberOfNodes(const std::size_t nbNodes) {
210 nbCC_ = nbNodes;
211 }
212
213 void setNbCC(const std::size_t nb) {
214 // usefull if the forest is willingly larger than the real number of
215 // nodes
216 nbCC_ = nb;
217 }
218
219 void reset() {
220 for(auto &node : this->nodes_) {
221 node.parent_ = nullptr;
222 node.weight_ = 0;
223 std::ignore = node;
224 }
225 nbCC_ = this->nodes_.size();
226 }
227
231 DynGraphNode<Type> *const n2,
232 const Type w,
233 const idSuperArc corArc) {
234 bool connect = super::insertEdge(n1, n2, w, corArc);
235 if(connect)
236 --nbCC_;
237 return connect;
238 }
239
241 bool insertEdge(const std::size_t n1,
242 const std::size_t n2,
243 const Type w,
244 const idSuperArc corArc) {
245 bool connect = super::insertEdge(n1, n2, w, corArc);
246 if(connect)
247 --nbCC_;
248 return connect;
249 }
250
254 ++nbCC_;
255 }
256
258 void removeEdge(const std::size_t nid) {
260 ++nbCC_;
261 }
262
266 DynGraphNode<Type> *const n2) {
267 int ret = super::removeEdge(n1, n2);
268 if(ret)
269 ++nbCC_;
270 return ret;
271 }
272
275 int removeEdge(const std::size_t nid1, const std::size_t nid2) {
276 int ret = super::removeEdge(nid1, nid2);
277 if(ret)
278 ++nbCC_;
279 return ret;
280 }
281
283 std::size_t getNbCC() const {
284 return nbCC_;
285 }
286 };
287
290 template <typename Type>
294
296
297 explicit DynGraphNode()
298 : parent_(nullptr), weight_(0), corArc_(nullSuperArc) {
299 }
300
302 operator=(other);
303 }
304
306 if(this != &other) {
307 parent_ = other.parent_;
308 weight_ = other.weight_;
309 }
310 return *this;
311 }
312
313 // Accessor functions
314 // ------------------
315
316 Type getWeight() const {
317 return weight_;
318 }
319
320 bool hasParent() const {
321 return parent_;
322 }
323
324 // Graph functions
325 // ---------------
326
328 // Various way to do that, test perfs ?
329 void evert();
330
332 DynGraphNode *findRoot() const;
333
336 idSuperArc findRootArc() const;
337
340 idSuperArc corArc;
341#ifdef TTK_ENABLE_OPENMP
342#pragma omp atomic read
343#endif
344 corArc = corArc_;
345 return corArc;
346 }
347
348 void setRootArc(const idSuperArc arcId);
349
353 std::tuple<DynGraphNode<Type> *, DynGraphNode<Type> *>
354 findMinWeightRoot() const;
355
359 bool insertEdge(DynGraphNode *const n,
360 const Type weight,
361 const idSuperArc corArc);
362
365 void removeEdge();
366 };
367 } // namespace ftr
368} // namespace ttk
369
void setNumberOfElmt(const idVertex nbVerts)
Definition FTRCommon.h:53
TTK fTRGraph dynamic graph tracking the evolution of level sets.
void removeEdge(DynGraphNode< Type > *const n)
remove the link btwn n and its parent
std::set< DynGraphNode< Type > * > findRoot(const std::vector< type > &nodesIds)
findRoot but using ids of the nodes in a vector
std::vector< DynGraphNode< Type > * > findRoot(std::initializer_list< DynGraphNode< Type > * > nodes)
recover the root of several nodes once, using brace initializers style: findRoot({n1,...
void removeEdge(const std::size_t nid)
remove the link btwn n and its parent
void setSubtreeArc(const std::size_t nid, const idSuperArc arc)
std::vector< DynGraphNode< Type > * > findRoot(std::initializer_list< std::size_t > nodesIds)
findRoot but using ids of the nodes
idSuperArc getCorArc(const std::size_t nid) const
void setNumberOfNodes(const std::size_t nbNodes)
int removeEdge(const std::size_t nid1, const std::size_t nid2)
DynGraphNode< Type > * findRoot(const std::size_t nid)
recover the root of a node using its id
DynGraphNode< Type > * findRoot(const DynGraphNode< Type > *const node)
recover the root of a node
std::vector< DynGraphNode< Type > > nodes_
void setCorArc(const std::size_t nid, idSuperArc arc)
idSuperArc getSubtreeArc(const std::size_t nid) const
bool isDisconnected(const DynGraphNode< Type > *const node) const
bool insertEdge(DynGraphNode< Type > *const n1, DynGraphNode< Type > *const n2, const Type w, const idSuperArc corArc)
DynGraphNode< Type > * getNode(const std::size_t nid)
get the node with the id: nid
bool isDisconnected(const std::size_t nid)
const DynGraphNode< Type > * getNode(const std::size_t nid) const
bool insertEdge(const std::size_t n1, const std::size_t n2, const Type w, const idSuperArc corArc)
inert or replace existing edge between n1 and n2
std::size_t getNodeId(DynGraphNode< Type > *node)
get the id of the node: node
std::size_t getNbCC() const
count the number of connected component in a list of nodes
bool insertEdge(const std::size_t n1, const std::size_t n2, const Type w, const idSuperArc corArc)
inert or replace existing edge between n1 and n2
bool insertEdge(DynGraphNode< Type > *const n1, DynGraphNode< Type > *const n2, const Type w, const idSuperArc corArc)
void setNbCC(const std::size_t nb)
void setNumberOfNodes(const std::size_t nbNodes)
void removeEdge(DynGraphNode< Type > *const n)
remove the link btwn n and its parent
void removeEdge(const std::size_t nid)
remove the link btwn n and its parent
int removeEdge(const std::size_t nid1, const std::size_t nid2)
int removeEdge(DynGraphNode< Type > *const n1, DynGraphNode< Type > *const n2)
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)
idSuperArc getCorArc() const
Get the arcs corresponding to this subtree.
DynGraphNode & operator=(const DynGraphNode &other)
DynGraphNode(const DynGraphNode &other)