Graph C++ Library
 All Classes Namespaces Files Functions Variables Typedefs Groups Pages
real_undirected_graph.hpp
Go to the documentation of this file.
1 
10 #ifndef REAL_UNDIRECTED_GRAPH_HPP_INCLUDED
11 #define REAL_UNDIRECTED_GRAPH_HPP_INCLUDED
12 
13 // Standard Library
14 #include <ctime> // time, gmtime
15 #include <cstdlib> // abort
16 #include <fstream>
17 #include <iostream>
18 #include <map>
19 #include <set>
20 #include <sstream>
21 #include <string>
22 #include <vector>
23 #include <utility> // pair, make_pair, swap
24 // Graph C++ Library
27 
29 namespace gcl
30 {
31 
41  class real_undirected_graph : public gcl::base_undirected_graph<gcl::real_undirected_vertex>
42  {
43  // ============================================================================================
44  // *** Member functions.
45  public:
48  void read_edgelist(std::string _name);
49  void write_graph_properties(std::string _name);
50  void write_vertices_properties(std::string _name);
51  void clear();
52  };
53 
54 } // End of namespace gcl.
55 
56 
57 
58 // ================================================================================================
59 // ================================================================================================
61 {
62  clear();
63 }
64 
65 // ================================================================================================
66 // ================================================================================================
68 {
69  // Stream objects.
70  std::ifstream edgelist_file;
71  std::stringstream one_line;
72  // String objects.
73  std::string full_line, name1_str, name2_str;
74  // Integer objects.
75  unsigned int node_cnt, edge_cnt, node1_int, node2_int, edge_int;
76  // Map objects to assure the uniqueness of edges.
77  std::map< std::string, unsigned int > Name2ID;
78  std::map< unsigned int, std::string > ID2Name;
79  std::set< std::pair<unsigned int, unsigned int> > Edgelist;
80  // Iterator objects.
81  std::map< std::string,unsigned int >::iterator name_it;
82  std::set< std::pair<unsigned int,unsigned int> >::iterator edge_it, edge_end;
83  // Opens the stream and aborts if the operation did not succeed.
84  edgelist_file.open(_name.c_str(), std::ios_base::in);
85  if( !edgelist_file.is_open() )
86  {
87  std::cout << "Could not open file: " << _name << "." << std::endl;
88  abort();
89  }
90  // Reads the edgelist and registers the nodes and the edges.
91  node_cnt = 0;
92  edge_cnt = 0;
93  while( !edgelist_file.eof() )
94  {
95  // Reads a line of the edgelist.
96  std::getline(edgelist_file,full_line); edgelist_file >> std::ws;
97  one_line.str(full_line); one_line >> std::ws;
98  one_line >> name1_str >> std::ws;
99  one_line >> name2_str >> std::ws;
100  one_line.clear();
101  // Is name1 new?
102  name_it = Name2ID.find(name1_str);
103  if( name_it == Name2ID.end() )
104  {
105  Name2ID[name1_str] = node_cnt;
106  ID2Name[node_cnt] = name1_str;
107  node1_int = node_cnt;
108  ++node_cnt;
109  }
110  else
111  {
112  node1_int = name_it->second;
113  }
114  // Is name2 new?
115  name_it = Name2ID.find(name2_str);
116  if( name_it == Name2ID.end() )
117  {
118  Name2ID[name2_str] = node_cnt;
119  ID2Name[node_cnt] = name2_str;
120  node2_int = node_cnt;
121  ++node_cnt;
122  }
123  else
124  {
125  node2_int = name_it->second;
126  }
127  // Is this a new edge? (excludes self- and multi- edges).
128  if(node1_int < node2_int)
129  {
130  std::swap(node1_int,node2_int);
131  }
132  if(node1_int != node2_int)
133  {
134  edge_it = Edgelist.find( std::make_pair(node1_int,node2_int) );
135  if( edge_it == Edgelist.end() )
136  {
137  // Registers this new edge.
138  Edgelist.insert( std::make_pair(node1_int,node2_int) );
139  ++edge_cnt;
140  }
141  }
142  }
143  // Sets the number of vertices and edges.
144  this->set_nb_vertices(node_cnt);
145  this->set_nb_edges(edge_cnt);
146  // Populates the graph.
147  edge_it = Edgelist.begin();
148  edge_end = Edgelist.end();
149  for(unsigned int n(0), nn(this->get_nb_vertices()); n<nn; ++n)
150  {
151  // Sets the id of the vertex.
152  (*this)(n)->set_name(ID2Name[n]);
153  }
154  for(; edge_it!=edge_end; ++edge_it)
155  {
156  // Finds the vertices' identity.
157  node1_int = edge_it->first;
158  node2_int = edge_it->second;
159  // Creates the edge.
160  (*this)(node1_int)->neighbour_insert(gcl::simple_edge(node2_int));
161  (*this)(node2_int)->neighbour_insert(gcl::simple_edge(node1_int));
162  }
163  // Closes the stream.
164  edgelist_file.close();
165 }
166 
167 // ================================================================================================
168 // ================================================================================================
170 {
171  // Streams objects.
172  std::ofstream graph_properties_file;
173  // String objects.
174  std::string graph_properties_filename = _name + "_graph_properties.dat";
175  // Opens the stream and aborts if the operation did not succeed.
176  graph_properties_file.open(graph_properties_filename.c_str(), std::ios_base::out);
177  if( !graph_properties_file.is_open() )
178  {
179  std::cout << "Could not open file: " << _name << "." << std::endl;
180  abort();
181  }
182  // Gets the current date/time.
183  time_t theTime = time(NULL);
184  struct tm *aTime = gmtime(&theTime);
185  int year = aTime->tm_year + 1900;
186  int month = aTime->tm_mon + 1;
187  int day = aTime->tm_mday;
188  int hours = aTime->tm_hour;
189  int minutes = aTime->tm_min;
190  // Writes the properties of the graph.
191  graph_properties_file << "===================================================================================" << std::endl;
192  graph_properties_file << "General information." << std::endl;
193  graph_properties_file << "type of graph: " << this->get_type_of_graph() << std::endl;
194  graph_properties_file << "graph: " << _name << std::endl;
195  graph_properties_file << "computed on: " << year << "/";
196  if(month < 10)
197  graph_properties_file << "0";
198  graph_properties_file << month << "/";
199  if(day < 10)
200  graph_properties_file << "0";
201  graph_properties_file << day << " " << hours << ":";
202  if(minutes < 10)
203  graph_properties_file << "0";
204  graph_properties_file << minutes << " UTC" << std::endl;
205  graph_properties_file << "===================================================================================" << std::endl;
206  graph_properties_file << "Observables (excluding zero-degree vertices)" << std::endl;
207  graph_properties_file << "Number of nodes: " << this->get_nb_vertices()-this->get_nb_zerodegree_vertices() << std::endl;
208  graph_properties_file << "Number of edges: " << this->get_nb_edges() << std::endl;
209  graph_properties_file << "Number of wedges: " << this->get_nb_wedges() << std::endl;
210  graph_properties_file << "Number of triangles: " << this->get_nb_triangles() << std::endl;
211  graph_properties_file << "Global clustering coefficient: " << this->get_global_clustering_coefficient() << std::endl;
212  graph_properties_file << "Average local clustering coefficient: " << this->get_avg_local_clustering_coefficient() << std::endl;
213  graph_properties_file << "Degree distribution" << std::endl;
214  graph_properties_file << " - average degree: " << this->get_avg_degree() << std::endl;
215  graph_properties_file << " - minimum degree (excluding zero): " << this->get_min_degree() << std::endl;
216  graph_properties_file << " - maximum degree: " << this->get_max_degree() << std::endl;
217  // Closes the stream.
218  graph_properties_file.close();
219 }
220 
221 // ================================================================================================
222 // ================================================================================================
224 {
225  // Streams objects.
226  std::ofstream vertices_properties_file;
227  // String objects.
228  std::string vertices_properties_filename = _name + "_vertices_properties.dat";
229  // Opens the stream and aborts if the operation did not succeed.
230  vertices_properties_file.open(vertices_properties_filename.c_str(), std::ios_base::out);
231  if( !vertices_properties_file.is_open() )
232  {
233  std::cout << "Could not open file: " << _name << "." << std::endl;
234  abort();
235  }
236  // Writes the properties of each vertex.
237  vertices_properties_file.precision(8);
238  for(unsigned int n(0), nn(this->get_nb_vertices()); n<nn; ++n)
239  {
240  vertices_properties_file << std::fixed << (*this)(n)->get_name() << " ";
241  vertices_properties_file << std::fixed << (*this)(n)->get_degree() << " ";
242  vertices_properties_file << std::fixed << (*this)(n)->get_nb_triangles() << " ";
243  vertices_properties_file << std::fixed << (*this)(n)->get_local_clustering_coefficient() << std::endl;
244  }
245  // Closes the stream.
246  vertices_properties_file.close();
247 }
248 
249 // ================================================================================================
250 // ================================================================================================
252 {
253  // Reintializes the variables inherited from the class base_undirected_graph.
254  base_undirected_graph_clear();
255  // Sets the type of the graph.
256  this->set_type_of_graph("Real undirected graph");
257 }
258 
259 
260 
261 #endif // REAL_UNDIRECTED_GRAPH_HPP_INCLUDED
void write_graph_properties(std::string _name)
Exports the graph's properties.
Definition: real_undirected_graph.hpp:169
Class for vertices in real undirected graphs.
void clear()
Reinitializes the graph.
Definition: real_undirected_graph.hpp:251
Class of the attributes of a simple edge.
Definition: edge_attributes.hpp:24
real_undirected_graph()
Constructor.
Definition: real_undirected_graph.hpp:60
Virtual base class for undirected graphs.
Virtual template base class for undirected graph objects.
Definition: base_undirected_graph.hpp:37
void write_vertices_properties(std::string _name)
Exports the vertices' properties.
Definition: real_undirected_graph.hpp:223
Class for real undirected graphs.
Definition: real_undirected_graph.hpp:41
~real_undirected_graph()
Destructor.
Definition: real_undirected_graph.hpp:47
void read_edgelist(std::string _name)
Imports a undirected graph from an edgelist.
Definition: real_undirected_graph.hpp:67