10 #ifndef BASE_DIRECTED_GRAPH_HPP_INCLUDED
11 #define BASE_DIRECTED_GRAPH_HPP_INCLUDED
36 template <
class VertexType>
49 unsigned int nb_reciprocal_edges;
50 std::list< std::vector<unsigned int> > triangles;
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;
59 bool has_triangles_been_surveyed;
60 bool has_nb_reciprocal_edges_been_computed;
61 bool have_undirected_projection_clustering_coefficients_been_computed;
96 template <
class VertexType>
98 : id_out_degree(0), id_in_degree(1) { }
102 template <
class VertexType>
105 return nb_reciprocal_edges;
110 template <
class VertexType>
118 template <
class VertexType>
121 return this->get_base_graph_min_degrees(id_in_degree);
126 template <
class VertexType>
129 return this->get_base_graph_max_degrees(id_in_degree);
134 template <
class VertexType>
137 return this->get_base_graph_avg_degrees(id_in_degree);
142 template <
class VertexType>
145 return this->get_base_graph_min_degrees(id_out_degree);
150 template <
class VertexType>
153 return this->get_base_graph_max_degrees(id_out_degree);
158 template <
class VertexType>
161 return this->get_base_graph_avg_degrees(id_out_degree);
166 template <
class VertexType>
169 return nb_undirected_projection_triangles;
174 template <
class VertexType>
177 return nb_undirected_projection_wedges;
182 template <
class VertexType>
185 return global_undirected_projection_clustering_coefficient;
190 template <
class VertexType>
193 return avg_local_undirected_projection_clustering_coefficient;
198 template <
class VertexType>
202 std::ofstream edgelist_file;
204 std::string edgelist_filename = _name +
"_edgelist.dat";
205 std::string node1_str;
207 typename VertexType::iterator it, end;
209 edgelist_file.open(edgelist_filename.c_str(), std::ios_base::out);
210 if( !edgelist_file.is_open() )
212 std::cout <<
"Could not open file: " << edgelist_filename <<
"." << std::endl;
216 for(
unsigned int node1(0), node2, nn(this->get_nb_vertices()); node1<nn; ++node1)
219 it = (*this)(node1)->out_neighbour_begin();
220 end = (*this)(node1)->out_neighbour_end();
221 node1_str = (*this)(node1)->get_name();
225 edgelist_file << node1_str <<
" " << (*this)(node2)->get_name() << std::endl;
229 edgelist_file.close();
245 template <
class VertexType>
249 std::vector<unsigned int> intersection;
251 std::set<unsigned int> in_neighbours, out_neighbours;
253 std::vector<unsigned int>::iterator it;
254 typename VertexType::iterator it_in, end_in, it_out, end_out;
256 for(
unsigned int n(0), nn(this->get_nb_vertices()); n<nn; ++n)
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();
264 in_neighbours.clear();
265 for(; it_in!=end_in; ++it_in)
267 in_neighbours.insert(it_in->id);
269 out_neighbours.clear();
270 for(; it_out!=end_out; ++it_out)
272 out_neighbours.insert(it_out->id);
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());
285 reciprocity =
static_cast<double>(this->get_nb_reciprocal_edges()) / this->get_nb_edges();
287 has_nb_reciprocal_edges_been_computed =
true;
292 template <
class VertexType>
296 if(!has_nb_reciprocal_edges_been_computed)
298 compute_nb_reciprocal_edges();
301 std::vector<unsigned int> intersection;
303 std::set<unsigned int> neighbours_v1, neighbours_v2;
305 std::vector<unsigned int>::iterator it;
306 typename VertexType::iterator it1, end1, it2, end2;
307 std::set<unsigned int>::iterator it3, end3;
309 for(
unsigned int v1(0), v2, v3, d1, d2, nn(this->get_nb_vertices()); v1<nn; ++v1)
312 d1 = (*this)(v1)->get_undirected_projection_degree();
317 neighbours_v1.clear();
318 it1 = (*this)(v1)->out_neighbour_begin();
319 end1 = (*this)(v1)->out_neighbour_end();
320 for(; it1 != end1; ++it1)
322 neighbours_v1.insert(it1->id);
324 it1 = (*this)(v1)->in_neighbour_begin();
325 end1 = (*this)(v1)->in_neighbour_end();
326 for(; it1 != end1; ++it1)
328 neighbours_v1.insert(it1->id);
332 it3 = neighbours_v1.begin();
333 end3 = neighbours_v1.end();
334 for(; it3!=end3; ++it3)
338 d2 = (*this)(v2)->get_undirected_projection_degree();
340 if( v2 > v1 && d2 > 1 )
343 neighbours_v2.clear();
344 it2 = (*this)(v2)->out_neighbour_begin();
345 end2 = (*this)(v2)->out_neighbour_end();
346 for(; it2 != end2; ++it2)
351 neighbours_v2.insert(v3);
354 it2 = (*this)(v2)->in_neighbour_begin();
355 end2 = (*this)(v2)->in_neighbour_end();
356 for(; it2 != end2; ++it2)
361 neighbours_v2.insert(v3);
364 d2 = neighbours_v2.size();
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());
371 for(
unsigned int n(0), nn(intersection.size()); n<nn; ++n)
374 v3 = intersection[n];
379 triangles.push_back({v1,v2,v3});
387 nb_undirected_projection_triangles = triangles.size();
389 has_triangles_been_surveyed =
true;
394 template <
class VertexType>
398 if(!has_triangles_been_surveyed)
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)
410 for(
unsigned int i(0); i<3; ++i)
413 (*this)(v)->set_nb_undirected_projection_triangles((*
this)(v)->get_nb_undirected_projection_triangles() + 1);
417 for(
unsigned int n(0), d, nn(this->get_nb_vertices()); n<nn; ++n)
420 d = (*this)(n)->get_undirected_projection_degree();
421 nb_undirected_projection_wedges += d * ( d - 1. ) / 2.;
423 avg_local_undirected_projection_clustering_coefficient += (*this)(n)->get_local_undirected_projection_clustering_coefficient();
425 avg_local_undirected_projection_clustering_coefficient /= this->get_nb_vertices();
427 global_undirected_projection_clustering_coefficient = 3. * this->get_nb_undirected_projection_triangles() / nb_undirected_projection_wedges;
429 have_undirected_projection_clustering_coefficients_been_computed =
true;
434 template <
class VertexType>
438 this->set_nb_of_types_of_degrees(2);
440 this->base_graph_clear();
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;
451 has_triangles_been_surveyed =
false;
452 has_nb_reciprocal_edges_been_computed =
false;
453 have_undirected_projection_clustering_coefficients_been_computed =
false;
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