Graph 3
graph.cpp
Go to the documentation of this file.
1 #include "graph.h"
2 #include <algorithm>
3 #include <cassert>
4 #include <fstream>
5 using namespace std;
6 
7 [[maybe_unused]] graph::graph(const string &file_name)
8  : _edges(0), _vertices(), _maxvert(-1) // graph_2
9 {
10  ifstream fin(file_name); // Oeffne das File im ASCII-Modus
11  if ( fin.is_open() ) { // File gefunden:
12 // _edges.clear(); // Vektor leeren
13  unsigned int k, l;
14  while ( fin >> k >> l) {_edges.push_back({k, l});} // Einlesen
15  if (!fin.eof()) {
16  // Fehlerbehandlung
17  cout << " Error handling \n";
18  if ( fin.bad() ) {throw runtime_error("Schwerer Fehler in istr");}
19  if ( fin.fail() ) { // Versuch des Aufraeumens
20  cout << " Failed in reading all data.\n";
21  fin.clear();
22  }
23  }
24  _edges.shrink_to_fit();
25  }
26  else { // File nicht gefunden:
27  cout << "\nFile " << file_name << " has not been found.\n\n" ;
28  assert( fin.is_open() && "File not found." ); // exeption handling for the poor programmer
29  }
30 
31  DetermineNumberVertices();
32 }
33 
34 
35 vector<vector<unsigned int>> graph::get_node2nodes() const
36 {
37 // size_t nnode=Nvertices();
38  size_t nnode = Max_vertex() + 1; // graph_2
39 
40  // Determine the neighborhood for each vertex
41  vector<vector<unsigned int>> n2n(nnode);
42  for (auto _edge : _edges) {
43  auto const v0 = _edge[0];
44  auto const v1 = _edge[1];
45  n2n.at(v0).push_back(v1); // add v1 to neighborhood of v0
46  n2n.at(v1).push_back(v0); // and vice versa
47  }
48  // ascending sort of entries per node
49  for (auto & k : n2n) {
50  sort(k.begin(), k.end());
51  }
52 
53 
54  return n2n;
55 }
56 // graph_2
57 void graph::DetermineNumberVertices()
58 {
59  // we assume that the nodes are numbered consecutively from 0 to n-1
60  // determine number of nodes
61  _vertices.clear();
62  unsigned int nnode = 0;
63  for (auto & _edge : _edges) {
64  for (unsigned int & j : _edge) {
65  nnode = max(nnode, j);
66  _vertices.insert(j); // graph_2
67  }
68  }
69  if ( !_edges.empty() ) // at least one edge in graph?
70  {_maxvert = nnode;}
71  else
72  {_maxvert=-1;}
73 }
74 
75 ostream &operator<<(ostream &s, graph const &rhs)
76 {
77  s << "Graph with " << rhs.Nedges() << " edges and " << rhs.Nvertices() << " vertices" << endl;
78 
79  const auto &edges = rhs._edges;
80  s << "\n -- Edges --\n";
81  for (size_t k = 0; k < edges.size(); ++k) {
82  s << k << " : ";
83  for (unsigned int j : edges[k]) {
84  s << j << " ";
85  }
86  s << endl;
87  }
88 
89  s << "\n -- Vertices --\n"; // graph_2
90  for (auto v : rhs._vertices) { // graph_2
91  s << v << " ";
92  }
93  s << endl;
94 
95  return s;
96 }
97 
98 
99 [[maybe_unused]] bool graph::Append(unsigned int v1, unsigned int v2) // graph_3
100 {
101  const auto ip = find(_edges.cbegin(), _edges.cend(), Edge{v1, v2});
102  bool edgeFound(ip == _edges.cend()); // really a new edge
103  if (edgeFound) {
104  _edges.push_back(Edge{v1, v2});
105  _vertices.insert(v1);
106  _maxvert = max(_maxvert, v1);
107  _vertices.insert(v2);
108  _maxvert = max(_maxvert, v2);
109  }
110  return edgeFound;
111 }
112 
113 bool graph::Delete(Edge const& e) // graph_3
114 {
115  const auto ip = find(_edges.cbegin(), _edges.cend(), e);
116  bool edgeFound(ip != _edges.cend()); // edge found
117  if (edgeFound) {
118  _edges.erase(ip);
119  DetermineNumberVertices(); // updates _vertices, _maxvert
120  }
121  return edgeFound;
122 }
123 
124 [[maybe_unused]] bool graph::Delete(unsigned int v1, unsigned int v2) // graph_3
125 {
126  return Delete(Edge{v1, v2});
127 }
128 
129 void graph::Delete(vector<Edge> const &v) // graph_3
130 {
131  for (const auto &e : v) {
132  const auto ip = find(_edges.cbegin(), _edges.cend(), e);
133  bool edgeFound(ip != _edges.cend()); // edge found
134  if (edgeFound) {
135  _edges.erase(ip);
136  }
137  }
138  DetermineNumberVertices(); // updates _vertices, _maxvert: called only once
139 }
140 
Definition: graph.h:14
size_t Nedges() const
Definition: graph.h:45
size_t Max_vertex() const
Definition: graph.h:61
bool Delete(unsigned int v1, unsigned int v2)
Removes one directed edge (v1, v2) from the graph. The method add only edges that not already contain...
Definition: graph.cpp:124
graph(const std::string &file_name)
Reads edges for graph from file.
size_t Nvertices() const
Definition: graph.h:53
bool Append(unsigned int v1, unsigned int v2)
Appends one directed edge to the graph. The method add only edges that not already contained in the g...
Definition: graph.cpp:99
std::vector< std::vector< unsigned int > > get_node2nodes() const
Definition: graph.cpp:35
ostream & operator<<(ostream &s, graph const &rhs)
Definition: graph.cpp:75