Graph C++ Library
 All Classes Namespaces Files Functions Variables Typedefs Groups Pages
base_undirected_graph.hpp
Go to the documentation of this file.
1 
10 #ifndef BASE_UNDIRECTED_GRAPH_HPP_INCLUDED
11 #define BASE_UNDIRECTED_GRAPH_HPP_INCLUDED
12 
13 // Standard Library
14 #include <algorithm> // set_intersection
15 #include <cstdlib> // abort
16 #include <iostream>
17 #include <list>
18 #include <set>
19 #include <string>
20 #include <vector>
21 // Graph C++ Library
22 #include "base_graph.hpp"
23 
25 namespace gcl
26 {
27 
36  template <class VertexType>
37  class base_undirected_graph : public gcl::base_graph<VertexType>
38  {
39  // ============================================================================================
40  // *** Objects related to the graph.
41  private:
42  const unsigned int id_degree;
43  // ============================================================================================
44  // *** Information about the graph.
45  private:
46  unsigned int nb_wedges;
47  unsigned int nb_triangles;
48  double global_clustering_coefficient;
49  double avg_local_clustering_coefficient;
50  std::list< std::vector<unsigned int> > triangles;
51  // ============================================================================================
52  // *** Member functions.
53  public:
55  virtual ~base_undirected_graph() {}
56  unsigned int get_min_degree();
57  unsigned int get_max_degree();
58  double get_avg_degree();
59  unsigned int get_nb_triangles();
60  unsigned int get_nb_wedges();
63  void write_edgelist(std::string _name);
64  // void analyse_structural_properties(); ///< Computes a set of structural properties.
65  void survey_triangles();
67  virtual void write_graph_properties(std::string _name) = 0;
68  virtual void write_vertices_properties(std::string _name) = 0;
69  protected:
71  };
72 
73 } // End of namespace gcl.
74 
75 // Il faudrait faire un wrap up de survey_degrees_distribution pour avoir une forme au singulier.
76 
77 
78 // ================================================================================================
79 // ================================================================================================
80 template <class VertexType>
82 
83 // ================================================================================================
84 // ================================================================================================
85 template <class VertexType>
87 {
88  return this->get_base_graph_min_degrees(id_degree);
89 }
90 
91 // ================================================================================================
92 // ================================================================================================
93 template <class VertexType>
95 {
96  return this->get_base_graph_max_degrees(id_degree);
97 }
98 
99 // ================================================================================================
100 // ================================================================================================
101 template <class VertexType>
103 {
104  return this->get_base_graph_avg_degrees(id_degree);
105 }
106 
107 // ================================================================================================
108 // ================================================================================================
109 template <class VertexType>
111 {
112  return nb_triangles;
113 }
114 
115 // ================================================================================================
116 // ================================================================================================
117 template <class VertexType>
119 {
120  return nb_wedges;
121 }
122 
123 // ================================================================================================
124 // ================================================================================================
125 template <class VertexType>
127 {
128  return global_clustering_coefficient;
129 }
130 
131 // ================================================================================================
132 // ================================================================================================
133 template <class VertexType>
135 {
136  return avg_local_clustering_coefficient;
137 }
138 
139 // ================================================================================================
140 // ================================================================================================
141 template <class VertexType>
143 {
144  // Stream objects.
145  std::ofstream edgelist_file;
146  // String objects.
147  std::string edgelist_filename = _name + "_edgelist.dat";
148  std::string node1_str;
149  // Operator objects.
150  typename VertexType::iterator it, end;
151  // Opens the stream and aborts if the operation did not succeed.
152  edgelist_file.open(edgelist_filename.c_str(), std::ios_base::out);
153  if( !edgelist_file.is_open() )
154  {
155  std::cout << "Could not open file: " << edgelist_filename << "." << std::endl;
156  abort();
157  }
158  // Writes each edges in the format "node1 node2". Each edge appears once.
159  for(unsigned int node1(0), node2, nn(this->get_nb_vertices()); node1<nn; ++node1)
160  {
161  // Browses the neighbours of node1.
162  it = (*this)(node1)->neighbour_begin();
163  end = (*this)(node1)->neighbour_end();
164  node1_str = (*this)(node1)->get_name();
165  for(; it!=end; ++it)
166  {
167  node2 = it->id;
168  if(node1 < node2) // Ensures that undirected edges appear only once (excludes self-edges).
169  {
170  edgelist_file << node1_str << " " << (*this)(node2)->get_name() << std::endl;
171  }
172  }
173  }
174  // Closes the stream.
175  edgelist_file.close();
176 }
177 
178 // // ================================================================================================
179 // // ================================================================================================
180 // template <class VertexType>
181 // void gcl::base_undirected_graph<VertexType>::analyse_structural_properties()
182 // {
183 // // Degree distributions.
184 // this->survey_degrees_distribution();
185 // // Identifies the triangles.
186 // survey_triangles();
187 // // Computes the clustering coefficients.
188 // compute_clustering_coefficients();
189 // }
190 
191 // ================================================================================================
192 // ================================================================================================
193 template <class VertexType>
195 {
196  // Vector objects.
197  std::vector<unsigned int> intersection;
198  // Set objects.
199  std::set<unsigned int> neighbours_v1, neighbours_v2;
200  // Iterator objects.
201  std::vector<unsigned int>::iterator it;
202  typename VertexType::iterator it1, end1, it2, end2;
203  // Computes the intersection for the in- and out- neighbourhoods of each node.
204  for(unsigned int v1(0), v2, v3, d1, d2, nn(this->get_nb_vertices()); v1<nn; ++v1)
205  {
206  // Degree of vertex v1.
207  d1 = (*this)(v1)->get_degree();
208  // Performs the calculation only if d1>1.
209  if( d1 > 1 )
210  {
211  // Builds an ordered list of the neighbourhood of v1
212  it1 = (*this)(v1)->neighbour_begin();
213  end1 = (*this)(v1)->neighbour_end();
214  neighbours_v1.clear();
215  for(; it1 != end1; ++it1)
216  {
217  neighbours_v1.insert(it1->id);
218  }
219  it1 = (*this)(v1)->neighbour_begin();
220  // Loops over the neighbours of vertex v1.
221  for(; it1!=end1; ++it1)
222  {
223  // Identity and degree of vertex 2.
224  v2 = it1->id;
225  d2 = (*this)(v2)->get_degree();
226  // Performs the calculation only if d1>1 and if v2>v1 (ensures that each triangle is counted once).
227  if( v2 > v1 && d2 > 1 )
228  {
229  // Builds an ordered list of the neighbourhood of v2
230  it2 = (*this)(v2)->neighbour_begin();
231  end2 = (*this)(v2)->neighbour_end();
232  neighbours_v2.clear();
233  for(; it2 != end2; ++it2)
234  {
235  v3 = it2->id;
236  if(v3 > v2) // Ensures that triangles will be counted only once.
237  {
238  neighbours_v2.insert(v3);
239  }
240  }
241  d2 = neighbours_v2.size();
242  // Identifies the triangles.
243  intersection.clear();
244  intersection.resize(std::min(d1,d2));
245  it = std::set_intersection(neighbours_v1.begin(), neighbours_v1.end(), neighbours_v2.begin(), neighbours_v2.end(), intersection.begin());
246  intersection.resize(it-intersection.begin());
247  // Loops over the common neighbours of vertices v1 and v2.
248  for(unsigned int n(0), nn(intersection.size()); n<nn; ++n)
249  {
250  // Identity and degree of vertex 2.
251  v3 = intersection[n];
252  // Considers the triangle only if v1 is the lowest index (ensures that each triangle is counted once).
253  // if(v3 > v1)
254  {
255  // Adds the triangle to the list.
256  triangles.push_back({v1,v2,v3});
257  }
258  }
259  }
260  }
261  }
262  }
263 }
264 
265 // ================================================================================================
266 // ================================================================================================
267 template <class VertexType>
269 {
270  // Sets the local clustering coefficients.
271  unsigned int v1, v2, v3;
272  std::list< std::vector<unsigned int> >::iterator it = triangles.begin();
273  std::list< std::vector<unsigned int> >::iterator end = triangles.end();
274  for(unsigned int v; it != end; ++it)
275  {
276  // Loops over the three vertices in the triangle.
277  for(unsigned int i(0); i<3; ++i)
278  {
279  v = (*it)[i];
280  (*this)(v)->set_nb_triangles((*this)(v)->get_nb_triangles() + 1);
281  }
282  }
283  // Counts the number of wedges and computes the average local clustering coefficient.
284  for(unsigned int n(0), d, nn(this->get_nb_vertices()); n<nn; ++n)
285  {
286  // Number of wedges.
287  d = (*this)(n)->get_degree();
288  nb_wedges += d * ( d - 1. ) / 2.;
289  // Local clustering coefficient.
290  avg_local_clustering_coefficient += (*this)(n)->get_local_clustering_coefficient();
291  }
292  avg_local_clustering_coefficient /= this->get_nb_vertices();
293  // Counts the number of triangles.
294  nb_triangles = triangles.size();
295  // Sets the global clustering coefficient.
296  global_clustering_coefficient = 3. * nb_triangles / nb_wedges;
297 }
298 
299 // ================================================================================================
300 // ================================================================================================
301 template <class VertexType>
303 {
304  // Resets the number of types of vertices.
305  this->set_nb_of_types_of_degrees(1);
306  // Resets the variables inherited from base_graph.
307  this->base_graph_clear();
308  // Resets the quatities related to the clustering.
309  nb_wedges = 0;
310  nb_triangles = 0;
311  global_clustering_coefficient = 0;
312  avg_local_clustering_coefficient = 0;
313  triangles.clear();
314 }
315 
316 
317 
318 #endif // BASE_UNDIRECTED_GRAPH_HPP_INCLUDED
double get_avg_degree()
Returns the average degree found in the graph.
Definition: base_undirected_graph.hpp:102
virtual ~base_undirected_graph()
Destructor.
Definition: base_undirected_graph.hpp:55
unsigned int get_nb_wedges()
Returns the number of wegdes in the graph.
Definition: base_undirected_graph.hpp:118
double get_avg_local_clustering_coefficient()
Returns the average value of the local clustering coefficients.
Definition: base_undirected_graph.hpp:134
base_undirected_graph()
Constructor.
Definition: base_undirected_graph.hpp:81
void write_edgelist(std::string _name)
Exports the directed graph to an edgelist.
Definition: base_undirected_graph.hpp:142
void base_undirected_graph_clear()
Reinitializes the graph (inherited variables).
Definition: base_undirected_graph.hpp:302
unsigned int get_nb_triangles()
Returns the number of triangles in the graph.
Definition: base_undirected_graph.hpp:110
Virtual template base class for undirected graph objects.
Definition: base_undirected_graph.hpp:37
void survey_triangles()
Creates a list of the triangles in the graph.
Definition: base_undirected_graph.hpp:194
unsigned int get_min_degree()
Returns the minimal degree found in the graph.
Definition: base_undirected_graph.hpp:86
Virtual template base class for graph objects.
Definition: base_graph.hpp:33
virtual void write_graph_properties(std::string _name)=0
Exports the graph's properties.
double get_global_clustering_coefficient()
Returns the global clustering coefficient (3 x [number of triangles] / [number of wedges])...
Definition: base_undirected_graph.hpp:126
virtual void write_vertices_properties(std::string _name)=0
Exports the vertices' properties.
void compute_clustering_coefficients()
Computes the clustering coefficients (individual and global).
Definition: base_undirected_graph.hpp:268
unsigned int get_max_degree()
Returns the maximal degree found in the graph.
Definition: base_undirected_graph.hpp:94
Virtual base class for graphs.