adj_list.h
Go to the documentation of this file.
1 /*
2  * This file is part of the alglib project.
3  *
4  * (c) Divyanshu Kakwani <divkakwani@gmail.com>
5  *
6  * For the full copyright and license information, please view the LICENSE file
7  * that was distributed with this source code.
8  */
9 
10 #include <iostream>
11 #include <map>
12 #include <functional>
13 #include <boost/iterator/transform_iterator.hpp>
15 #include <stdexcept>
16 
17 #pragma once
18 
19 
24 template<typename T>
25 struct get_first : public std::unary_function<T, typename T::first_type> {
26 
27  typename T::first_type operator() (const T& p) const { return p.first; }
28 };
29 
30 /* auto select1st = [](auto const& pair) { return pair.first; } */
31 
36 template<typename T>
37 struct get_second : public std::unary_function<T, typename T::second_type> {
38 
39  typename T::second_type operator() (const T& p) const { return p.second; }
40 };
41 
42 namespace alglib {
43 namespace graph {
44 namespace models {
45 
51 template<typename vertex_t, typename edge_t>
52 class adj_list : public graph_model<vertex_t, edge_t> {
53 
54  public:
55 
56  typedef vertex_t vertex_type;
57  typedef edge_t edge_type;
58 
60  bool are_adj (const vertex_t&, const vertex_t&) const;
61 
62  void add_vertex (const vertex_t& v);
63  void add_edge (const vertex_t& u, const vertex_t& v, const edge_t& a);
64  void add_edge (const edge_t& e);
65  void remove_vertex (const vertex_t& v);
66  void remove_edge (const vertex_t& u, const vertex_t& v);
67 
68  int indeg (const vertex_t& v) const;
69  int outdeg (const vertex_t& v) const;
70 
71  int num_vertices () const;
72  int num_edges () const;
73 
74 
75  private:
76  typedef std::map<vertex_t, edge_t> alist_t;
77  typedef std::map<vertex_t, alist_t> alists_t;
78 
81 
84 
85  public:
86 
88  typedef boost::transform_iterator<get_first<std::pair<vertex_t, alist_t>>,
89  typename std::map<vertex_t, alist_t>::const_iterator>
91 
92  typedef boost::transform_iterator<get_first<std::pair<vertex_t, edge_t>>,
93  typename std::map<vertex_t, edge_t>::const_iterator>
95  typedef boost::transform_iterator<get_second<std::pair<vertex_t, edge_t>>,
96  typename std::map<vertex_t, edge_t>::const_iterator>
98 
99  class const_eiterator;
100  friend class const_iterator;
101 
102  const_viterator vbegin() const noexcept {
103  return boost::make_transform_iterator(alists.cbegin(), get_vertex);
104  }
105  const_viterator vend() const noexcept {
106  return boost::make_transform_iterator(alists.cend(), get_vertex);
107  }
108  const_eiterator ebegin() const noexcept {
109  return const_eiterator(*this);
110  }
111  const_eiterator eend() const noexcept {
112  const_eiterator it(*this);
113  it.vit = alists.end();
114  return it;
115  }
116  const_aviterator avbegin(const vertex_t& u) const {
117  typename alists_t::const_iterator it;
118  if((it = alists.find(u)) == alists.end())
119  throw std::out_of_range("The vertex doesn't exist");
120  return boost::make_transform_iterator((it->second).cbegin(), get_avertex);
121  }
122 
123  const_aviterator avend(const vertex_t& u) const {
124  typename alists_t::const_iterator it;
125  if((it = alists.find(u)) == alists.end())
126  throw std::out_of_range("The vertex doesn't exist");
127  return boost::make_transform_iterator((it->second).cend(), get_avertex);
128  }
129 
130  const_aeiterator aebegin(const vertex_t& u) const {
131  typename alists_t::const_iterator it;
132  if((it = alists.find(u)) == alists.end())
133  throw std::out_of_range("The vertex doesn't exist");
134  return boost::make_transform_iterator((it->second).cbegin(), get_aedge);
135  }
136 
137  const_aeiterator aeend(const vertex_t& u) const {
138  typename alists_t::const_iterator it;
139  if((it = alists.find(u)) == alists.end())
140  throw std::out_of_range("The vertex doesn't exist");
141  return boost::make_transform_iterator((it->second).cend(), get_aedge);
142  }
143 
144  private:
145 
146  std::map<vertex_t, alist_t> alists;
147 
148 };
149 
150 
151 template<typename vertex_t, typename edge_t>
152 inline void adj_list<vertex_t, edge_t>::add_vertex(const vertex_t& v) {
158  if(alists.find(v) == alists.end())
159  alists[v] = alist_t();
160 }
161 
162 template<typename vertex_t, typename edge_t>
163 inline void adj_list<vertex_t, edge_t>::add_edge(const vertex_t& u,
164  const vertex_t& v,
165  const edge_t& e) {
172  add_vertex(u);
173  add_vertex(v);
174 
175  alists[u][v] = e;
176 }
177 
178 template<typename vertex_t, typename edge_t>
185  add_vertex(e.from);
186  add_vertex(e.to);
187 
188  alists[e.from][e.to] = e;
189 }
190 
191 template<typename vertex_t, typename edge_t>
192 inline void adj_list<vertex_t, edge_t>::remove_vertex(const vertex_t& v){
199  alists.erase(v);
200 
201  for(auto& entry : alists) {
202  entry.second.erase(v);
203  }
204 }
205 
206 template<typename vertex_t, typename edge_t>
207 inline void adj_list<vertex_t, edge_t>::remove_edge(const vertex_t& u,
208  const vertex_t& v) {
213  alists[u].erase(v);
214 }
215 
216 template<typename vertex_t, typename edge_t>
217 inline int adj_list<vertex_t, edge_t>::indeg(const vertex_t& v) const {
223  int deg = 0;
224 
225  for(auto& entry : alists) {
226  auto& alist = entry.second;
227  if(alist.find(v) != alist.end())
228  deg++;
229  }
230  return deg;
231 }
232 
233 template<typename vertex_t, typename edge_t>
234 inline int adj_list<vertex_t, edge_t>::outdeg(const vertex_t& v) const {
239  return alists.at(v).size();
240 }
241 
242 template<typename vertex_t, typename edge_t>
248  return alists.size();
249 }
250 
251 template<typename vertex_t, typename edge_t>
258  int sum = 0;
259  for(auto& entry : alists)
260  sum += entry.second.size();
261  return sum;
262 }
263 
264 
265 template<typename vertex_t, typename edge_t>
266 inline bool adj_list<vertex_t, edge_t>::are_adj(const vertex_t& u,
267  const vertex_t& v) const {
274  return alists.at(u).find(v) != alists.at(u).end();
275 }
276 
277 template<typename vertex_t, typename edge_t>
278 class adj_list<vertex_t, edge_t>::const_eiterator {
279 
280  private:
281  typename alist_t::const_iterator ait;
282  typename alists_t::const_iterator vit;
284 
286 
287  friend class adj_list<vertex_t, edge_t>;
288 
289  template<typename t1, typename t2>
290  friend std::ostream& operator<<(std::ostream& out,
291  typename adj_list<t1, t2>::const_eiterator cit);
292 
293 
294  public:
295 
296  const_eiterator() = delete;
297 
298  explicit const_eiterator(const adj_list<vertex_t, edge_t>& graph) : G(graph) {
299  if(G.alists.size() != 0) {
300  vit = G.alists.cbegin();
301  ait = (vit->second).cbegin();
302  }
303  }
304 
305  const_eiterator(const const_eiterator& eit) : G(eit.G){
306  vit = eit.vit;
307  ait = eit.ait;
308  }
309 
310  // Prefix increment
312  ait++;
313  while(vit != G.alists.cend() and ait == (vit->second).cend()) {
314  vit++;
315  ait = (vit->second).cbegin();
316  }
317  return ait->second;
318  }
319 
320  // prefix decrement
322  if(ait == (vit->second).cbegin()) {
323  while(vit != G.alists.cbegin() and (vit->second).cbegin() == (vit->second).cend())
324  vit--;
325  ait = --((vit->second).cend());
326  } else {
327  ait--;
328  }
329  }
330 
331  // postfix increment
333  outer::edge_type e = ait->second;
334  ++(*this);
335  return e;
336  }
337 
338  // postfix decrement
340  outer::edge_type e = ait->second;
341  --(*this);
342  return e;
343  }
344 
345  const edge_t& operator*() {
346  return ait->second;
347  }
348 
349  bool operator==(const const_eiterator& other) const {
350  return (vit == other.vit && ait == other.ait) ||
351  (vit == other.vit && vit == G.alists.end());
352  }
353 
354  bool operator!=(const const_eiterator& other) const {
355  return !(*this == other);
356  }
357 
358 };
359 
360 
361 template<typename vertex_t, typename edge_t>
362 std::ostream& operator<<(std::ostream& out,
364  out << *(eit.ait).second;
365  return out;
366 }
367 
368 } // end of models namespace
369 } // end of graph namespace
370 } // end of alglib namespace
371 
372 
const outer::edge_type & operator++()
Definition: adj_list.h:311
void add_vertex(const vertex_t &v)
Definition: adj_list.h:152
void add_edge(const vertex_t &u, const vertex_t &v, const edge_t &a)
Definition: adj_list.h:163
bool operator!=(const const_eiterator &other) const
Definition: adj_list.h:354
outer::edge_type operator--(int)
Definition: adj_list.h:339
const_aviterator avend(const vertex_t &u) const
Definition: adj_list.h:123
int outdeg(const vertex_t &v) const
Definition: adj_list.h:234
bool operator==(const const_eiterator &other) const
Definition: adj_list.h:349
Definition: bimap.h:17
const_viterator vend() const noexcept
Definition: adj_list.h:105
boost::transform_iterator< get_second< std::pair< vertex_t, edge_t > >, typename std::map< vertex_t, edge_t >::const_iterator > const_aeiterator
Definition: adj_list.h:97
const_eiterator ebegin() const noexcept
Definition: adj_list.h:108
const_aviterator avbegin(const vertex_t &u) const
Definition: adj_list.h:116
The interface of a graph model.
Definition: graph_model.h:25
T::second_type operator()(const T &p) const
Definition: adj_list.h:39
const outer::edge_type & operator--()
Definition: adj_list.h:321
boost::transform_iterator< get_first< std::pair< vertex_t, alist_t > >, typename std::map< vertex_t, alist_t >::const_iterator > const_viterator
Iterators.
Definition: adj_list.h:90
Definition: adj_list.h:25
Definition: edge.h:19
const_aeiterator aeend(const vertex_t &u) const
Definition: adj_list.h:137
T::first_type operator()(const T &p) const
Definition: adj_list.h:27
const_eiterator eend() const noexcept
Definition: adj_list.h:111
void remove_edge(const vertex_t &u, const vertex_t &v)
Definition: adj_list.h:207
int indeg(const vertex_t &v) const
Definition: adj_list.h:217
friend class const_iterator
Definition: adj_list.h:99
boost::transform_iterator< get_first< std::pair< vertex_t, edge_t > >, typename std::map< vertex_t, edge_t >::const_iterator > const_aviterator
Definition: adj_list.h:94
Definition: adj_list.h:52
const_eiterator(const const_eiterator &eit)
Definition: adj_list.h:305
const_aeiterator aebegin(const vertex_t &u) const
Definition: adj_list.h:130
vertex_t to
Definition: edge.h:22
int num_edges() const
Definition: adj_list.h:252
outer::edge_type operator++(int)
Definition: adj_list.h:332
edge_t edge_type
Definition: adj_list.h:57
int num_vertices() const
Definition: adj_list.h:243
void remove_vertex(const vertex_t &v)
Definition: adj_list.h:192
const_eiterator(const adj_list< vertex_t, edge_t > &graph)
Definition: adj_list.h:298
std::ostream & operator<<(std::ostream &out, typename adj_list< vertex_t, edge_t >::const_eiterator eit)
Definition: adj_list.h:362
Definition: adj_list.h:37
vertex_t from
Definition: edge.h:21
const_viterator vbegin() const noexcept
Definition: adj_list.h:102
const edge_t & operator*()
Definition: adj_list.h:345
bool are_adj(const vertex_t &, const vertex_t &) const
Returs true if the two given vertices are adjacent, otherwise false.
Definition: adj_list.h:266
vertex_t vertex_type
Definition: adj_list.h:56