Milena (Olena)  User documentation 2.0a Id
 All Classes Namespaces Functions Variables Typedefs Enumerator Groups Pages
line_graph.hh
1 // Copyright (C) 2008, 2009, 2010 EPITA Research and Development
2 // Laboratory (LRDE)
3 //
4 // This file is part of Olena.
5 //
6 // Olena is free software: you can redistribute it and/or modify it under
7 // the terms of the GNU General Public License as published by the Free
8 // Software Foundation, version 2 of the License.
9 //
10 // Olena is distributed in the hope that it will be useful,
11 // but WITHOUT ANY WARRANTY; without even the implied warranty of
12 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 // General Public License for more details.
14 //
15 // You should have received a copy of the GNU General Public License
16 // along with Olena. If not, see <http://www.gnu.org/licenses/>.
17 //
18 // As a special exception, you may use this file as part of a free
19 // software project without restriction. Specifically, if other files
20 // instantiate templates or use macros or inline functions from this
21 // file, or you compile this file and link it with other files to produce
22 // an executable, this file does not by itself cause the resulting
23 // executable to be covered by the GNU General Public License. This
24 // exception does not however invalidate any other reasons why the
25 // executable file might be covered by the GNU General Public License.
26 
27 #ifndef MLN_UTIL_LINE_GRAPH_HH
28 # define MLN_UTIL_LINE_GRAPH_HH
29 
33 
34 # include <mln/util/internal/graph_base.hh>
35 # include <mln/util/internal/graph_iter.hh>
36 # include <mln/util/internal/graph_nbh_iter.hh>
37 # include <mln/util/ord_pair.hh>
38 
39 namespace mln
40 {
41 
42  namespace util
43  {
45  template <typename G>
46  class line_graph;
47  }
48 
49 
50  namespace internal
51  {
52 
54  template <typename G>
55  struct data< util::line_graph<G> >
56  {
57  typedef util::line_graph<G> lg_t;
58  typedef std::vector<std::vector<util::edge_id_t> > vertices_t;
59  typedef std::vector<util::ord_pair<util::vertex_id_t> > edges_t;
60 
61  data();
62  data(const G& g);
63  ~data();
64 
65  G g_;
67  vertices_t vertices_;
69  edges_t edges_;
70  };
71 
72  } // end of namespace mln::internal
73 
74 
75  namespace util
76  {
77 
81  template <typename G>
82  class line_graph : public internal::graph_base< line_graph<G> >
83  {
85  typedef internal::graph_base< line_graph<G> > super;
86 
87  typedef typename super::vertex_t vertex_t;
88  typedef typename super::edge_t edge_t;
89 
90  typedef typename super::vertex_data_t vertex_data_t;
91  typedef typename super::edge_data_t edge_data_t;
92 
93  public:
95  typedef std::vector<vertex_data_t> vertices_t;
96 
98  typedef std::vector<edge_data_t> edges_t;
99 
104  typedef mln::internal::vertex_fwd_iterator< line_graph<G> >
105  vertex_fwd_iter;
106  typedef mln::internal::vertex_bkd_iterator< line_graph<G> >
107  vertex_bkd_iter;
108  typedef vertex_fwd_iter vertex_iter;
110 
113  typedef mln::internal::edge_fwd_iterator< line_graph<G> >
115  typedef mln::internal::edge_bkd_iterator< line_graph<G> >
116  edge_bkd_iter;
117  typedef edge_fwd_iter edge_iter;
119 
122  typedef mln::internal::edge_nbh_edge_fwd_iterator< line_graph<G> >
124  typedef mln::internal::edge_nbh_edge_bkd_iterator< line_graph<G> >
125  edge_nbh_edge_bkd_iter;
126  typedef edge_nbh_edge_fwd_iter edge_nbh_edge_iter;
128 
131  typedef mln::internal::vertex_nbh_vertex_fwd_iterator< line_graph<G> >
133  typedef mln::internal::vertex_nbh_vertex_bkd_iterator< line_graph<G> >
134  vertex_nbh_vertex_bkd_iter;
135  typedef vertex_nbh_vertex_fwd_iter vertex_nbh_vertex_iter;
137 
140  typedef mln::internal::vertex_nbh_edge_fwd_iterator< line_graph<G> >
142  typedef mln::internal::vertex_nbh_edge_bkd_iterator< line_graph<G> >
143  vertex_nbh_edge_bkd_iter;
144  typedef vertex_nbh_edge_fwd_iter vertex_nbh_edge_iter;
147 
148  line_graph();
149  line_graph(const G& g);
150 
157  vertex_t vertex(const vertex_id_t& id_v) const;
159 
161  // FIXME: Rename as nvertices.
162  size_t v_nmax() const;
163 
165  // FIXME: Is the `_v' suffix really needed?
166  bool has_v(const vertex_id_t& id_v) const;
167 
169  template <typename G2>
170  bool has(const util::vertex<G2>& v) const;
171 
172 
174  size_t v_nmax_nbh_edges(const vertex_id_t& id_v) const;
175 
177  edge_id_t v_ith_nbh_edge(const vertex_id_t& id_v, unsigned i) const;
178 
180  size_t v_nmax_nbh_vertices(const vertex_id_t& id_v) const;
181 
183  vertex_id_t v_ith_nbh_vertex(const vertex_id_t& id_v, unsigned i) const;
185 
186 
187 
188 
192  edge_t edge(const edge_id_t& e) const;
193 
195  // FIXME: Rename as nedges.
196  size_t e_nmax() const;
197 
199  // FIXME: Is the `_e' suffix really needed?
200  bool has_e(const util::edge_id_t& id_e) const;
201 
203  template <typename G2>
204  bool has(const util::edge<G2>& e) const;
205 
206 
208  vertex_id_t v1(const edge_id_t& id_e) const;
209 
211  vertex_id_t v2(const edge_id_t& id_e) const;
212 
214  size_t e_nmax_nbh_edges(const edge_id_t& id_e) const;
215 
217  edge_id_t e_ith_nbh_edge(const edge_id_t& id_e, unsigned i) const;
218 
221  template <typename G2>
222  bool is_subgraph_of(const G2& g) const;
223 
225  const G& graph() const;
227 
228  protected:
229  using super::data_;
230  };
231 
232  template <typename G>
233  std::ostream&
234  operator<<(std::ostream& ostr, const line_graph<G>& g);
235 
236  } // end of namespace mln::util
237 
238 } // end of namespace mln
239 
240 # ifndef MLN_INCLUDE_ONLY
241 
242 namespace mln
243 {
244 
245  namespace internal
246  {
247 
248  template <typename G>
249  inline
251  {
252  }
253 
254  template <typename G>
255  inline
256  data< util::line_graph<G> >::data(const G& g)
257  {
258  g_ = g;
259 
260  // Initialize vertices and edges.
261  // FIXME: use an adjacency matrix!!
262  std::set<util::ord_pair<util::vertex_id_t> > edges_set;
263 
264  vertices_.resize(g.e_nmax());
265  mln_edge_iter(G) e(g);
266  mln_edge_nbh_edge_iter(G) ne(e);
267 
268  for_all(e)
269  {
270  util::vertex_id_t v1(e.id().value());
271  for_all(ne)
272  {
273  util::vertex_id_t v2(ne.id().value());
274  util::ord_pair<util::vertex_id_t> edge(v1, v2);
275  if (edges_set.find(edge) == edges_set.end())
276  {
277  vertices_[v1].push_back(edges_.size());
278  vertices_[v2].push_back(edges_.size());
279  edges_set.insert(edge);
280  edges_.push_back(edge);
281  }
282  }
283  }
284  }
285 
286  template <typename G>
287  inline
288  data< util::line_graph<G> >::~data()
289  {
290  }
291 
292  } // end of namespace mln::internal
293 
294  namespace util
295  {
296 
297  template <typename G>
298  inline
300  {
301  this->data_ = new mln::internal::data< util::line_graph<G> >();
302  }
303 
304  template <typename G>
305  inline
306  line_graph<G>::line_graph(const G& g)
307  {
308  this->data_ = new mln::internal::data< util::line_graph<G> >(g);
309  }
310 
311  /*---------------.
312  | Vertex related |
313  `---------------*/
314 
315  template <typename G>
316  inline
317  typename line_graph<G>::vertex_t
319  {
320  mln_assertion(has_v(id_v));
321  return vertex_t(*this, id_v);
322  }
323 
324 
325  template <typename G>
326  inline
327  size_t
329  {
330  return data_->g_.e_nmax();
331  }
332 
333  template <typename G>
334  inline
335  bool
337  {
338  return data_->g_.has_v(id_v);
339  }
340 
341  template <typename G>
342  template <typename G2>
343  inline
344  bool
346  {
347  // FIXME: not sure...
348  return v.graph().is_subgraph_of(*this) && has_v(v.id());
349  }
350 
351  template <typename G>
352  inline
353  size_t
355  {
356  mln_precondition(has_v(id_v));
357  return data_->vertices_[id_v].size();
358  }
359 
360  template <typename G>
361  inline
362  edge_id_t
363  line_graph<G>::v_ith_nbh_edge(const vertex_id_t& id_v, unsigned i) const
364  {
365  mln_precondition(has_v(id_v));
366  if (i >= v_nmax_nbh_edges(id_v))
367  return v_nmax();
368  return data_->vertices_[id_v][i];
369  }
370 
371  template <typename G>
372  inline
373  size_t
375  {
376  mln_precondition(has_v(id_v));
377  return v_nmax_nbh_edges(id_v);
378  }
379 
380  template <typename G>
381  inline
383  line_graph<G>::v_ith_nbh_vertex(const vertex_id_t& id_v, unsigned i) const
384  {
385  mln_precondition(has_v(id_v));
386 
387  unsigned id_e = this->v_ith_nbh_edge(id_v, i);
388  return this->v_other(id_e, id_v);
389  }
390 
391 
392  /*--------------.
393  | Edges related |
394  `---------------*/
395 
396  template <typename G>
397  inline
398  typename line_graph<G>::edge_t
400  {
401  mln_assertion(e < e_nmax());
402  return edge_t(*this, e);
403  }
404 
405  template <typename G>
406  inline
407  size_t
409  {
410  return data_->edges_.size();
411  }
412 
413  template <typename G>
414  inline
415  bool
416  line_graph<G>::has_e(const edge_id_t& id_e) const
417  {
418  return id_e < data_->edges_.size();
419  }
420 
421  template <typename G>
422  template <typename G2>
423  inline
424  bool
426  {
427  return e.graph().is_subgraph_of(*this) && has_e(e.id());
428  }
429 
430  template <typename G>
431  inline
433  line_graph<G>::v1(const edge_id_t& id_e) const
434  {
435  mln_precondition(has_e(id_e));
436  return data_->edges_[id_e].first();
437  }
438 
439  template <typename G>
440  inline
442  line_graph<G>::v2(const edge_id_t& id_e) const
443  {
444  mln_precondition(has_e(id_e));
445  return data_->edges_[id_e].second();
446  }
447 
448  template <typename G>
449  inline
450  size_t
451  line_graph<G>::e_nmax_nbh_edges(const edge_id_t& id_e) const
452  {
453  mln_precondition(has_e(id_e));
454  return v_nmax_nbh_edges(v1(id_e)) + v_nmax_nbh_edges(v2(id_e));
455  }
456 
457  template <typename G>
458  inline
459  edge_id_t
460  line_graph<G>::e_ith_nbh_edge(const edge_id_t& id_e, unsigned i) const
461  {
462  mln_precondition(has_e(id_e));
463  if (i >= e_nmax_nbh_edges(id_e))
464  return e_nmax();
465 
466  unsigned v1_nmax = v_nmax_nbh_edges(v1(id_e));
467  if (i < v1_nmax)
468  return v_ith_nbh_edge(v1(id_e), i);
469  return v_ith_nbh_edge(v2(id_e), i - v1_nmax);
470  }
471 
472 
473  template <typename G>
474  template <typename G2>
475  inline
476  bool
477  line_graph<G>::is_subgraph_of(const G2& g) const
478  {
479  return g.id() == this->id();
480  }
481 
482  template <typename G>
483  inline
484  const G&
486  {
487  return this->data_->g_;
488  }
489 
490  // FIXME: move to graph_base
491  template <typename G>
492  inline
493  std::ostream&
494  operator<<(std::ostream& ostr, const line_graph<G>& g)
495  {
496  typedef line_graph<G> LG;
497  mln_vertex_iter(LG) v(g);
498  mln_vertex_nbh_edge_iter(LG) e(v);
499  for_all(v)
500  {
501  ostr << "v(" << v << ") : ";
502  for_all(e)
503  ostr << e << " ";
504  ostr << std::endl;
505  }
506 
507  return ostr;
508  }
509 
510  } // end of namespace mln::util
511 
512 } // end of namespace mln
513 
514 # endif // ! MLN_INCLUDE_ONLY
515 
516 
517 #endif // ! MLN_UTIL_LINE_GRAPH_HH