GEDLIB  1.0
ged_graph.ipp
Go to the documentation of this file.
1 /***************************************************************************
2  * *
3  * Copyright (C) 2018 by David B. Blumenthal *
4  * *
5  * This file is part of GEDLIB. *
6  * *
7  * GEDLIB is free software: you can redistribute it and/or modify it *
8  * under the terms of the GNU Lesser General Public License as published *
9  * by the Free Software Foundation, either version 3 of the License, or *
10  * (at your option) any later version. *
11  * *
12  * GEDLIB is distributed in the hope that it will be useful, *
13  * but WITHOUT ANY WARRANTY; without even the implied warranty of *
14  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
15  * GNU Lesser General Public License for more details. *
16  * *
17  * You should have received a copy of the GNU Lesser General Public *
18  * License along with GEDLIB. If not, see <http://www.gnu.org/licenses/>. *
19  * *
20  ***************************************************************************/
21 
27 #ifndef SRC_ENV_GED_GRAPH_IPP_
28 #define SRC_ENV_GED_GRAPH_IPP_
29 
30 
31 namespace ged {
32 
35 alist_{},
36 amatrix_(1),
37 id_(undefined()),
38 initialized_{false} {}
39 
42 alist_{},
43 amatrix_(1),
44 id_{id},
45 initialized_{false} {}
46 
48 GEDGraph(const GEDGraph & ged_graph):
49 alist_(ged_graph.alist_),
50 amatrix_(ged_graph.amatrix_),
51 id_{ged_graph.id_},
52 initialized_{ged_graph.initialized_} {}
53 
57  return std::numeric_limits<NodeID>::max() - 1;
58 }
59 
63  return std::numeric_limits<NodeID>::max();
64 }
65 
69  return std::numeric_limits<EdgeID>::max();
70 }
71 
75  initialized_ = false;
76  NodeID new_node{boost::add_vertex(alist_)};
77  if (new_node >= dummy_node()) {
78  throw Error("Cannot add node. Maximal number of nodes reached.");
79  }
80  alist_[new_node].label = invalid_label();
81  return new_node;
82 }
83 
87  initialized_ = false;
88  auto alist_ed = boost::add_edge(tail, head, alist_);
89  alist_[alist_ed.first].label = invalid_label();
90  return alist_ed.first;
91 }
92 
93 void
96  detail::GedGraphAM tmp(num_nodes());
97  for (auto eitr = boost::edges(alist_); eitr.first != eitr.second; ++eitr.first) {
98  EdgeID e{*eitr.first};
99  NodeID source {boost::source(e, alist_)};
100  NodeID target {boost::target(e, alist_)};
101 
102  auto am_edge = boost::add_edge(source, target, tmp);
103  if (am_edge.second == false) {
104  throw Error("Parallel edge detected!");
105  }
106  tmp[am_edge.first].cref = e;
107  }
108  std::swap(tmp, amatrix_);
109  initialized_ = true;
110 }
111 
112 void
115  alist_[v].label = l_id;
116 }
117 
118 void
121  alist_[e].label = l_id;
122 }
123 
124 LabelID
126 get_node_label(NodeID node) const {
127  if (node == dummy_node()) {
128  return dummy_label();
129  }
130  return alist_[node].label;
131 }
132 
133 LabelID
136  return alist_[e].label;
137 }
138 
139 LabelID
141 get_edge_label(NodeID node_1, NodeID node_2) const {
142  if (is_edge(node_1, node_2)) {
143  return get_edge_label(get_edge(node_1, node_2));
144  }
145  return dummy_label();
146 }
147 
148 std::pair<GEDGraph::incident_edge_iterator, GEDGraph::incident_edge_iterator>
151  return boost::out_edges(v, alist_);
152 }
153 
154 const detail::GedGraphAL &
157  return alist_;
158 }
159 
160 std::size_t
162 degree(NodeID v) const {
163  return static_cast<std::size_t>(boost::out_degree(v, alist_));
164 }
165 
166 std::size_t
168 maxdeg() const {
169  std::size_t maxdeg{0};
170  for (auto node = this->nodes().first; node != this->nodes().second; node++) {
171  maxdeg = std::max(this->degree(*node), maxdeg);
172  }
173  return static_cast<std::size_t>(maxdeg);
174 }
175 
178 tail(EdgeID e) const {
179  return boost::source(e, alist_);
180 }
181 
184 id() const {
185  return id_;
186 }
187 
188 void
190 clear() {
191  initialized_ = false;
192  alist_.clear();
193  detail::GedGraphAM tmp(1);
194  std::swap(tmp, amatrix_);
195 }
196 
199 head(EdgeID e) const {
200  return boost::target(e, alist_);
201 }
202 
203 std::pair<GEDGraph::node_iterator, GEDGraph::node_iterator>
205 nodes() const {
206  return boost::vertices(alist_);
207 }
208 
209 std::size_t
211 num_nodes() const {
212  return static_cast<std::size_t>(boost::num_vertices(alist_));
213 }
214 
215 std::pair<GEDGraph::edge_iterator, GEDGraph::edge_iterator>
217 edges() const {
218  return boost::edges(alist_);
219 }
220 
221 std::size_t
223 num_edges() const {
224  return static_cast<std::size_t>(boost::num_edges(alist_));
225 }
226 
227 bool
229 initialized() const {
230  return initialized_;
231 }
232 
233 void
236  initialized_ = false;
237 }
238 
241 get_edge(NodeID source, NodeID target) const {
242  auto am_edge = boost::edge(source, target, amatrix_);
243  if (am_edge.second == false) {
244  return dummy_edge();
245  }
246  return amatrix_[am_edge.first].cref;
247 }
248 
251 safe_get_edge(NodeID source, NodeID target) const {
252  for (auto iedges = incident_edges(source); iedges.first != iedges.second; ++iedges.first) {
253  EdgeID e { *iedges.first };
254  NodeID n { this->head( e ) };
255  if (n == target) return e;
256  }
257  return dummy_edge();
258 }
259 
260 bool
262 is_edge(NodeID source, NodeID target) const {
263  if (source >= this->num_nodes() or target >= this->num_nodes()) {
264  return false;
265  }
266  auto am_edge = boost::edge(source, target, amatrix_);
267  return am_edge.second;
268 }
269 
270 bool
272 safe_is_edge(NodeID source, NodeID target) const {
273  for (auto iedges = incident_edges(source); iedges.first != iedges.second; ++iedges.first) {
274  EdgeID e { *iedges.first };
275  NodeID n { this->head( e ) };
276  if (n == target) return true;
277  }
278  return false;
279 }
280 
281 std::ostream & operator<<(std::ostream & os, const GEDGraph & graph) {
282  os << "ID = " << graph.id() << ", number of nodes = " << graph.num_nodes() << ", number of edges = " << graph.num_edges();
283  os << "\nadjacency matrix:\n ";
284  for (auto head = graph.nodes().first; head != graph.nodes().second; head++) {
285  os << "\033[1m" << std::setw(3) << std::right << graph.get_node_label(*head) << "\033[0m" << " ";
286  }
287  os << "\n";
288  for (auto tail = graph.nodes().first; tail != graph.nodes().second; tail++) {
289  os << "\033[1m" << std::setw(3) << std::right << graph.get_node_label(*tail) << "\033[0m" << " ";
290  for (auto head = graph.nodes().first; head != graph.nodes().second; head++) {
291  if (graph.initialized()) {
292  os << "\033[1m" << std::setw(3) << std::right << graph.get_edge_label(*tail, *head) << "\033[0m" << " ";
293  }
294  else {
295  if (graph.safe_is_edge(*tail, *head)) {
296  os << "\033[1m" << std::setw(3) << std::right << graph.get_edge_label(graph.safe_get_edge(*tail, *head)) << "\033[0m" << " ";
297  }
298  else {
299  os << std::setw(3) << std::right << 0 << " ";
300  }
301  }
302  }
303  os << "\n";
304  }
305  return os;
306 }
307 
308 }
309 
310 #endif /* SRC_ENV_GED_GRAPH_IPP_ */
void un_init()
Declare graph as un-initialized.
Definition: ged_graph.ipp:235
std::size_t num_nodes() const
Returns the number of nodes.
Definition: ged_graph.ipp:211
EdgeID add_edge(NodeID tail, NodeID head)
Adds a new edge to the graph.
Definition: ged_graph.ipp:86
const detail::GedGraphAL & get_adjacency_list() const
Returns the internal adjacency list representation.
Definition: ged_graph.ipp:156
GEDGraph()
Constructs an empty graph without meaningful ID.
Definition: ged_graph.ipp:34
std::vector< GEDGraph >::size_type GraphID
Type of internally used graph IDs.
Definition: ged_graph.hpp:112
EdgeID get_edge(NodeID tail, NodeID head) const
Retrieves an edge from its incident nodes.
Definition: ged_graph.ipp:241
NodeID head(EdgeID edge) const
Returns the head of an edge.
Definition: ged_graph.ipp:199
bool is_edge(NodeID tail, NodeID head) const
Checks if an edge exists.
Definition: ged_graph.ipp:262
static EdgeID dummy_edge()
Returns a dummy edge.
Definition: ged_graph.ipp:68
std::size_t degree(NodeID node) const
Returns node degree.
Definition: ged_graph.ipp:162
std::size_t maxdeg() const
Returns the maximum degree of the graph.
Definition: ged_graph.ipp:168
EdgeID safe_get_edge(NodeID tail, NodeID head) const
Retrieves an edge from its incident nodes.
Definition: ged_graph.ipp:251
std::size_t LabelID
Internally used type of node and edge labels.
void clear()
Clears the graph.
Definition: ged_graph.ipp:190
NodeID tail(EdgeID edge) const
Returns the tail of an edge.
Definition: ged_graph.ipp:178
LabelID get_node_label(NodeID node) const
Returns the label of a given node.
Definition: ged_graph.ipp:126
std::size_t num_edges() const
Returns the number of edges.
Definition: ged_graph.ipp:223
Runtime error class.
Definition: error.hpp:37
static NodeID dummy_node()
Returns a dummy node.
Definition: ged_graph.ipp:56
static NodeID undefined_node()
Returns an undefined node.
Definition: ged_graph.ipp:62
std::ostream & operator<<(std::ostream &os, const GEDGraph &graph)
Streams a graph.
Definition: ged_graph.ipp:281
LabelID get_edge_label(EdgeID edge) const
Returns the label of a given edge.
Definition: ged_graph.ipp:135
void set_label(NodeID node, LabelID label)
Sets a node&#39;s label.
Definition: ged_graph.ipp:114
std::pair< incident_edge_iterator, incident_edge_iterator > incident_edges(NodeID node) const
Provides access to all incident edges of a node.
Definition: ged_graph.ipp:150
std::pair< node_iterator, node_iterator > nodes() const
Provides access to all nodes in the graph.
Definition: ged_graph.ipp:205
constexpr LabelID invalid_label()
Returns an invalid label.
The normalized input graphs used by GEDLIB. All labels are integers.
Definition: ged_graph.hpp:104
detail::GedGraphAL::edge_descriptor EdgeID
Internally used edge ID type.
Definition: ged_graph.hpp:110
constexpr LabelID dummy_label()
Returns a dummy label.
constexpr std::size_t undefined()
Returns undefined size.
Global namespace for GEDLIB.
NodeID add_node()
Adds a new vertex to the graph.
Definition: ged_graph.ipp:74
std::size_t NodeID
Internally used vertex ID type.
Definition: ged_graph.hpp:108
bool initialized() const
Checks if graph has already been initialized.
Definition: ged_graph.ipp:229
GraphID id() const
Returns the ID of the graph.
Definition: ged_graph.ipp:184
bool safe_is_edge(NodeID tail, NodeID head) const
Checks if an edge exists.
Definition: ged_graph.ipp:272
void setup_adjacency_matrix()
Prepares the adjacency matrix to allow quick retrieval of edges.
Definition: ged_graph.ipp:95
std::pair< edge_iterator, edge_iterator > edges() const
Provides access to all edge in the graph.
Definition: ged_graph.ipp:217