Graph C++ Library
 All Classes Namespaces Files Functions Variables Typedefs Groups Pages
base_directed_graph.hpp
Go to the documentation of this file.
1 
10 #ifndef BASE_DIRECTED_GRAPH_HPP_INCLUDED
11 #define BASE_DIRECTED_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_directed_graph : public gcl::base_graph<VertexType>
38  {
39  // ============================================================================================
40  // *** Objects related to the graph.
41  protected:
42  // const unsigned int nb_degree_types; ///< Numbers of different degree types (in this case 2)
43  const unsigned int id_out_degree;
44  const unsigned int id_in_degree;
45  // ============================================================================================
46  // *** Information about the graph.
47  private:
48  double reciprocity;
49  unsigned int nb_reciprocal_edges;
50  std::list< std::vector<unsigned int> > triangles;
51  // Quantities related to the undirected projection of the graph (regardless of the direction of the edges).
52  unsigned int nb_undirected_projection_wedges;
53  unsigned int nb_undirected_projection_triangles;
54  double global_undirected_projection_clustering_coefficient;
55  double avg_local_undirected_projection_clustering_coefficient;
56  // ============================================================================================
57  // *** Status of the properties computed.
58  private:
59  bool has_triangles_been_surveyed;
60  bool has_nb_reciprocal_edges_been_computed;
61  bool have_undirected_projection_clustering_coefficients_been_computed;
62  // ============================================================================================
63  // *** Member functions.
64  public:
66  virtual ~base_directed_graph() {}
67  unsigned int get_nb_reciprocal_edges();
68  double get_reciprocity();
73  unsigned int get_min_in_degree();
74  unsigned int get_max_in_degree();
75  double get_avg_in_degree();
76  unsigned int get_min_out_degree();
77  unsigned int get_max_out_degree();
78  double get_avg_out_degree();
79  void survey_triangles();
80  void write_edgelist(std::string _name);
81  // void analyse_structural_properties(); ///< Computes a set of structural properties.
84  virtual void write_graph_properties(std::string _name) = 0;
85  virtual void write_vertices_properties(std::string _name) = 0;
86  protected:
88  };
89 
90 } // End of namespace gcl.
91 
92 
93 
94 // ================================================================================================
95 // ================================================================================================
96 template <class VertexType>
98 : /*nb_degree_types(2),*/ id_out_degree(0), id_in_degree(1) { }
99 
100 // ================================================================================================
101 // ================================================================================================
102 template <class VertexType>
104 {
105  return nb_reciprocal_edges;
106 }
107 
108 // ================================================================================================
109 // ================================================================================================
110 template <class VertexType>
112 {
113  return reciprocity;
114 }
115 
116 // ================================================================================================
117 // ================================================================================================
118 template <class VertexType>
120 {
121  return this->get_base_graph_min_degrees(id_in_degree);
122 }
123 
124 // ================================================================================================
125 // ================================================================================================
126 template <class VertexType>
128 {
129  return this->get_base_graph_max_degrees(id_in_degree);
130 }
131 
132 // ================================================================================================
133 // ================================================================================================
134 template <class VertexType>
136 {
137  return this->get_base_graph_avg_degrees(id_in_degree);
138 }
139 
140 // ================================================================================================
141 // ================================================================================================
142 template <class VertexType>
144 {
145  return this->get_base_graph_min_degrees(id_out_degree);
146 }
147 
148 // ================================================================================================
149 // ================================================================================================
150 template <class VertexType>
152 {
153  return this->get_base_graph_max_degrees(id_out_degree);
154 }
155 
156 // ================================================================================================
157 // ================================================================================================
158 template <class VertexType>
160 {
161  return this->get_base_graph_avg_degrees(id_out_degree);
162 }
163 
164 // ================================================================================================
165 // ================================================================================================
166 template <class VertexType>
168 {
169  return nb_undirected_projection_triangles;
170 }
171 
172 // ================================================================================================
173 // ================================================================================================
174 template <class VertexType>
176 {
177  return nb_undirected_projection_wedges;
178 }
179 
180 // ================================================================================================
181 // ================================================================================================
182 template <class VertexType>
184 {
185  return global_undirected_projection_clustering_coefficient;
186 }
187 
188 // ================================================================================================
189 // ================================================================================================
190 template <class VertexType>
192 {
193  return avg_local_undirected_projection_clustering_coefficient;
194 }
195 
196 // ================================================================================================
197 // ================================================================================================
198 template <class VertexType>
200 {
201  // Stream objects.
202  std::ofstream edgelist_file;
203  // String objects.
204  std::string edgelist_filename = _name + "_edgelist.dat";
205  std::string node1_str;
206  // Operator objects.
207  typename VertexType::iterator it, end;
208  // Opens the stream and aborts if the operation did not succeed.
209  edgelist_file.open(edgelist_filename.c_str(), std::ios_base::out);
210  if( !edgelist_file.is_open() )
211  {
212  std::cout << "Could not open file: " << edgelist_filename << "." << std::endl;
213  abort();
214  }
215  // Writes each edges in the format "node1 node2". Each edge appears once.
216  for(unsigned int node1(0), node2, nn(this->get_nb_vertices()); node1<nn; ++node1)
217  {
218  // Browses the out neighbours of node1.
219  it = (*this)(node1)->out_neighbour_begin();
220  end = (*this)(node1)->out_neighbour_end();
221  node1_str = (*this)(node1)->get_name();
222  for(; it!=end; ++it)
223  {
224  node2 = it->id;
225  edgelist_file << node1_str << " " << (*this)(node2)->get_name() << std::endl;
226  }
227  }
228  // Closes the stream.
229  edgelist_file.close();
230 }
231 
232 // // ================================================================================================
233 // // ================================================================================================
234 // template <class VertexType>
235 // void gcl::base_directed_graph<VertexType>::analyse_structural_properties()
236 // {
237 // // Degree distributions.
238 // this->survey_degrees_distribution();
239 // // Number of reciprocal edges.
240 // compute_nb_reciprocal_edges();
241 // }
242 
243 // ================================================================================================
244 // ================================================================================================
245 template <class VertexType>
247 {
248  // Vector objects.
249  std::vector<unsigned int> intersection;
250  // Set objects.
251  std::set<unsigned int> in_neighbours, out_neighbours;
252  // Iterator objects.
253  std::vector<unsigned int>::iterator it;
254  typename VertexType::iterator it_in, end_in, it_out, end_out;
255  // Computes the intersection for the in- and out- neighbourhoods of each node.
256  for(unsigned int n(0), nn(this->get_nb_vertices()); n<nn; ++n)
257  {
258  // Sets the iterators.
259  it_in = (*this)(n)->in_neighbour_begin();
260  end_in = (*this)(n)->in_neighbour_end();
261  it_out = (*this)(n)->out_neighbour_begin();
262  end_out = (*this)(n)->out_neighbour_end();
263  // Fills the ordered sets.
264  in_neighbours.clear();
265  for(; it_in!=end_in; ++it_in)
266  {
267  in_neighbours.insert(it_in->id);
268  }
269  out_neighbours.clear();
270  for(; it_out!=end_out; ++it_out)
271  {
272  out_neighbours.insert(it_out->id);
273  }
274  // Counts the number of edges that are reciprocal.
275  intersection.clear();
276  intersection.resize(std::min((*this)(n)->get_in_degree(), (*this)(n)->get_out_degree()));
277  it = std::set_intersection(in_neighbours.begin(), in_neighbours.end(), out_neighbours.begin(), out_neighbours.end(), intersection.begin());
278  intersection.resize(it-intersection.begin());
279  nb_reciprocal_edges += intersection.size();
280  (*this)(n)->set_nb_reciprocal_edges(2 * intersection.size());
281  }
282  // // Divides the number of intersections found since every reciprocal edge is counted twice.
283  // nb_reciprocal_edges /= 2;
284  // Computes the reciprocity.
285  reciprocity = static_cast<double>(this->get_nb_reciprocal_edges()) / this->get_nb_edges();
286  // Indicates that the calculations has been done.
287  has_nb_reciprocal_edges_been_computed = true;
288 }
289 
290 // ================================================================================================
291 // ================================================================================================
292 template <class VertexType>
294 {
295  // Ensures that required quantities have previously been calculated.
296  if(!has_nb_reciprocal_edges_been_computed)
297  {
298  compute_nb_reciprocal_edges();
299  }
300  // Vector objects.
301  std::vector<unsigned int> intersection;
302  // Set objects.
303  std::set<unsigned int> neighbours_v1, neighbours_v2;
304  // Iterator objects.
305  std::vector<unsigned int>::iterator it;
306  typename VertexType::iterator it1, end1, it2, end2;
307  std::set<unsigned int>::iterator it3, end3;
308  // Computes the intersection for the in- and out- neighbourhoods of each node.
309  for(unsigned int v1(0), v2, v3, d1, d2, nn(this->get_nb_vertices()); v1<nn; ++v1)
310  {
311  // Projected undirected degree of vertex v1.
312  d1 = (*this)(v1)->get_undirected_projection_degree();
313  // Performs the calculation only if d1>1.
314  if( d1 > 1 )
315  {
316  // Builds an ordered list of the neighbourhood of v1 (neighbors appear only once).
317  neighbours_v1.clear();
318  it1 = (*this)(v1)->out_neighbour_begin();
319  end1 = (*this)(v1)->out_neighbour_end();
320  for(; it1 != end1; ++it1)
321  {
322  neighbours_v1.insert(it1->id);
323  }
324  it1 = (*this)(v1)->in_neighbour_begin();
325  end1 = (*this)(v1)->in_neighbour_end();
326  for(; it1 != end1; ++it1)
327  {
328  neighbours_v1.insert(it1->id);
329  }
330  // it1 = (*this)(v1)->neighbour_begin();
331  // Loops over the neighbours of vertex v1.
332  it3 = neighbours_v1.begin();
333  end3 = neighbours_v1.end();
334  for(; it3!=end3; ++it3)
335  {
336  // Identity and degree of vertex 2.
337  v2 = *it3;
338  d2 = (*this)(v2)->get_undirected_projection_degree();
339  // Performs the calculation only if d1>1 and if v2>v1 (ensures that each triangle is counted once).
340  if( v2 > v1 && d2 > 1 )
341  {
342  // Builds an ordered list of the neighbourhood of v2 (neighbors appear only once).
343  neighbours_v2.clear();
344  it2 = (*this)(v2)->out_neighbour_begin();
345  end2 = (*this)(v2)->out_neighbour_end();
346  for(; it2 != end2; ++it2)
347  {
348  v3 = it2->id;
349  if(v3 > v2) // Ensures that triangles will be counted only once.
350  {
351  neighbours_v2.insert(v3);
352  }
353  }
354  it2 = (*this)(v2)->in_neighbour_begin();
355  end2 = (*this)(v2)->in_neighbour_end();
356  for(; it2 != end2; ++it2)
357  {
358  v3 = it2->id;
359  if(v3 > v2) // Ensures that triangles will be counted only once.
360  {
361  neighbours_v2.insert(v3);
362  }
363  }
364  d2 = neighbours_v2.size();
365  // Identifies the triangles.
366  intersection.clear();
367  intersection.resize(std::min(d1,d2));
368  it = std::set_intersection(neighbours_v1.begin(), neighbours_v1.end(), neighbours_v2.begin(), neighbours_v2.end(), intersection.begin());
369  intersection.resize(it-intersection.begin());
370  // Loops over the common neighbours of vertices v1 and v2.
371  for(unsigned int n(0), nn(intersection.size()); n<nn; ++n)
372  {
373  // Identity and degree of vertex 2.
374  v3 = intersection[n];
375  // Considers the triangle only if v1 is the lowest index (ensures that each triangle is counted once).
376  // if(v3 > v1)
377  {
378  // Adds the triangle to the list.
379  triangles.push_back({v1,v2,v3});
380  }
381  }
382  }
383  }
384  }
385  }
386  // Counts the number of triangles.
387  nb_undirected_projection_triangles = triangles.size();
388  // Indicates that the calculations has been done.
389  has_triangles_been_surveyed = true;
390 }
391 
392 // ================================================================================================
393 // ================================================================================================
394 template <class VertexType>
396 {
397  // Ensures that required quantities have previously been calculated.
398  if(!has_triangles_been_surveyed)
399  {
400  survey_triangles();
401  }
402  // Sets the local clustering coefficients.
403  unsigned int v1, v2, v3;
404  std::list< std::vector<unsigned int> >::iterator it = triangles.begin();
405  std::list< std::vector<unsigned int> >::iterator end = triangles.end();
406  for(unsigned int v; it != end; ++it)
407  {
408  // std::cout << (*it)[0] << " " << (*it)[1] << " " << (*it)[2] << std::endl;
409  // Loops over the three vertices in the triangle.
410  for(unsigned int i(0); i<3; ++i)
411  {
412  v = (*it)[i];
413  (*this)(v)->set_nb_undirected_projection_triangles((*this)(v)->get_nb_undirected_projection_triangles() + 1);
414  }
415  }
416  // Counts the number of wedges and computes the average local clustering coefficient.
417  for(unsigned int n(0), d, nn(this->get_nb_vertices()); n<nn; ++n)
418  {
419  // Number of wedges.
420  d = (*this)(n)->get_undirected_projection_degree();
421  nb_undirected_projection_wedges += d * ( d - 1. ) / 2.;
422  // Local clustering coefficient.
423  avg_local_undirected_projection_clustering_coefficient += (*this)(n)->get_local_undirected_projection_clustering_coefficient();
424  }
425  avg_local_undirected_projection_clustering_coefficient /= this->get_nb_vertices();
426  // Sets the global clustering coefficient.
427  global_undirected_projection_clustering_coefficient = 3. * this->get_nb_undirected_projection_triangles() / nb_undirected_projection_wedges;
428  // Indicates that the calculations has been done.
429  have_undirected_projection_clustering_coefficients_been_computed = true;
430 }
431 
432 // ================================================================================================
433 // ================================================================================================
434 template <class VertexType>
436 {
437  // Resets the number of types of vertices.
438  this->set_nb_of_types_of_degrees(2);
439  // Resets the variables inherited from base_graph.
440  this->base_graph_clear();
441  // Resets various objects.
442  reciprocity = 0;
443  nb_reciprocal_edges = 0;
444  nb_undirected_projection_wedges = 0;
445  nb_undirected_projection_triangles = 0;
446  global_undirected_projection_clustering_coefficient = 0;
447  avg_local_undirected_projection_clustering_coefficient = 0;
448  has_triangles_been_surveyed = false;
449  triangles.clear();
450  // Resets boolean indicators.
451  has_triangles_been_surveyed = false;
452  has_nb_reciprocal_edges_been_computed = false;
453  have_undirected_projection_clustering_coefficients_been_computed = false;
454 }
455 
456 
457 
458 #endif // BASE_DIRECTED_GRAPH_HPP_INCLUDED
double get_reciprocity()
Returns the reciprocity.
Definition: base_directed_graph.hpp:111
virtual void write_graph_properties(std::string _name)=0
Exports the graph's properties.
Virtual template base class for directed graph objects.
Definition: base_directed_graph.hpp:37
const unsigned int id_in_degree
Index corresponding to the in-degree in degree-related vectors.
Definition: base_directed_graph.hpp:44
unsigned int get_nb_reciprocal_edges()
Returns the number of reciprocal edges.
Definition: base_directed_graph.hpp:103
void write_edgelist(std::string _name)
Exports the directed graph to an edgelist.
Definition: base_directed_graph.hpp:199
double get_avg_out_degree()
Returns the average out degree found in the graph.
Definition: base_directed_graph.hpp:159
unsigned int get_max_out_degree()
Returns the maximal out degree found in the graph.
Definition: base_directed_graph.hpp:151
double get_avg_local_undirected_projection_clustering_coefficient()
Returns the average value of the local clustering coefficients.
Definition: base_directed_graph.hpp:191
double get_avg_in_degree()
Returns the average in degree found in the graph.
Definition: base_directed_graph.hpp:135
unsigned int get_max_in_degree()
Returns the maximal in degree found in the graph.
Definition: base_directed_graph.hpp:127
Virtual template base class for graph objects.
Definition: base_graph.hpp:33
unsigned int get_min_out_degree()
Returns the minimal out degree found in the graph.
Definition: base_directed_graph.hpp:143
virtual void write_vertices_properties(std::string _name)=0
Exports the vertices' properties.
unsigned int get_nb_undirected_projection_wedges()
Returns the number of wegdes in the graph (regardless of the direction of the edges).
Definition: base_directed_graph.hpp:175
unsigned int get_min_in_degree()
Returns the minimal in degree found in the graph.
Definition: base_directed_graph.hpp:119
base_directed_graph()
Constructor.
Definition: base_directed_graph.hpp:97
double get_global_undirected_projection_clustering_coefficient()
Returns the global clustering coefficient (3 x [number of triangles] / [number of wedges]...
Definition: base_directed_graph.hpp:183
Virtual base class for graphs.
const unsigned int id_out_degree
Index corresponding to the out-degree in degree-related vectors.
Definition: base_directed_graph.hpp:43
unsigned int get_nb_undirected_projection_triangles()
Returns the number of triangles in the graph (regardless of the direction of the edges).
Definition: base_directed_graph.hpp:167
void compute_undirected_projection_clustering_coefficients()
Computes the clustering coefficients.
Definition: base_directed_graph.hpp:395
void base_directed_graph_clear()
Reinitializes the graph (inherited variables).
Definition: base_directed_graph.hpp:435
virtual ~base_directed_graph()
Destructor.
Definition: base_directed_graph.hpp:66
void survey_triangles()
Creates a list of the triangles in the graph (regardless of the direction of the edges).
Definition: base_directed_graph.hpp:293
void compute_nb_reciprocal_edges()
Computes the number of reciprocal edges.
Definition: base_directed_graph.hpp:246