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