-
Notifications
You must be signed in to change notification settings - Fork 13
/
Copy pathitkGraph.h
executable file
·321 lines (278 loc) · 11.7 KB
/
itkGraph.h
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
/*=========================================================================
Program: Insight Segmentation & Registration Toolkit
Module: $RCSfile: itkGraph.h,v $
Language: C++
Date: $Date: 2008/11/11 03:08:24 $
Version: $Revision: 1.2 $
Copyright (c) Insight Software Consortium. All rights reserved.
See ITKCopyright.txt or http://www.itk.org/HTML/Copyright.htm for details.
Portions of this code are covered under the VTK copyright.
See VTKCopyright.txt or http://www.kitware.com/VTKCopyright.htm for details.
This software is distributed WITHOUT ANY WARRANTY; without even
the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
PURPOSE. See the above copyright notices for more information.
=========================================================================*/
#ifndef __itkGraph_h
#define __itkGraph_h
#include "itkDataObject.h"
#include "itkObjectFactory.h"
#include "itkVectorContainer.h"
namespace itk
{
/** \class Graph
* \brief Basic graph class.
*
* \par
* Directional graph class which has basic functionality. It is
* templated over TGraphTraits which contain the definitions for
* nodes and edges (see itkDefaultGraphTraits.h for the basic
* concept). This class maintains two container types - one for
* the nodes and one for the edges. It also defines two basic
* iterator classes which are simply interfaces to the iterator
* types already defined for the container type.
*
* \ingroup GraphObjects
* \ingroup DataRepresentation
*/
template <typename TGraphTraits>
class ITK_EXPORT Graph : public DataObject
{
public:
/** Standard class typedefs. */
typedef Graph Self;
typedef DataObject Superclass;
typedef SmartPointer<Self> Pointer;
typedef SmartPointer<const Self> ConstPointer;
/** Method for creation through the object factory. */
itkNewMacro( Self );
/** Standard part of every itk Object. */
itkTypeMacro( Graph, DataObject );
/** Hold on to the type information specified by the template parameters. */
typedef TGraphTraits GraphTraitsType;
typedef typename GraphTraitsType::NodeType NodeType;
typedef typename GraphTraitsType::EdgeType EdgeType;
typedef typename GraphTraitsType::NodePointerType NodePointerType;
typedef typename GraphTraitsType::EdgePointerType EdgePointerType;
typedef typename GraphTraitsType::NodeIdentifierType NodeIdentifierType;
typedef typename GraphTraitsType::EdgeIdentifierType EdgeIdentifierType;
typedef typename GraphTraitsType::NodeWeightType NodeWeightType;
typedef typename GraphTraitsType::EdgeWeightType EdgeWeightType;
typedef typename GraphTraitsType::EdgeIdentifierContainerType
EdgeIdentifierContainerType;
typedef VectorContainer<unsigned, NodeType> NodeContainerType;
typedef typename NodeContainerType::Iterator NodeIteratorType;
typedef typename NodeContainerType::ConstIterator NodeConstIteratorType;
typedef VectorContainer<unsigned, EdgeType> EdgeContainerType;
typedef typename EdgeContainerType::Iterator EdgeIteratorType;
typedef typename EdgeContainerType::ConstIterator EdgeConstIteratorType;
/** Return the total number of nodes. */
unsigned int GetTotalNumberOfNodes()
{ return m_Nodes->Size(); }
/** Return the total number of edges. */
unsigned int GetTotalNumberOfEdges()
{ return m_Edges->Size(); }
/** Clear the graph */
void Clear();
/** Create new nodes */
NodePointerType CreateNewNode();
NodePointerType CreateNewNode( NodeWeightType );
/** Create new edges */
EdgePointerType CreateNewEdge();
EdgePointerType CreateNewEdge( NodeIdentifierType, NodeIdentifierType );
EdgePointerType CreateNewEdge(
NodeIdentifierType, NodeIdentifierType, EdgeWeightType);
EdgePointerType CreateNewEdge( NodePointerType SourceNode,
NodePointerType TargetNode )
{
return this->CreateNewEdge(
SourceNode->Identifier, TargetNode->Identifier );
};
EdgePointerType CreateNewEdge( NodePointerType SourceNode,
NodePointerType TargetNode, EdgeWeightType w )
{
return this->CreateNewEdge(
SourceNode->Identifier, TargetNode->Identifier, w );
};
EdgePointerType CreateNewEdge( NodeType SourceNode, NodeType TargetNode)
{
return this->CreateNewEdge( SourceNode.Identifier, TargetNode.Identifier);
};
EdgePointerType CreateNewEdge(
NodeType SourceNode, NodeType TargetNode, EdgeWeightType w )
{
return this->CreateNewEdge(
SourceNode.Identifier, TargetNode.Identifier, w );
};
/** Graph utility functions */
/** Get Nodes/Edges */
NodeType& GetNode( NodeIdentifierType Id )
{ return m_Nodes->ElementAt( Id ); }
EdgeType& GetEdge( EdgeIdentifierType Id )
{ return m_Edges->ElementAt( Id ); }
EdgeType& GetReverseEdge( EdgeIdentifierType );
NodeType& GetSourceNode( EdgePointerType Edge )
{ return this->GetNode( Edge->SourceIdentifier ); }
NodeType& GetSourceNode( EdgeType Edge )
{ return this->GetNode( Edge.SourceIdentifier ); }
NodeType& GetSourceNode( EdgeIdentifierType Id )
{ return this->GetSourceNode( this->GetEdgePointer( Id ) ); }
NodeType& GetTargetNode( EdgePointerType Edge )
{ return this->GetNode( Edge->TargetIdentifier ); }
NodeType& GetTargetNode( EdgeType Edge )
{ return this->GetNode( Edge.TargetIdentifier ); }
NodeType& GetTargetNode( EdgeIdentifierType Id )
{ return this->GetTargetNode( this->GetEdgePointer( Id ) ); }
EdgeType& GetEdge( NodeIdentifierType, NodeIdentifierType );
NodePointerType GetNodePointer( NodeIdentifierType Id )
{ return &m_Nodes->ElementAt( Id ); }
EdgePointerType GetEdgePointer( EdgeIdentifierType Id )
{ return &m_Edges->ElementAt( Id ); }
EdgePointerType GetReverseEdgePointer( EdgeIdentifierType );
EdgePointerType GetReverseEdgePointer( EdgePointerType );
NodePointerType GetSourceNodePointer( EdgePointerType Edge )
{ return this->GetNodePointer( Edge->SourceIdentifier ); }
NodePointerType GetSourceNodePointer( EdgeIdentifierType Id )
{ return this->GetSourceNodePointer( this->GetEdgePointer( Id ) ); }
NodePointerType GetTargetNodePointer( EdgePointerType Edge )
{ return this->GetNodePointer( Edge->TargetIdentifier ); }
NodePointerType GetTargetNodePointer( EdgeIdentifierType Id )
{ return this->GetTargetNodePointer( this->GetEdgePointer( Id ) ); }
EdgePointerType GetEdgePointer( NodeIdentifierType, NodeIdentifierType );
EdgePointerType GetEdgePointer( NodePointerType, NodePointerType );
/** Get Node/Edge Identifiers */
NodeIdentifierType GetNodeIdentifier( NodePointerType node )
{ return node->Identifier; }
EdgeIdentifierType GetEdgeIdentifier( EdgePointerType edge )
{ return edge->Identifier; }
NodeIdentifierType GetNodeIdentifier( NodeType node )
{ return node.Identifier; }
EdgeIdentifierType GetEdgeIdentifier( EdgeType edge )
{ return edge.Identifier; }
/** Get/Set/Add Node/Edge weights */
NodeWeightType GetNodeWeight( NodePointerType Node )
{ return Node->Weight; }
EdgeWeightType GetEdgeWeight( EdgePointerType Edge )
{ return Edge->Weight; }
NodeWeightType GetNodeWeight( NodeType Node )
{ return Node.Weight; }
EdgeWeightType GetEdgeWeight( EdgeType Edge )
{ return Edge.Weight; }
NodeWeightType GetNodeWeight( NodeIdentifierType Id )
{ return this->GetNodePointer( Id )->Weight; }
EdgeWeightType GetEdgeWeight( EdgeIdentifierType Id )
{ return this->GetEdgePointer( Id )->Weight; }
void SetNodeWeight( NodePointerType Node, NodeWeightType w )
{ Node->Weight = w; }
void SetEdgeWeight( EdgePointerType Edge, EdgeWeightType w )
{ Edge->Weight = w; }
void SetNodeWeight( NodeType Node, NodeWeightType w )
{ Node.Weight = w; }
void SetEdgeWeight( EdgeType Edge, EdgeWeightType w )
{ Edge.Weight = w; }
void SetNodeWeight( NodeIdentifierType Id, NodeWeightType w )
{ this->GetNodePointer( Id )->Weight = w; }
void SetEdgeWeight( EdgeIdentifierType Id, EdgeWeightType w )
{ this->GetEdgePointer( Id )->Weight = w; }
void AddNodeWeight( NodePointerType Node, NodeWeightType w )
{ Node->Weight += w; }
void AddEdgeWeight( EdgePointerType Edge, EdgeWeightType w )
{ Edge->Weight += w; }
void AddNodeWeight( NodeType Node, NodeWeightType w )
{ Node.Weight += w; }
void AddEdgeWeight( EdgeType Edge, EdgeWeightType w )
{ Edge.Weight += w; }
void AddNodeWeight( NodeIdentifierType Id, NodeWeightType w )
{ this->GetNodePointer( Id )->Weight += w; }
void AddEdgeWeight( EdgeIdentifierType Id, EdgeWeightType w )
{ this->GetEdgePointer( Id )->Weight += w; }
/** Get edges to adjacent nodes */
EdgeIdentifierContainerType GetOutgoingEdges( NodePointerType Node )
{ return Node->OutgoingEdges; }
EdgeIdentifierContainerType GetIncomingEdges( NodePointerType Node )
{ return Node->IncomingEdges; }
/**
* After creating all the edges, this function associates each
* edge with it's reverse edge ( if it exists ).
*/
virtual void SetAllReverseEdges();
void ChangeNodeWeight( NodeIdentifierType Id, NodeWeightType W )
{ this->GetNodePointer( Id )->Weight = W; }
void ChangeEdgeWeight( EdgeIdentifierType Id, EdgeWeightType W )
{ this->GetEdgePointer( Id )->Weight = W; }
NodeContainerType* GetNodeContainer()
{ return this->m_Nodes.GetPointer(); }
const NodeContainerType* GetNodeContainer() const
{ return this->m_Nodes.GetPointer(); }
void SetNodeContainer( NodeContainerType * );
EdgeContainerType* GetEdgeContainer()
{ return this->m_Edges.GetPointer(); }
const EdgeContainerType* GetEdgeContainer() const
{ return this->m_Edges.GetPointer(); }
void SetEdgeContainer( EdgeContainerType * );
void Graft( const Self * );
/**
* Define the node/edge iterators which are simple
* wrappers for existing iterators of the wrapper
* class.
*/
friend class NodeIterator;
friend class EdgeIterator;
class NodeIterator
{
public:
NodeIterator( Graph* graph ) { this->m_Graph = graph; }
~NodeIterator() {}
/** Iterator-related functions */
void GoToBegin(void)
{ this->m_NodeIterator = this->m_Graph->m_Nodes->Begin(); }
bool IsAtEnd(void)
{ return ( this->m_NodeIterator == this->m_Graph->m_Nodes->End() ); }
void operator++()
{ m_NodeIterator++; }
NodePointerType GetPointer( void )
{ return &this->m_NodeIterator.Value(); }
NodeType& Get( void )
{ return this->m_NodeIterator.Value(); }
unsigned long GetIdentifier( void )
{ return this->m_NodeIterator.Index(); }
private:
Graph* m_Graph;
NodeIteratorType m_NodeIterator;
};
class EdgeIterator
{
public:
EdgeIterator( Graph* graph ) { this->m_Graph = graph; }
~EdgeIterator() {}
/** Iterator-related functions */
void GoToBegin( void )
{ this->m_EdgeIterator = this->m_Graph->m_Edges->Begin(); }
bool IsAtEnd( void )
{ return ( this->m_EdgeIterator == this->m_Graph->m_Edges->End() ); }
void operator++() { m_EdgeIterator++; }
EdgePointerType GetPointer(void)
{ return &this->m_EdgeIterator.Value(); }
EdgeType& Get( void )
{ return this->m_EdgeIterator.Value(); }
unsigned long GetIdentifier( void )
{ return this->m_EdgeIterator.Index(); }
private:
Graph* m_Graph;
EdgeIteratorType m_EdgeIterator;
};
protected:
/** Constructor for use by New() method. */
Graph();
~Graph();
virtual void PrintSelf( std::ostream& os, Indent indent ) const;
private:
Graph( const Self& ); //purposely not implemented
void operator=( const Self& ); //purposely not implemented
typename EdgeContainerType::Pointer m_Edges;
typename NodeContainerType::Pointer m_Nodes;
}; // End Class: Graph
} // end namespace itk
#ifndef ITK_MANUAL_INSTANTIATION
#include "itkGraph.hxx"
#endif
#endif