Claw  1.7.3
graph.tpp
Go to the documentation of this file.
1 /*
2  CLAW - a C++ Library Absolutely Wonderful
3 
4  CLAW is a free library without any particular aim but being useful to
5  anyone.
6 
7  Copyright (C) 2005-2011 Julien Jorge
8 
9  This library is free software; you can redistribute it and/or
10  modify it under the terms of the GNU Lesser General Public
11  License as published by the Free Software Foundation; either
12  version 2.1 of the License, or (at your option) any later version.
13 
14  This library is distributed in the hope that it will be useful,
15  but WITHOUT ANY WARRANTY; without even the implied warranty of
16  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
17  Lesser General Public License for more details.
18 
19  You should have received a copy of the GNU Lesser General Public
20  License along with this library; if not, write to the Free Software
21  Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
22 
23  contact: julien.jorge@gamned.org
24 */
30 #include <cassert>
31 #include <algorithm>
32 
33 #include <claw/functional.hpp>
34 
35 /*---------------------------------------------------------------------------*/
40  : m_msg("No message")
41 {
42 
43 } // graph_exception()
44 
45 /*---------------------------------------------------------------------------*/
50 claw::graph_exception::graph_exception( const std::string& s) throw()
51  : m_msg(s)
52 {
53 
54 } // graph_exception()
55 
56 /*---------------------------------------------------------------------------*/
61 {
62 
63 } // ~graph_exception()
64 
65 /*---------------------------------------------------------------------------*/
69 const char* claw::graph_exception::what() const throw()
70 {
71  return m_msg.c_str();
72 } // what()
73 
74 
75 
76 
77 /*---------------------------------------------------------------------------*/
81 template <class S, class A, class Comp>
83 {
84 
85 } // graph_vertex_iterator() [constructor]
86 
87 /*---------------------------------------------------------------------------*/
92 template <class S, class A, class Comp>
95 {
96  ++m_iterator;
97  return *this;
98 } // operator++() [preincrement]
99 
100 /*---------------------------------------------------------------------------*/
105 template <class S, class A, class Comp>
108 {
109  graph_vertex_iterator it_tmp(*this);
110  m_iterator++;
111  return *this;
112 } // operator++() [postincrement]
113 
114 /*---------------------------------------------------------------------------*/
119 template <class S, class A, class Comp>
122 {
123  --m_iterator;
124  return *this;
125 } // operator--() [predecrement]
126 
127 /*---------------------------------------------------------------------------*/
132 template <class S, class A, class Comp>
135 {
136  graph_vertex_iterator it_tmp(*this);
137  m_iterator--;
138  return it_tmp;
139 } // operator--() [postdecrement]
140 
141 /*---------------------------------------------------------------------------*/
146 template <class S, class A, class Comp>
147 typename claw::graph<S, A, Comp>::graph_vertex_iterator::reference
149 {
150  return m_iterator->first;
151 } // operator*()
152 
153 /*---------------------------------------------------------------------------*/
158 template <class S, class A, class Comp>
159 typename claw::graph<S, A, Comp>::graph_vertex_iterator::pointer
161 {
162  return &(m_iterator->first);
163 } // operator->()
164 
165 /*---------------------------------------------------------------------------*/
171 template <class S, class A, class Comp>
173 (const graph_vertex_iterator& it) const
174 {
175  return m_iterator == it.m_iterator;
176 } // operator==()
177 
178 /*---------------------------------------------------------------------------*/
184 template <class S, class A, class Comp>
185 bool claw::graph<S, A, Comp>::graph_vertex_iterator::operator!=
186 (const graph_vertex_iterator& it) const
187 {
188  return m_iterator != it.m_iterator;
189 } // operator!=()
190 
191 /*---------------------------------------------------------------------------*/
196 template <class S, class A, class Comp>
198 (typename graph_content::const_iterator it)
199  : m_iterator(it)
200 {
201 
202 } // graph_vertex_iterator() [constructor on an iterator]
203 
204 
205 
206 
207 /*---------------------------------------------------------------------------*/
211 template <class S, class A, class Comp>
213  : m_label(NULL), m_source(NULL), m_target(NULL)
214 {
215 
216 } // edge::edge [constructor]
217 
218 /*---------------------------------------------------------------------------*/
222 template <class S, class A, class Comp>
223 const typename claw::graph<S, A, Comp>::edge_type&
225 {
226  assert(m_label != NULL);
227  return *m_label;
228 } // edge::label()
229 
230 /*---------------------------------------------------------------------------*/
234 template <class S, class A, class Comp>
237 {
238  assert(m_source != NULL);
239  return *m_source;
240 } // edge::source()
241 
242 /*---------------------------------------------------------------------------*/
246 template <class S, class A, class Comp>
249 {
250  assert(m_target != NULL);
251  return *m_target;
252 } // edge::target()
253 
254 /*---------------------------------------------------------------------------*/
258 template <class S, class A, class Comp>
260 set( const edge_type& l, const vertex_type& s, const vertex_type& t )
261 {
262  m_label = &l;
263  m_source = &s;
264  m_target = &t;
265 } // edge::set()
266 
267 
268 
269 
270 /*---------------------------------------------------------------------------*/
274 template <class S, class A, class Comp>
276 {
277 
278 } // graph_edge_iterator() [constructor]
279 
280 /*---------------------------------------------------------------------------*/
285 template <class S, class A, class Comp>
288 {
289  bool ok = true;
290  ++m_neighbours_iterator;
291 
292  // end of a neighbourhood
293  if ( m_neighbours_iterator == m_vertex_iterator->second.end() )
294  {
295  // find next edge or end.
296  ok = false;
297  ++m_vertex_iterator;
298 
299  while ( (m_vertex_iterator != m_vertex_end) && !ok )
300  if ( !m_vertex_iterator->second.empty() )
301  {
302  ok = true;
303  m_neighbours_iterator = m_vertex_iterator->second.begin();
304  }
305  else
306  ++m_vertex_iterator;
307  }
308 
309  if (ok)
310  m_edge.set( m_neighbours_iterator->second, m_vertex_iterator->first,
311  m_neighbours_iterator->first );
312 
313  return *this;
314 } // operator++() [preincrement]
315 
316 /*---------------------------------------------------------------------------*/
321 template <class S, class A, class Comp>
324 {
325  graph_edge_iterator it_tmp(*this);
326  ++(*this);
327  return it_tmp;
328 } // operator++() [postincrement]
329 
330 /*---------------------------------------------------------------------------*/
335 template <class S, class A, class Comp>
338 {
339  bool ok = true;
340 
341  if (m_vertex_iterator == m_vertex_end)
342  {
343  --m_vertex_iterator;
344  m_neighbours_iterator = m_vertex_iterator->second.end();
345  }
346 
347  // begining of a neighbourhood
348  if ( m_neighbours_iterator == m_vertex_iterator->second.begin() )
349  {
350  ok = false;
351  // find previous edge or begining.
352  while ( (m_vertex_iterator != m_vertex_begin) && !ok )
353  {
354  --m_vertex_iterator;
355  if ( !m_vertex_iterator->second.empty() )
356  {
357  ok = true;
358  m_neighbours_iterator = --m_vertex_iterator->second.end();
359  }
360  }
361  }
362  else
363  --m_neighbours_iterator;
364 
365  if (!ok)
366  m_vertex_iterator == m_vertex_end;
367  else
368  m_edge.set( m_neighbours_iterator->second, m_vertex_iterator->first,
369  m_neighbours_iterator->first );
370 
371  return *this;
372 } // operator--() [predecrement]
373 
374 /*---------------------------------------------------------------------------*/
379 template <class S, class A, class Comp>
382 {
383  graph_edge_iterator it_tmp(*this);
384  --(*this);
385  return it_tmp;
386 } // operator--() [postdecrement]
387 
388 /*---------------------------------------------------------------------------*/
393 template <class S, class A, class Comp>
396 {
397  return m_edge;
398 } // operator*()
399 
400 /*---------------------------------------------------------------------------*/
405 template <class S, class A, class Comp>
406 typename claw::graph<S, A, Comp>::graph_edge_iterator::pointer
408 {
409  return &m_edge;
410 } // operator->()
411 
412 /*---------------------------------------------------------------------------*/
418 template <class S, class A, class Comp>
420 (const graph_edge_iterator& it) const
421 {
422  // both are empty
423  if ( m_vertex_begin == m_vertex_end )
424  return (it.m_vertex_begin == it.m_vertex_end)
425  && (m_vertex_begin == it.m_vertex_begin);
426  else
427  if ( it.m_vertex_begin == it.m_vertex_end ) // -it- is empty
428  return false;
429  else
430  // none is empty, perheaps at the end ?
431  if (m_vertex_iterator == m_vertex_end)
432  return (it.m_vertex_iterator == it.m_vertex_end)
433  && (m_vertex_begin == it.m_vertex_begin);
434  else
435  if (it.m_vertex_iterator == it.m_vertex_end)
436  return false;
437  else
438  return m_neighbours_iterator == it.m_neighbours_iterator;
439 } // operator==()
440 
441 /*---------------------------------------------------------------------------*/
447 template <class S, class A, class Comp>
448 bool claw::graph<S, A, Comp>::graph_edge_iterator::operator!=
449 (const graph_edge_iterator& it) const
450 {
451  return !(*this == it);
452 } // operator!=()
453 
454 /*---------------------------------------------------------------------------*/
462 template <class S, class A, class Comp>
464 ( typename graph_content::const_iterator it_begin,
465  typename graph_content::const_iterator it_end,
466  typename graph_content::const_iterator it_s,
467  typename neighbours_list::const_iterator it_d)
468  : m_vertex_begin(it_begin), m_vertex_end(it_end),
469  m_vertex_iterator(it_s), m_neighbours_iterator(it_d)
470 {
471  if (m_vertex_begin != m_vertex_end)
472  m_edge.set( m_neighbours_iterator->second, m_vertex_iterator->first,
473  m_neighbours_iterator->first );
474 } // graph_edge_iterator() [constructor on an iterator]
475 
476 
477 
478 
479 /*---------------------------------------------------------------------------*/
483 template <class S, class A, class Comp>
485  : m_edges_count(0)
486 {
487 
488 } // graph::graph() [constructor]
489 
490 /*---------------------------------------------------------------------------*/
497 template <class S, class A, class Comp>
499 ( const vertex_type& s1, const vertex_type& s2, const edge_type& e )
500 {
501  if ( !edge_exists(s1, s2) )
502  {
503  // s2 is not a neighbor of s1
504  ++m_edges_count;
505 
506  add_vertex(s1);
507  add_vertex(s2);
508 
509  // in all cases, s2 as one more inner edge
510  ++m_inner_degrees[s2];
511  }
512 
513  m_edges[s1][s2] = e;
514 } // graph::add_edge()
515 
516 /*---------------------------------------------------------------------------*/
521 template <class S, class A, class Comp>
523 {
524  std::pair<S, neighbours_list> p;
525 
526  if (m_edges.find(s) == m_edges.end())
527  {
528  // Add the vertex in the adjacency list.
529  p.first = s;
530  m_edges.insert(p);
531  m_inner_degrees[s] = 0;
532  }
533 } // graph::add_vertex()
534 
535 /*---------------------------------------------------------------------------*/
541 template <class S, class A, class Comp>
543 ( const vertex_type& s, const vertex_type& r ) const
544 {
545  typename graph_content::const_iterator it = m_edges.find(s);
546 
547  if ( it == m_edges.end() )
548  return false;
549  else
550  return it->second.find(r) != it->second.end();
551 } // graph::edge_exists()
552 
553 /*---------------------------------------------------------------------------*/
559 template <class S, class A, class Comp>
561 (const vertex_type& s, std::vector<vertex_type>& v) const
562 {
563  typename graph_content::const_iterator it_s = m_edges.find(s);
564  v.clear();
565 
566  if ( it_s != m_edges.end() )
567  {
568  v.resize( it_s->second.size() );
569  std::transform( it_s->second.begin(), it_s->second.end(), v.begin(),
570  const_first<S,A>() );
571  }
572 } // graph::neighbours()
573 
574 /*---------------------------------------------------------------------------*/
579 template <class S, class A, class Comp>
580 void claw::graph<S, A, Comp>::vertices(std::vector<vertex_type>& v) const
581 {
582  v.clear();
583  v.resize(m_edges.size());
584 
585  std::transform( m_edges.begin(), m_edges.end(), v.begin(),
587 } // graph::vertices()
588 
589 /*---------------------------------------------------------------------------*/
594 template <class S, class A, class Comp>
597 {
598  return vertex_iterator( m_edges.begin() );
599 } // graph::vertex_begin()
600 
601 /*---------------------------------------------------------------------------*/
605 template <class S, class A, class Comp>
608 {
609  return vertex_iterator( m_edges.end() );
610 } // graph::vertex_end()
611 
612 /*---------------------------------------------------------------------------*/
617 template <class S, class A, class Comp>
620 {
621  return vertex_iterator( m_edges.find(s) );
622 } // graph::vertex_begin()
623 
624 /*---------------------------------------------------------------------------*/
629 template <class S, class A, class Comp>
630 typename claw::graph<S, A, Comp>::reverse_vertex_iterator
632 {
633  return reverse_vertex_iterator( vertex_end() );
634 } // graph::vertex_rbegin()
635 
636 /*---------------------------------------------------------------------------*/
640 template <class S, class A, class Comp>
641 typename claw::graph<S, A, Comp>::reverse_vertex_iterator
643 {
644  return reverse_vertex_iterator( vertex_begin() );
645 } // graph::vertex_rend()
646 
647 /*---------------------------------------------------------------------------*/
652 template <class S, class A, class Comp>
653 typename claw::graph<S, A, Comp>::reverse_vertex_iterator
655 {
656  vertex_iterator it = vertex_begin(s);
657 
658  if (it != vertex_end())
659  ++it;
660 
661  return reverse_vertex_iterator( it );
662 } // graph::vertex_rbegin()
663 
664 /*---------------------------------------------------------------------------*/
669 template <class S, class A, class Comp>
672 {
673  bool ok = false;
674  typename graph_content::const_iterator it_s;
675  it_s = m_edges.begin();
676 
677  while ( (it_s != m_edges.end()) && !ok )
678  if ( it_s->second.empty() )
679  ++it_s;
680  else
681  ok = true;
682 
683  if (ok)
684  return edge_iterator( m_edges.begin(), m_edges.end(), it_s,
685  it_s->second.begin() );
686  else
687  return edge_end();
688 
689 } // graph::edge_begin()
690 
691 /*---------------------------------------------------------------------------*/
695 template <class S, class A, class Comp>
698 {
699  return edge_iterator( m_edges.begin(), m_edges.end(), m_edges.end(),
700  typename neighbours_list::const_iterator() );
701 } // graph::edge_end()
702 
703 /*---------------------------------------------------------------------------*/
708 template <class S, class A, class Comp>
711 ( const vertex_type& s1, const vertex_type& s2 ) const
712 {
713  if ( edge_exists(s1, s2) )
714  {
715  typename graph_content::const_iterator it_s1;
716 
717  it_s1 = m_edges.find(s1);
718  return edge_iterator( m_edges.begin(), m_edges.end(), it_s1,
719  it_s1->second.find(s2) );
720  }
721  else
722  return edge_end();
723 } // graph::edge_()
724 
725 /*---------------------------------------------------------------------------*/
730 template <class S, class A, class Comp>
731 typename claw::graph<S, A, Comp>::reverse_edge_iterator
733 {
734  return reverse_edge_iterator( edge_end() );
735 } // graph::edge_rbegin()
736 
737 /*---------------------------------------------------------------------------*/
741 template <class S, class A, class Comp>
742 typename claw::graph<S, A, Comp>::reverse_edge_iterator
744 {
745  return reverse_edge_iterator( edge_begin() );
746 } // graph::edge_rend()
747 
748 /*---------------------------------------------------------------------------*/
753 template <class S, class A, class Comp>
754 typename claw::graph<S, A, Comp>::reverse_edge_iterator
756 ( const vertex_type& s1, const vertex_type& s2 ) const
757 {
758  reverse_edge_iterator it = edge_begin(s1, s2);
759 
760  if ( it != edge_end() )
761  ++it;
762 
763  return reverse_edge_iterator( it );
764 } // graph::edge_rbegin()
765 
766 /*---------------------------------------------------------------------------*/
772 template <class S, class A, class Comp>
773 const typename claw::graph<S, A, Comp>::edge_type&
775 ( const vertex_type& s, const vertex_type& r ) const
776 {
777  typename graph_content::const_iterator it_s = m_edges.find(s);
778 
779  if ( it_s == m_edges.end() )
780  throw graph_exception
781  ("claw::graph::label(): unkonwn source vertex.");
782  else
783  {
784  typename neighbours_list::const_iterator it_r = it_s->second.find(r);
785 
786  if ( it_r == it_s->second.end() )
787  throw graph_exception
788  ("claw::graph::label(): destination is not a neighbor.");
789  else
790  return it_r->second;
791  }
792 } // graph::label()
793 
794 /*---------------------------------------------------------------------------*/
799 template <class S, class A, class Comp>
801 {
802  typename graph_content::const_iterator it = m_edges.find(s);
803 
804  if (it == m_edges.end())
805  throw graph_exception("claw::graph::outer_degree(): unknown vertex.");
806  else
807  return it->second.size();
808 } // graph::outer_degree()
809 
810 /*---------------------------------------------------------------------------*/
815 template <class S, class A, class Comp>
817 {
818  typename std::map<S, std::size_t, Comp>::const_iterator it;
819  it = m_inner_degrees.find(s);
820 
821  if (it == m_inner_degrees.end())
822  throw graph_exception
823  ("claw::graph::inner_degree(): unkown vertex.");
824  else
825  return it->second;
826 } // graph::inner_degree()
827 
828 /*---------------------------------------------------------------------------*/
832 template <class S, class A, class Comp>
834 {
835  return m_edges.size();
836 } // graph::vertices_count()
837 
838 /*---------------------------------------------------------------------------*/
842 template <class S, class A, class Comp>
844 {
845  return m_edges_count;
846 } // graph::edges_count()
847