[ VIGRA Homepage | Function Index | Class Index | Namespaces | File List | Main Page ]

multi_gridgraph.hxx VIGRA

1 /************************************************************************/
2 /* */
3 /* Copyright 2011-2012 by Stefan Schmidt and Ullrich Koethe */
4 /* */
5 /* This file is part of the VIGRA computer vision library. */
6 /* The VIGRA Website is */
7 /* http://hci.iwr.uni-heidelberg.de/vigra/ */
8 /* Please direct questions, bug reports, and contributions to */
9 /* ullrich.koethe@iwr.uni-heidelberg.de or */
10 /* vigra@informatik.uni-hamburg.de */
11 /* */
12 /* Permission is hereby granted, free of charge, to any person */
13 /* obtaining a copy of this software and associated documentation */
14 /* files (the "Software"), to deal in the Software without */
15 /* restriction, including without limitation the rights to use, */
16 /* copy, modify, merge, publish, distribute, sublicense, and/or */
17 /* sell copies of the Software, and to permit persons to whom the */
18 /* Software is furnished to do so, subject to the following */
19 /* conditions: */
20 /* */
21 /* The above copyright notice and this permission notice shall be */
22 /* included in all copies or substantial portions of the */
23 /* Software. */
24 /* */
25 /* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND */
26 /* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES */
27 /* OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND */
28 /* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT */
29 /* HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, */
30 /* WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING */
31 /* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR */
32 /* OTHER DEALINGS IN THE SOFTWARE. */
33 /* */
34 /************************************************************************/
35 
36 #ifndef VIGRA_MULTI_GRIDGRAPH_HXX
37 #define VIGRA_MULTI_GRIDGRAPH_HXX
38 
39 #include "multi_fwd.hxx"
40 #include "multi_iterator.hxx"
41 #include "multi_array.hxx"
42 #include "graphs.hxx"
43 
44 template <unsigned int N>
45 struct NeighborhoodTests;
46 
47 namespace vigra {
48 
49 template<unsigned int N, class T, class Stride>
50 inline
54 {
55  return pmap[k];
56 }
57 
58 /** \addtogroup GraphDataStructures Graph Data Structures and Algorithms
59 
60  Graph algorithms and the underlying graph data structures (e.g. GridGraph and AdjacencyListGraph)
61  implementing the APIs of the
62  <a href="http://www.boost.org/doc/libs/release/libs/graph/">boost::graph</a> and
63  <a href="http://lemon.cs.elte.hu/">LEMON</a> libraries.
64 
65  See also the \ref BoostGraphExtensions.
66 */
67 //@{
68 
69 /*
70 undirected edge_descriptor derived from TinyVector,
71 including flag for original edge orientation,
72 as necessary for source(), target() functions;
73 This edge_descriptor allows to directly (without adapter object)
74 index a MultiArrayView with one dimension more than the gridgraph,
75 the last coordinate indexing the edge number
76 (missing edges at the border are just ignored)
77 
78 The gridgraph class is able to convert/construct these edge_descriptors
79 and to reconstruct the corresponding source/target nodes.
80 
81 FIXME: store edge index in (*this)[0] ??
82 */
83 template<unsigned int N>
84 class GridGraphArcDescriptor
85  : public MultiArrayShape<N+1>::type
86 {
87  public:
88  typedef typename MultiArrayShape<N+1>::type base_type;
89  typedef typename base_type::value_type value_type;
90  typedef base_type edge_coord_type;
91  typedef value_type index_type;
92  typedef typename MultiArrayShape<N>::type shape_type;
93  typedef TinyVectorView<value_type, N> vertex_descriptor_view;
94 
95  GridGraphArcDescriptor()
96  : is_reversed_(false)
97  {}
98 
99  GridGraphArcDescriptor(lemon::Invalid)
100  : base_type(-1),
101  is_reversed_(false)
102  {}
103 
104  GridGraphArcDescriptor(base_type const & b, bool reversed)
105  : base_type(b),
106  is_reversed_(reversed)
107  {}
108 
109  GridGraphArcDescriptor(shape_type const &vertex,
110  index_type edge_index,
111  bool reversed=false)
112  : base_type(detail::DontInit())
113  {
114  set(vertex, edge_index, reversed);
115  }
116 
117  void set(shape_type const &vertex, index_type edge_index, bool reversed)
118  {
119  this->template subarray<0,N>() = vertex;
120  (*this)[N] = edge_index;
121  is_reversed_ = reversed;
122  }
123 
124  void increment(GridGraphArcDescriptor const & diff, bool opposite=false)
125  {
126  if(diff.is_reversed_)
127  {
128  is_reversed_ = !opposite;
129  this->template subarray<0,N>() += diff.template subarray<0,N>();
130  }
131  else
132  {
133  is_reversed_ = opposite;
134  }
135  (*this)[N] = diff[N];
136  }
137 
138  bool isReversed() const
139  {
140  return is_reversed_;
141  }
142 
143  vertex_descriptor_view vertexDescriptor() const
144  {
145  return this->template subarray<0,N>();
146  }
147 
148  value_type edgeIndex() const
149  {
150  return (*this)[N];
151  }
152 
153  protected:
154  bool is_reversed_;
155 };
156 
157 inline MultiArrayIndex
158 gridGraphMaxDegree(unsigned int N, NeighborhoodType t)
159 {
160  return t == DirectNeighborhood
161  ? 2*N
162  : pow(3.0, (int)N) - 1;
163 }
164 
165 template <unsigned int N, NeighborhoodType>
166 struct GridGraphMaxDegree;
167 
168 template <unsigned int N>
169 struct GridGraphMaxDegree<N, DirectNeighborhood>
170 {
171  static const MultiArrayIndex value = 2*N;
172 };
173 
174 template <unsigned int N>
175 struct GridGraphMaxDegree<N, IndirectNeighborhood>
176 {
177  static const MultiArrayIndex value = MetaPow<3, N>::value - 1;
178 };
179 
180 template <class Shape>
182 gridGraphEdgeCount(Shape const & shape, NeighborhoodType t, bool directed)
183 {
184  int res = 0;
185  if(t == DirectNeighborhood)
186  {
187  for(unsigned int k=0; k<shape.size(); ++k)
188  res += 2*prod(shape - Shape::unitVector(k));
189  }
190  else
191  {
192  res = prod(3*shape - Shape(2)) - prod(shape);
193  }
194  return directed
195  ? res
196  : res / 2;
197 }
198 
199 namespace detail {
200 
201 template <class Shape>
202 void
203 computeNeighborOffsets(ArrayVector<Shape> const & neighborOffsets,
204  ArrayVector<ArrayVector<bool> > const & neighborExists,
205  ArrayVector<ArrayVector<Shape> > & incrementOffsets,
206  ArrayVector<ArrayVector<GridGraphArcDescriptor<Shape::static_size> > > & edgeDescriptorOffsets,
207  ArrayVector<ArrayVector<MultiArrayIndex> > & indices,
208  ArrayVector<ArrayVector<MultiArrayIndex> > & backIndices,
209  bool directed)
210 {
211  typedef GridGraphArcDescriptor<Shape::static_size> EdgeDescriptor;
212 
213  unsigned int borderTypeCount = neighborExists.size();
214  incrementOffsets.resize(borderTypeCount);
215  edgeDescriptorOffsets.resize(borderTypeCount);
216  indices.resize(borderTypeCount);
217  backIndices.resize(borderTypeCount);
218 
219  for(unsigned int k=0; k<borderTypeCount; ++k)
220  {
221  incrementOffsets[k].clear();
222  edgeDescriptorOffsets[k].clear();
223  indices[k].clear();
224  backIndices[k].clear();
225 
226  for(unsigned int j=0; j < neighborOffsets.size(); ++j)
227  {
228  if(neighborExists[k][j])
229  {
230  if(incrementOffsets[k].size() == 0)
231  {
232  incrementOffsets[k].push_back(neighborOffsets[j]);
233  }
234  else
235  {
236  incrementOffsets[k].push_back(neighborOffsets[j] - neighborOffsets[indices[k].back()]);
237  }
238 
239  if(directed || j < neighborOffsets.size() / 2) // directed or backward edge
240  {
241  edgeDescriptorOffsets[k].push_back(EdgeDescriptor(Shape(), j));
242  }
243  else if(edgeDescriptorOffsets[k].size() == 0 || !edgeDescriptorOffsets[k].back().isReversed()) // the first forward edge
244  {
245  edgeDescriptorOffsets[k].push_back(EdgeDescriptor(neighborOffsets[j], neighborOffsets.size()-j-1, true));
246  }
247  else // second or higher forward edge
248  {
249  edgeDescriptorOffsets[k].push_back(EdgeDescriptor(neighborOffsets[j] - neighborOffsets[indices[k].back()],
250  neighborOffsets.size()-j-1, true));
251  }
252 
253  indices[k].push_back(j);
254  if(j < neighborOffsets.size() / 2)
255  backIndices[k].push_back(j);
256  }
257  }
258  }
259 }
260 
261 } // namespace detail
262 
263 template<unsigned int N, bool BackEdgesOnly>
264 class GridGraphNeighborIterator
265 {
266 public:
267  typedef typename MultiArrayShape<N>::type shape_type;
268  typedef MultiCoordinateIterator<N> vertex_iterator;
269  typedef typename vertex_iterator::value_type vertex_descriptor;
270  typedef vertex_descriptor value_type;
271  typedef typename vertex_iterator::pointer pointer;
272  typedef typename vertex_iterator::const_pointer const_pointer;
273  typedef typename vertex_iterator::reference reference;
274  typedef typename vertex_iterator::const_reference const_reference;
275  typedef MultiArrayIndex difference_type;
276  typedef MultiArrayIndex index_type;
277  typedef std::forward_iterator_tag iterator_category;
278 
279  friend struct NeighborhoodTests<N>;
280 
281  GridGraphNeighborIterator()
282  : neighborOffsets_(0),
283  neighborIndices_(0),
284  index_(0)
285  {}
286 
287  template <class DirectedTag>
288  GridGraphNeighborIterator(GridGraph<N, DirectedTag> const & g, typename GridGraph<N, DirectedTag>::Node const & v)
289  : neighborOffsets_(0),
290  neighborIndices_(0),
291  target_(v),
292  index_(0)
293  {
294  unsigned int nbtype = g.get_border_type(v);
295  neighborOffsets_ = &(*g.neighborIncrementArray())[nbtype];
296  neighborIndices_ = &(*g.neighborIndexArray(BackEdgesOnly))[nbtype];
297  updateTarget();
298  }
299 
300  template <class DirectedTag>
301  GridGraphNeighborIterator(GridGraph<N, DirectedTag> const & g, typename GridGraph<N, DirectedTag>::NodeIt const & v)
302  : neighborOffsets_(0),
303  neighborIndices_(0),
304  target_(v),
305  index_(0)
306  {
307  unsigned int nbtype = g.get_border_type(v);
308  neighborOffsets_ = &(*g.neighborIncrementArray())[nbtype];
309  neighborIndices_ = &(*g.neighborIndexArray(BackEdgesOnly))[nbtype];
310  updateTarget();
311  }
312 
313  // TODO: implement a "goto-neighbor" operation
314  // yielding a vertex_iterator! -> useful for
315  // watershed algo.
316 
317  GridGraphNeighborIterator & operator++()
318  {
319  ++index_;
320  updateTarget();
321  return *this;
322  }
323 
324  GridGraphNeighborIterator operator++(int)
325  {
326  GridGraphNeighborIterator ret(*this);
327  ++*this;
328  return ret;
329  }
330 
331  const_reference operator*() const
332  {
333  return target_;
334  }
335 
336  const_pointer operator->() const
337  {
338  return &target_;
339  }
340 
341  operator const_reference() const
342  {
343  return target_;
344  }
345 
346  const_reference target() const
347  {
348  return target_;
349  }
350 
351  MultiArrayIndex index() const
352  {
353  return index_;
354  }
355 
356  MultiArrayIndex neighborIndex() const
357  {
358  return (*neighborIndices_)[index_];
359  }
360 
361  bool operator==(GridGraphNeighborIterator const & other) const
362  {
363  return index_ == other.index_;
364  }
365 
366  bool operator!=(GridGraphNeighborIterator const & other) const
367  {
368  return index_ != other.index_;
369  }
370 
371  bool isValid() const
372  {
373  return index_ < (MultiArrayIndex)neighborIndices_->size();
374  }
375 
376  bool atEnd() const
377  {
378  return index_ >= (MultiArrayIndex)neighborIndices_->size();
379  }
380 
381  GridGraphNeighborIterator getEndIterator() const
382  {
383  GridGraphNeighborIterator res(*this);
384  res.index_ = (MultiArrayIndex)neighborIndices_->size();
385  return res;
386  }
387 
388  protected:
389 
390  // for testing only
391  GridGraphNeighborIterator(ArrayVector<shape_type> const & neighborOffsets,
392  ArrayVector<index_type> const & neighborIndices,
393  ArrayVector<index_type> const & backIndices,
394  vertex_descriptor source)
395  : neighborOffsets_(&neighborOffsets),
396  neighborIndices_(BackEdgesOnly ? &backIndices : &neighborIndices),
397  target_(source),
398  index_(0)
399  {
400  updateTarget();
401  }
402 
403  void updateTarget()
404  {
405  if(isValid())
406  target_ += (*neighborOffsets_)[index_];
407  }
408 
409  ArrayVector<shape_type> const * neighborOffsets_;
410  ArrayVector<index_type> const * neighborIndices_;
411  vertex_descriptor target_;
412  MultiArrayIndex index_;
413 };
414 
415 template<unsigned int N, bool BackEdgesOnly>
416 class GridGraphOutEdgeIterator
417 {
418  public:
419  typedef typename MultiArrayShape<N>::type shape_type;
420  typedef MultiArrayIndex index_type;
421  typedef GridGraphArcDescriptor<N> arc_descriptor;
422  typedef typename MultiArrayShape<N+1>::type value_type;
423  typedef value_type const & reference;
424  typedef value_type const & const_reference;
425  typedef value_type const * pointer;
426  typedef value_type const * const_pointer;
427  typedef MultiArrayIndex difference_type;
428  typedef std::forward_iterator_tag iterator_category;
429 
430  friend struct NeighborhoodTests<N>;
431  friend class GridGraphEdgeIterator<N, BackEdgesOnly>;
432 
433  GridGraphOutEdgeIterator()
434  : neighborOffsets_(0),
435  neighborIndices_(0),
436  index_(0)
437  {}
438 
439  template <class DirectedTag>
440  GridGraphOutEdgeIterator(GridGraph<N, DirectedTag> const & g,
441  typename GridGraph<N, DirectedTag>::NodeIt const & v,
442  bool opposite=false)
443  : neighborOffsets_(0),
444  neighborIndices_(0),
445  edge_descriptor_(),
446  index_(0)
447  {
448  unsigned int nbtype = g.get_border_type(v);
449  init(&(*g.edgeIncrementArray())[nbtype], &(*g.neighborIndexArray(BackEdgesOnly))[nbtype], *v, opposite);
450  }
451 
452  template <class DirectedTag>
453  GridGraphOutEdgeIterator(GridGraph<N, DirectedTag> const & g,
454  typename GridGraph<N, DirectedTag>::Node const & v,
455  bool opposite=false)
456  : neighborOffsets_(0),
457  neighborIndices_(0),
458  edge_descriptor_(),
459  index_(0)
460  {
461  unsigned int nbtype = g.get_border_type(v);
462  init(&(*g.edgeIncrementArray())[nbtype], &(*g.neighborIndexArray(BackEdgesOnly))[nbtype], v, opposite);
463  }
464 
465  GridGraphOutEdgeIterator & operator++()
466  {
467  increment(false);
468  return *this;
469  }
470 
471  GridGraphOutEdgeIterator operator++(int)
472  {
473  GridGraphOutEdgeIterator ret(*this);
474  ++*this;
475  return ret;
476  }
477 
478  const_reference operator*() const
479  {
480  return edge_descriptor_;
481  }
482 
483  operator const_reference() const
484  {
485  return edge_descriptor_;
486  }
487 
488  const_pointer operator->() const
489  {
490  return &edge_descriptor_;
491  }
492 
493  index_type index() const
494  {
495  return index_;
496  }
497 
498  index_type neighborIndex() const
499  {
500  return (*neighborIndices_)[index_];
501  }
502 
503  arc_descriptor const & arcDescriptor() const
504  {
505  return edge_descriptor_;
506  }
507 
508  bool operator==(GridGraphOutEdgeIterator const & other) const
509  {
510  return index_ == other.index();
511  }
512 
513  bool operator!=(GridGraphOutEdgeIterator const & other) const
514  {
515  return index_ != other.index();
516  }
517 
518  bool isValid() const
519  {
520  return index_ < (index_type)neighborIndices_->size();
521  }
522 
523  bool atEnd() const
524  {
525  return index_ >= (index_type)neighborIndices_->size();
526  }
527 
528  GridGraphOutEdgeIterator getEndIterator() const
529  {
530  GridGraphOutEdgeIterator res(*this);
531  res.index_ = (index_type)neighborIndices_->size();
532  return res;
533  }
534 
535  protected:
536 
537  // for testing only
538  GridGraphOutEdgeIterator(ArrayVector<arc_descriptor> const & neighborOffsets,
539  ArrayVector<index_type> const & neighborIndices,
540  ArrayVector<index_type> const & backIndices,
541  shape_type const & source)
542  : neighborOffsets_(0),
543  neighborIndices_(0),
544  edge_descriptor_(),
545  index_(0)
546  {
547  init(&neighborOffsets, BackEdgesOnly ? &backIndices : &neighborIndices, source);
548  }
549 
550  void init(ArrayVector<arc_descriptor> const * neighborOffsets,
551  ArrayVector<index_type> const * neighborIndices,
552  shape_type const & source,
553  bool opposite=false)
554  {
555  neighborOffsets_ = neighborOffsets;
556  neighborIndices_ = neighborIndices;
557  edge_descriptor_ = arc_descriptor(source, 0);
558  index_ = 0;
559  updateEdgeDescriptor(opposite);
560  }
561 
562  void increment(bool opposite)
563  {
564  ++index_;
565  updateEdgeDescriptor(opposite);
566  }
567 
568  void updateEdgeDescriptor(bool opposite)
569  {
570  if(isValid())
571  edge_descriptor_.increment((*neighborOffsets_)[index_], opposite);
572  }
573 
574  ArrayVector<arc_descriptor> const * neighborOffsets_;
575  ArrayVector<index_type> const * neighborIndices_;
576  arc_descriptor edge_descriptor_;
577  index_type index_;
578 };
579 
580 template<unsigned int N, bool BackEdgesOnly>
581 class GridGraphOutArcIterator
582 : public GridGraphOutEdgeIterator<N, BackEdgesOnly>
583 {
584  public:
585  typedef GridGraphOutEdgeIterator<N, BackEdgesOnly> base_type;
586  typedef typename MultiArrayShape<N>::type shape_type;
587  typedef MultiArrayIndex index_type;
588  typedef GridGraphArcDescriptor<N> value_type;
589  typedef value_type const & reference;
590  typedef value_type const & const_reference;
591  typedef value_type const * pointer;
592  typedef value_type const * const_pointer;
593  typedef MultiArrayIndex difference_type;
594  typedef std::forward_iterator_tag iterator_category;
595 
596  friend struct NeighborhoodTests<N>;
597  friend class GridGraphEdgeIterator<N, BackEdgesOnly>;
598 
599  GridGraphOutArcIterator()
600  : base_type()
601  {}
602 
603  explicit GridGraphOutArcIterator(base_type const & b)
604  : base_type(b)
605  {}
606 
607  template <class DirectedTag>
608  GridGraphOutArcIterator(GridGraph<N, DirectedTag> const & g, typename GridGraph<N, DirectedTag>::NodeIt const & v)
609  : base_type(g, v)
610  {}
611 
612  template <class DirectedTag>
613  GridGraphOutArcIterator(GridGraph<N, DirectedTag> const & g, typename GridGraph<N, DirectedTag>::Node const & v)
614  : base_type(g, v)
615  {}
616 
617  GridGraphOutArcIterator & operator++()
618  {
619  base_type::operator++();
620  return *this;
621  }
622 
623  GridGraphOutArcIterator operator++(int)
624  {
625  GridGraphOutArcIterator ret(*this);
626  ++*this;
627  return ret;
628  }
629 
630  const_reference operator*() const
631  {
632  return this->edge_descriptor_;
633  }
634 
635  operator const_reference() const
636  {
637  return this->edge_descriptor_;
638  }
639 
640  const_pointer operator->() const
641  {
642  return &this->edge_descriptor_;
643  }
644 
645  GridGraphOutArcIterator getEndIterator() const
646  {
647  return GridGraphOutArcIterator(base_type::getEndIterator());
648  }
649 
650  protected:
651 
652  // for testing only
653  GridGraphOutArcIterator(ArrayVector<value_type> const & neighborOffsets,
654  ArrayVector<index_type> const & neighborIndices,
655  ArrayVector<index_type> const & backIndices,
656  shape_type const & source)
657  : base_type(neighborOffsets, neighborIndices, backIndices, source)
658  {}
659 };
660 
661 template<unsigned int N, bool BackEdgesOnly>
662 class GridGraphInArcIterator
663 : public GridGraphOutEdgeIterator<N, BackEdgesOnly>
664 {
665  public:
666  typedef GridGraphOutEdgeIterator<N, BackEdgesOnly> base_type;
667  typedef typename MultiArrayShape<N>::type shape_type;
668  typedef MultiArrayIndex index_type;
669  typedef GridGraphArcDescriptor<N> value_type;
670  typedef value_type const & reference;
671  typedef value_type const & const_reference;
672  typedef value_type const * pointer;
673  typedef value_type const * const_pointer;
674  typedef MultiArrayIndex difference_type;
675  typedef std::forward_iterator_tag iterator_category;
676 
677  friend struct NeighborhoodTests<N>;
678 
679  GridGraphInArcIterator()
680  : base_type()
681  {}
682 
683  explicit GridGraphInArcIterator(base_type const & b)
684  : base_type(b)
685  {}
686 
687  template <class DirectedTag>
688  GridGraphInArcIterator(GridGraph<N, DirectedTag> const & g, typename GridGraph<N, DirectedTag>::NodeIt const & v)
689  : base_type(g, v, true)
690  {}
691 
692  template <class DirectedTag>
693  GridGraphInArcIterator(GridGraph<N, DirectedTag> const & g, typename GridGraph<N, DirectedTag>::Node const & v)
694  : base_type(g, v, true)
695  {}
696 
697  GridGraphInArcIterator & operator++()
698  {
699  base_type::increment(true);
700  return *this;
701  }
702 
703  GridGraphInArcIterator operator++(int)
704  {
705  GridGraphInArcIterator ret(*this);
706  ++*this;
707  return ret;
708  }
709 
710  const_reference operator*() const
711  {
712  return this->edge_descriptor_;
713  }
714 
715  operator const_reference() const
716  {
717  return this->edge_descriptor_;
718  }
719 
720  const_pointer operator->() const
721  {
722  return &this->edge_descriptor_;
723  }
724 
725  GridGraphInArcIterator getEndIterator() const
726  {
727  return GridGraphInArcIterator(base_type::getEndIterator());
728  }
729 };
730 
731  // Edge iterator for directed and undirected graphs.
732  // Composed of a vertex_iterator and an out_edge_iterator.
733 template<unsigned int N, bool BackEdgesOnly>
734 class GridGraphEdgeIterator
735 {
736 public:
737  typedef GridGraphEdgeIterator<N, BackEdgesOnly> self_type;
738  typedef MultiCoordinateIterator<N> vertex_iterator;
739  typedef typename vertex_iterator::value_type vertex_descriptor;
740  typedef GridGraphOutArcIterator<N, BackEdgesOnly> out_edge_iterator;
741  typedef typename MultiArrayShape<N+1>::type edge_descriptor;
742  typedef edge_descriptor value_type;
743  typedef value_type const * pointer;
744  typedef value_type const * const_pointer;
745  typedef value_type const & reference;
746  typedef value_type const & const_reference;
747  typedef typename MultiArrayShape<N>::type shape_type;
748  typedef MultiArrayIndex difference_type;
749  typedef MultiArrayIndex index_type;
750  typedef std::forward_iterator_tag iterator_category;
751 
752  friend struct NeighborhoodTests<N>;
753 
754  GridGraphEdgeIterator()
755  : neighborOffsets_(0),
756  neighborIndices_(0)
757  {}
758 
759  template <class DirectedTag>
760  GridGraphEdgeIterator(GridGraph<N, DirectedTag> const & g)
761  : neighborOffsets_(g.edgeIncrementArray()),
762  neighborIndices_(g.neighborIndexArray(BackEdgesOnly)),
763  vertexIterator_(g),
764  outEdgeIterator_(g, vertexIterator_)
765  {
766  if(outEdgeIterator_.atEnd()) // in a undirected graph, the first point stores no edges
767  {
768  ++vertexIterator_;
769  if(vertexIterator_.isValid())
770  outEdgeIterator_ = out_edge_iterator(g, vertexIterator_);
771  }
772  }
773 
774  GridGraphEdgeIterator & operator++()
775  {
776  ++outEdgeIterator_;
777  if(outEdgeIterator_.atEnd())
778  {
779  ++vertexIterator_;
780  if(vertexIterator_.isValid())
781  {
782  unsigned int borderType = vertexIterator_.borderType();
783  outEdgeIterator_.init(&(*neighborOffsets_)[borderType], &(*neighborIndices_)[borderType], *vertexIterator_);
784  }
785  }
786  return *this;
787  }
788 
789  GridGraphEdgeIterator operator++(int)
790  {
791  GridGraphEdgeIterator ret(*this);
792  ++*this;
793  return ret;
794  }
795 
796  const_reference operator*() const
797  {
798  return *outEdgeIterator_;
799  }
800 
801  operator const_reference() const
802  {
803  return *outEdgeIterator_;
804  }
805 
806  const_pointer operator->() const
807  {
808  return outEdgeIterator_.operator->();
809  }
810 
811  MultiArrayIndex neighborIndex() const
812  {
813  return outEdgeIterator_.neighborIndex();
814  }
815 
816 
817  bool operator==(GridGraphEdgeIterator const & other) const
818  {
819  return (vertexIterator_ == other.vertexIterator_ && outEdgeIterator_ == other.outEdgeIterator_);
820  }
821 
822  bool operator!=(GridGraphEdgeIterator const & other) const
823  {
824  return !operator==(other);
825  }
826 
827  bool isValid() const
828  {
829  return vertexIterator_.isValid();
830  }
831 
832  bool atEnd() const
833  {
834  return !isValid();
835  }
836 
837  GridGraphEdgeIterator getEndIterator() const
838  {
839  GridGraphEdgeIterator ret(*this);
840  ret.vertexIterator_ = vertexIterator_.getEndIterator();
841  vertex_iterator lastVertex = ret.vertexIterator_ - 1;
842  unsigned int borderType = lastVertex.borderType();
843  ret.outEdgeIterator_.init(&(*neighborOffsets_)[borderType], &(*neighborIndices_)[borderType], *lastVertex);
844  ret.outEdgeIterator_ = ret.outEdgeIterator_.getEndIterator();
845  return ret;
846  }
847 
848  protected:
849 
850  // for testing only
851  GridGraphEdgeIterator(ArrayVector<ArrayVector<typename out_edge_iterator::value_type> > const & neighborOffsets,
852  ArrayVector<ArrayVector<index_type> > const & neighborIndices,
853  ArrayVector<ArrayVector<index_type> > const & backIndices,
854  shape_type const & shape)
855  : neighborOffsets_(&neighborOffsets),
856  neighborIndices_(BackEdgesOnly ? &backIndices : &neighborIndices),
857  vertexIterator_(shape),
858  outEdgeIterator_(neighborOffsets[vertexIterator_.borderType()],
859  neighborIndices[vertexIterator_.borderType()],
860  backIndices[vertexIterator_.borderType()], shape_type())
861  {
862  if(outEdgeIterator_.atEnd()) // in a undirected graph, the first point stores no edges
863  {
864  ++vertexIterator_;
865  if(vertexIterator_.isValid())
866  {
867  unsigned int borderType = vertexIterator_.borderType();
868  outEdgeIterator_.init(&(*neighborOffsets_)[borderType], &(*neighborIndices_)[borderType], *vertexIterator_);
869  }
870  }
871  }
872 
873  ArrayVector<ArrayVector<typename out_edge_iterator::value_type> > const * neighborOffsets_;
874  ArrayVector<ArrayVector<index_type> > const * neighborIndices_;
875  vertex_iterator vertexIterator_;
876  out_edge_iterator outEdgeIterator_;
877 };
878 
879 template<unsigned int N, bool BackEdgesOnly>
880 class GridGraphArcIterator
881 : public GridGraphEdgeIterator<N, BackEdgesOnly>
882 {
883 public:
884  typedef GridGraphEdgeIterator<N, BackEdgesOnly> base_type;
885  typedef GridGraphArcIterator<N, BackEdgesOnly> self_type;
886  typedef MultiCoordinateIterator<N> vertex_iterator;
887  typedef typename vertex_iterator::value_type vertex_descriptor;
888  typedef GridGraphOutArcIterator<N, BackEdgesOnly> out_edge_iterator;
889  typedef typename out_edge_iterator::value_type edge_descriptor;
890  typedef edge_descriptor value_type;
891  typedef value_type const * pointer;
892  typedef value_type const * const_pointer;
893  typedef value_type const & reference;
894  typedef value_type const & const_reference;
895  typedef typename MultiArrayShape<N>::type shape_type;
896  typedef MultiArrayIndex difference_type;
897  typedef MultiArrayIndex index_type;
898  typedef std::forward_iterator_tag iterator_category;
899 
900  friend struct NeighborhoodTests<N>;
901 
902  GridGraphArcIterator()
903  : base_type()
904  {}
905 
906  explicit GridGraphArcIterator(base_type const & b)
907  : base_type(b)
908  {}
909 
910  template <class DirectedTag>
911  GridGraphArcIterator(GridGraph<N, DirectedTag> const & g)
912  : base_type(g)
913  {}
914 
915  GridGraphArcIterator & operator++()
916  {
917  base_type::operator++();
918  return *this;
919  }
920 
921  GridGraphArcIterator operator++(int)
922  {
923  GridGraphArcIterator ret(*this);
924  ++*this;
925  return ret;
926  }
927 
928  const_reference operator*() const
929  {
930  return *(this->outEdgeIterator_);
931  }
932 
933  operator const_reference() const
934  {
935  return *(this->outEdgeIterator_);
936  }
937 
938  const_pointer operator->() const
939  {
940  return this->outEdgeIterator_.operator->();
941  }
942 
943  GridGraphArcIterator getEndIterator() const
944  {
945  return GridGraphArcIterator(base_type::getEndIterator());
946  }
947 
948  protected:
949 
950  // for testing only
951  GridGraphArcIterator(ArrayVector<ArrayVector<value_type> > const & neighborOffsets,
952  ArrayVector<ArrayVector<index_type> > const & neighborIndices,
953  ArrayVector<ArrayVector<index_type> > const & backIndices,
954  shape_type const & shape)
955  : base_type(neighborOffsets, neighborIndices, backIndices, shape)
956  {}
957 };
958 
959 template<unsigned int N>
960 inline bool operator==(MultiCoordinateIterator<N> const & i, lemon::Invalid)
961 {
962  return i.atEnd();
963 }
964 
965 template<unsigned int N>
966 inline bool operator!=(MultiCoordinateIterator<N> const & i, lemon::Invalid)
967 {
968  return i.isValid();
969 }
970 
971 template<unsigned int N>
972 inline bool operator==(lemon::Invalid, MultiCoordinateIterator<N> const & i)
973 {
974  return i.atEnd();
975 }
976 
977 template<unsigned int N>
978 inline bool operator!=(lemon::Invalid, MultiCoordinateIterator<N> const & i)
979 {
980  return i.isValid();
981 }
982 
983 #define VIGRA_LEMON_INVALID_COMPARISON(type) \
984 template<unsigned int N, bool BackEdgesOnly> \
985 inline bool operator==(type<N, BackEdgesOnly> const & i, lemon::Invalid) \
986 { \
987  return i.atEnd(); \
988 } \
989 template<unsigned int N, bool BackEdgesOnly> \
990 inline bool operator!=(type<N, BackEdgesOnly> const & i, lemon::Invalid) \
991 { \
992  return i.isValid(); \
993 } \
994 template<unsigned int N, bool BackEdgesOnly> \
995 inline bool operator==(lemon::Invalid, type<N, BackEdgesOnly> const & i) \
996 { \
997  return i.atEnd(); \
998 } \
999 template<unsigned int N, bool BackEdgesOnly> \
1000 inline bool operator!=(lemon::Invalid, type<N, BackEdgesOnly> const & i) \
1001 { \
1002  return i.isValid(); \
1003 }
1004 
1005 VIGRA_LEMON_INVALID_COMPARISON(GridGraphNeighborIterator)
1006 VIGRA_LEMON_INVALID_COMPARISON(GridGraphOutEdgeIterator)
1007 VIGRA_LEMON_INVALID_COMPARISON(GridGraphOutArcIterator)
1008 VIGRA_LEMON_INVALID_COMPARISON(GridGraphInArcIterator)
1009 VIGRA_LEMON_INVALID_COMPARISON(GridGraphEdgeIterator)
1010 VIGRA_LEMON_INVALID_COMPARISON(GridGraphArcIterator)
1011 
1012 #undef VIGRA_LEMON_INVALID_COMPARISON
1013 
1014 using boost::directed_tag;
1015 using boost::undirected_tag;
1016 
1017 namespace detail {
1018 
1019 template <unsigned int N, class DirectedTag>
1020 struct GridGraphBase;
1021 
1022 template <unsigned int N>
1023 struct GridGraphBase<N, directed_tag>
1024 {
1025  template <class T>
1026  class ArcMap
1027  : public MultiArray<N+1, Multiband<T> >
1028  {
1029  public:
1030  typedef MultiArray<N+1, Multiband<T> > base_type;
1031  typedef typename base_type::difference_type difference_type;
1032  typedef typename base_type::key_type key_type;
1033  typedef typename base_type::value_type value_type;
1034  typedef typename base_type::reference reference;
1035  typedef typename base_type::const_reference const_reference;
1036  typedef boost::read_write_property_map_tag category;
1037 
1038  typedef lemon::True ReferenceMapTag;
1039  typedef key_type Key;
1040  typedef value_type Value;
1041  typedef reference Reference;
1042  typedef const_reference ConstReference;
1043 
1044  ArcMap()
1045  : base_type()
1046  {}
1047 
1048  explicit ArcMap(GridGraph<N, directed_tag> const & g)
1049  : base_type(g.arc_propmap_shape())
1050  {}
1051 
1052  ArcMap(GridGraph<N, directed_tag> const & g, T const & t)
1053  : base_type(g.arc_propmap_shape(), t)
1054  {}
1055 
1056  explicit ArcMap(difference_type const & shape)
1057  : base_type(shape)
1058  {}
1059 
1060  ArcMap(difference_type const & shape, T const & t)
1061  : base_type(shape, t)
1062  {}
1063 
1064  ArcMap & operator=(ArcMap const & m)
1065  {
1066  base_type::operator=(m);
1067  return *this;
1068  }
1069 
1070  ArcMap & operator=(base_type const & m)
1071  {
1072  base_type::operator=(m);
1073  return *this;
1074  }
1075 
1076  // appropriate operator[] are inherited
1077 
1078  void set(Key const & k, Value const & v)
1079  {
1080  (*this)[k] = v;
1081  }
1082  };
1083 };
1084 
1085 template <unsigned int N>
1086 struct GridGraphBase<N, undirected_tag>
1087 {
1088  typedef lemon::True UndirectedTag;
1089 
1090  template <class T>
1091  class ArcMap
1092  : public MultiArray<N+1, Multiband<T> >
1093  {
1094  public:
1095  typedef MultiArray<N+1, Multiband<T> > base_type;
1096  typedef GridGraphArcDescriptor<N> difference_type;
1097  typedef difference_type key_type;
1098  typedef typename base_type::value_type value_type;
1099  typedef typename base_type::reference reference;
1100  typedef typename base_type::const_reference const_reference;
1101  typedef boost::read_write_property_map_tag category;
1102 
1103  typedef lemon::True ReferenceMapTag;
1104  typedef key_type Key;
1105  typedef value_type Value;
1106  typedef reference Reference;
1107  typedef const_reference ConstReference;
1108 
1109  ArcMap()
1110  : base_type()
1111  {}
1112 
1113  explicit ArcMap(GridGraph<N, undirected_tag> const & g)
1114  : base_type(g.arc_propmap_shape()),
1115  graph_(&g)
1116  {}
1117 
1118  ArcMap(GridGraph<N, undirected_tag> const & g, T const & t)
1119  : base_type(g.arc_propmap_shape(), t),
1120  graph_(&g)
1121  {}
1122 
1123  ArcMap & operator=(ArcMap const & m)
1124  {
1125  base_type::operator=(m);
1126  return *this;
1127  }
1128 
1129  ArcMap & operator=(base_type const & m)
1130  {
1131  base_type::operator=(m);
1132  return *this;
1133  }
1134 
1135  reference operator[](difference_type const & s)
1136  {
1137  if(s.isReversed())
1138  {
1139  return base_type::operator[](graph_->directedArc(s));
1140  }
1141  else
1142  {
1143  return base_type::operator[](s);
1144  }
1145  }
1146 
1147  const_reference operator[](difference_type const & s) const
1148  {
1149  if(s.isReversed())
1150  {
1151  return base_type::operator[](graph_->directedArc(s));
1152  }
1153  else
1154  {
1155  return base_type::operator[](s);
1156  }
1157  }
1158 
1159  void set(Key const & k, Value const & v)
1160  {
1161  (*this)[k] = v;
1162  }
1163 
1164  GridGraph<N, undirected_tag> const * graph_;
1165  };
1166 };
1167 
1168 } // namespace detail
1169 
1170 /********************************************************/
1171 /* */
1172 /* GridGraph */
1173 /* */
1174 /********************************************************/
1175 
1176 /** \brief Define a grid graph in arbitrary dimensions.
1177 
1178  A GridGraph connects each pixel to its direct or indirect neighbors.
1179  Direct neighbors are the adjacent point along the coordinate axes,
1180  whereas indirect neighbors include the diagonally adjacent points. Thus,
1181  direct neighbors correspond to the 4-neighborhood in 2D and the
1182  6-neighborhood in 3D, whereas indirect neighbors correspond to the
1183  8-neighborhood and 26-neighborhood respectively. The GridGraph class
1184  extends this scheme to arbitrary dimensions. While the dimension must be
1185  defined at compile time via the template parameter <tt>N</tt>, the
1186  desired neighborhood can be chosen at runtime in the GridGraph's
1187  constructor. The shape of the grid is also specified at runtime in terms
1188  of a suitable shape object.
1189 
1190  Another choice to be made at compile time is whether the graph should be directed
1191  or undirected. This is defined via the <tt>DirectedTag</tt> template parameter
1192  which can take the values <tt>directed_tag</tt> or <tt>undirected_tag</tt> (default).
1193 
1194  The main difficulty in a grid graph is to skip the missing neighbors
1195  of the pixels near the grid's border. For example, the upper left pixel in a
1196  2D grid has only two direct neighbors instead of the usual four. The GridGraph
1197  class uses a precomputed set of internal look-up tables to efficiently determine the
1198  appropriate number and location of the existing neighbors. A key design decision
1199  to make this fast was to give up the requirement that edge IDs are contiguous
1200  integers (as in LEMON's implementation of a 2D grid graph, which became very
1201  complicated and slow by enforcing this requirement). Instead, edges are numbered
1202  as if all nodes (including nodes at the grid's border) had the same degree.
1203  Since edges crossing the border are not actually present in the graph, these IDs
1204  are missing, leading to gaps in the sequence of IDs.
1205 
1206  For the sake of compatibility, the GridGraph class implements two
1207  popular graph APIs: the one defined by the <a href="http://www.boost.org/doc/libs/release/libs/graph/">boost::graph</a> library and
1208  the one defined by the <a href="http://lemon.cs.elte.hu/">LEMON</a> library.
1209  Their basic principles are very similar: The graph's nodes, edges and adjacency
1210  structure are accessed via a set of iterators, whereas additional properties
1211  (like node and edge weights) are provided via <i>property maps</i> that are
1212  indexed with suitable node or edge descriptor objects returned by the iterators.
1213 
1214  Specifically, GridGraph implements the requirements of the following <a href="http://www.boost.org/doc/libs/release/libs/graph/doc/graph_concepts.html">concepts of the
1215  boost::graph API</a>: <b>Graph, IncidenceGraph, BidirectionalGraph, AdjacencyGraph,
1216  VertexListGraph, EdgeListGraph,</b> and <b>AdjacencyMatrix</b>. Likewise, it supports
1217  the concepts <b>Graph</b> and <b>Digraph</b> of the LEMON API. The property maps
1218  associated with a GridGraph support the boost concepts ReadablePropertyMap,
1219  WritablePropertyMap, ReadWritePropertyMap, and LvaluePropertyMap as well as the
1220  LEMON concepts ReadMap, WriteMap, ReadWriteMap, and ReferenceMap.
1221 
1222  VIGRA's GridGraph class is designed such that multi-dimensional coordinates
1223  (i.e. <tt>TinyVector<MultiArrayIndex></tt>) serve as descriptor objects, which means
1224  that normal <tt>MultiArray</tt>s or <tt>MultiArrayView</tt>s can serve as property
1225  maps in most situations. Thus, node properties like a foreground probability for
1226  foreground/background segmentation can simply be stored as normal images.
1227 
1228  Since the boost::graph and LEMON APIs differ in how they call corresponding
1229  functionality (e.g., they use the terms <tt>vertex</tt> and <tt>node</tt> respectively
1230  in an exactly synonymous way), most GridGraph helper classes and functions are exposed
1231  under two different names. To implement your own algorithms, you can choose the API
1232  you like most. VIGRA adopts the convention that algorithms using the boost::graph
1233  API go into the namespace <tt>vigra::boost_graph</tt>, while those using the
1234  LEMON API are placed into the namespace <tt>vigra::lemon_graph</tt>. This helps
1235  to avoid name clashes when the two APIs happen to use the same name for different
1236  things. The documentation of the GridGraph members specifies which API the respective
1237  function or class belongs to. Please consult the documentation of these
1238  libraries for tutorial introductions and full reference of the respective APIs.
1239 
1240  VIGRA adds an important new concept of its own: the back neighborhood
1241  and associated adjacency and edge iterators. The back neighborhood of a given vertex
1242  with ID <tt>i</tt> is the set of all neighbor vertices whose ID is smaller than <tt>i</tt>.
1243  This concept is useful if you work on the grid graph's vertices in scan order
1244  and want to access just those neighbors that have already been processed. Connected
1245  components labeling is a typical example of an algorithm that can take advantage of this
1246  possibility. In principle, a back neighborhood iterator could be implemented as
1247  a filter iterator that simply skips all neighbors with inappropriate IDs. However,
1248  in case of grid graphs it is more efficient to provide a special iterator for this purpose.
1249 
1250  <b>Usage:</b>
1251 
1252  <b>\#include</b> <vigra/multi_gridgraph.hxx> <br/>
1253  Namespace: vigra
1254 
1255  At present, the GridGraph class is mainly used internally to implement image
1256  analysis functions for arbitrary dimensional arrays (e.g. detection of local
1257  extrema, connected components labeling, watersheds, SLIC superpixels). For example,
1258  a dimension-independent algorithm to detect local maxima using the LEMON API
1259  might look like this:
1260 
1261  \code
1262  namespace vigra { namespace lemon_graph {
1263 
1264  template <class Graph, class InputMap, class OutputMap>
1265  void
1266  localMaxima(Graph const & g,
1267  InputMap const & src,
1268  OutputMap & local_maxima,
1269  typename OutputMap::value_type marker)
1270  {
1271  // define abreviations for the required iterators
1272  typedef typename Graph::NodeIt graph_scanner;
1273  typedef typename Graph::OutArcIt neighbor_iterator;
1274 
1275  // iterate over all nodes (i.e. pixels)
1276  for (graph_scanner node(g); node != INVALID; ++node)
1277  {
1278  // remember the value of the current node
1279  typename InputMap::value_type current = src[*node];
1280 
1281  // iterate over all neighbors of the current node
1282  bool is_local_maximum = true;
1283  for (neighbor_iterator arc(g, node); arc != INVALID; ++arc)
1284  {
1285  // if a neighbor has larger value, the center node is not a local maximum
1286  if (current < src[g.target(*arc)])
1287  is_local_maximum = false;
1288  }
1289 
1290  // mark the node when it is a local maximum
1291  if (is_local_maximum)
1292  local_maxima[*node] = marker;
1293  }
1294  }
1295 
1296  }} // namespace vigra::lemon_graph
1297  \endcode
1298 
1299  It should be noted that this algorithm will work for any LEMON-compatible graph class,
1300  not just our GridGraph. When implemented in terms of the boost::graph API, the same algorithm
1301  looks like this:
1302 
1303  \code
1304  namespace vigra { namespace boost_graph {
1305 
1306  template <class Graph, class InputMap, class OutputMap>
1307  void
1308  localMaxima(Graph const & g,
1309  InputMap const & src,
1310  OutputMap & local_maxima,
1311  typename property_traits<OutputMap>::value_type marker)
1312  {
1313  // define abreviations and variables for the required iterators
1314  typedef typename graph_traits<Graph>::vertex_iterator graph_scanner;
1315  typedef typename graph_traits<Graph>::adjacency_iterator neighbor_iterator;
1316 
1317  graph_scanner node, node_end;
1318  neighbor_iterator arc, arc_end;
1319 
1320  // iterate over all nodes (i.e. pixels)
1321  tie(node, node_end) = vertices(g);
1322  for (; node != node_end; ++node)
1323  {
1324  // remember the value of the current node
1325  typename property_traits<InputMap>::value_type current = get(src, *node);
1326 
1327  // iterate over all neighbors of the current node
1328  bool is_local_maximum = true;
1329  tie(arc, arc_end) = adjacent_vertices(*node, g);
1330  for (;arc != arc_end; ++arc)
1331  {
1332  // if a neighbor has larger value, the center node is not a local maximum
1333  if (current < get(src, *arc))
1334  is_local_maximum = false;
1335  }
1336 
1337  // mark the node when it is a local maximum
1338  if (is_local_maximum)
1339  put(local_maxima, *node, marker);
1340  }
1341  }
1342 
1343  }} // namespace vigra::boost_graph
1344  \endcode
1345 
1346  It can be seen that the differences between the APIs are mainly syntactic
1347  (especially note that boost::graph users traits classes and free functions,
1348  whereas LEMON uses nested typedefs and member functions). Either of these
1349  algorithms can now serve as the backend of a local maxima detector
1350  for <tt>MultiArrayViews</tt>:
1351 
1352  \code
1353  namespace vigra {
1354 
1355  template <unsigned int N, class T1,
1356  class T2>
1357  void
1358  localMaxima(MultiArrayView<N, T1> const & src,
1359  MultiArrayView<N, T2> local_maxima,
1360  T2 marker,
1361  NeighborhoodType neighborhood = IndirectNeighborhood)
1362  {
1363  vigra_precondition(src.shape() == local_maxima.shape(),
1364  "localMinMax(): shape mismatch between input and output.");
1365 
1366  // create a grid graph with appropriate shape and desired neighborhood
1367  GridGraph<N, undirected_tag> graph(src.shape(), neighborhood);
1368 
1369  // forward the call to the graph-based algorithm, using
1370  // the given MultiArrayViews as property maps
1371  lemon_graph::localMaxima(graph, src, local_maxima, marker);
1372  }
1373 
1374  } // namespace vigra
1375  \endcode
1376 
1377  A slightly enhanced version of this code is actually used to implement this
1378  functionality in VIGRA.
1379 */
1380 template<unsigned int N, class DirectedTag=undirected_tag>
1381 class GridGraph
1382 : public detail::GridGraphBase<N, DirectedTag>
1383 {
1384 public:
1385  /** \brief 'true' if the graph is directed (API: boost::graph)
1386  */
1387  static const bool is_directed = IsSameType<DirectedTag, directed_tag>::value;
1388 
1389  typedef detail::GridGraphBase<N, DirectedTag> base_type;
1391 
1392  /** \brief Dimension of the grid.
1393  */
1394  static const unsigned int dimension = N;
1395 
1396  /** \brief Shape type of the graph and a node property map.
1397  */
1399 
1400  /** \brief Shape type of an edge property map (must have one additional dimension).
1401  */
1403 
1404  /** \brief Type of node and edge IDs.
1405  */
1407 
1408  /** \brief Type to specify number of vertices (API: boost::graph,
1409  use via <tt>boost::graph_traits<Graph>::vertices_size_type</tt>).
1410  */
1412 
1413  /** \brief Type to specify number of edges (API: boost::graph,
1414  use via <tt>boost::graph_traits<Graph>::edges_size_type</tt>).
1415  */
1417 
1418  /** \brief Type to specify number of neighbors (API: boost::graph,
1419  use via <tt>boost::graph_traits<Graph>::degree_size_type</tt>).
1420  */
1422 
1423  /** \brief Iterator over the vertices of the graph (API: boost::graph,
1424  use via <tt>boost::graph_traits<Graph>::vertex_iterator</tt>).
1425  */
1427 
1428  /** \brief Iterator over the neighbor vertices of a given vertex (API: boost::graph,
1429  use via <tt>boost::graph_traits<Graph>::adjacency_iterator</tt>).
1430  */
1431  typedef GridGraphNeighborIterator<N> adjacency_iterator;
1432 
1433  /** \brief Same as adjacency_iterator (API: VIGRA).
1434  */
1436 
1437  /** \brief Iterator over only those neighbor vertices of a given vertex
1438  that have smaller ID (API: VIGRA).
1439  */
1440  typedef GridGraphNeighborIterator<N, true> back_neighbor_vertex_iterator;
1441 
1442  /** \brief Iterator over the incoming edges of a given vertex (API: boost::graph,
1443  use via <tt>boost::graph_traits<Graph>::in_edge_iterator</tt>).
1444  */
1445  typedef GridGraphInArcIterator<N> in_edge_iterator;
1446 
1447  /** \brief Iterator over the outgoing edges of a given vertex (API: boost::graph,
1448  use via <tt>boost::graph_traits<Graph>::out_edge_iterator</tt>).
1449  */
1450  typedef GridGraphOutArcIterator<N> out_edge_iterator;
1451 
1452  /** \brief Iterator over only those outgoing edges of a given vertex
1453  that go to vertices with smaller IDs (API: VIGRA).
1454  */
1455  typedef GridGraphOutArcIterator<N, true> out_back_edge_iterator;
1456 
1457  /** \brief Iterator over the edges of a graph (API: boost::graph,
1458  use via <tt>boost::graph_traits<Graph>::edge_iterator</tt>).
1459  */
1460  typedef GridGraphArcIterator<N, !is_directed> edge_iterator;
1461 
1462  /** \brief The vertex descriptor (API: boost::graph,
1463  use via <tt>boost::graph_traits<Graph>::vertex_descriptor</tt>).
1464  */
1465  typedef shape_type vertex_descriptor;
1466 
1467  /** \brief The edge descriptor (API: boost::graph,
1468  use via <tt>boost::graph_traits<Graph>::edge_descriptor</tt>).
1469  */
1470  typedef GridGraphArcDescriptor<N> edge_descriptor;
1471 
1472  /** \brief Is the graph directed or undirected ? (API: boost::graph,
1473  use via <tt>boost::graph_traits<Graph>::directed_category</tt>).
1474  */
1475  typedef DirectedTag directed_category;
1476 
1477  /** \brief The graph does not allow multiple edges between the same vertices
1478  (API: boost::graph, use via
1479  <tt>boost::graph_traits<Graph>::edge_parallel_category</tt>).
1480  */
1481  typedef boost::disallow_parallel_edge_tag edge_parallel_category;
1482 
1483  /** \brief The graph does not define internal property maps (API: boost::graph,
1484  use via <tt>boost::graph_traits<Graph>::vertex_property_type</tt>).
1485  */
1486  typedef boost::no_property vertex_property_type; // we only support "external properties".
1487  // FIXME: Maybe support the vertex -> coordinate map (identity) as the only internal property map
1488  // and additionally the vertex_descriptor -> ID map (vertex_index = SOI).
1489 
1490  /** \brief Define several graph tags related to graph traversal (API: boost::graph,
1491  use via <tt>boost::graph_traits<Graph>::traversal_category</tt>).
1492  */
1494  : virtual public boost::bidirectional_graph_tag,
1495  virtual public boost::adjacency_graph_tag,
1496  virtual public boost::vertex_list_graph_tag,
1497  virtual public boost::edge_list_graph_tag,
1498  virtual public boost::adjacency_matrix_tag
1499  {};
1500 
1501  // internal types
1507 
1508 
1509 
1510  ////////////////////////////////////////////////////////////////////
1511 
1512  // LEMON interface
1513  typedef self_type Graph;
1514 
1515  /** \brief The Node descriptor (API: LEMON).
1516  */
1517  typedef vertex_descriptor Node;
1518 
1519  /** \brief Iterator over all nodes of the graph (API: LEMON).
1520  */
1521  typedef vertex_iterator NodeIt;
1522 
1523  /** \brief The arc (directed edge) descriptor (API: LEMON).
1524  */
1525  typedef GridGraphArcDescriptor<N> Arc;
1526 
1527  /** \brief Iterator over the outgoing edges of a node (API: LEMON).
1528  */
1529  typedef GridGraphOutArcIterator<N> OutArcIt;
1530 
1531  /** \brief Iterator over only those outgoing edges of a node
1532  that end in a node with smaller ID (API: VIGRA).
1533  */
1534  typedef GridGraphOutArcIterator<N, true> OutBackArcIt;
1535 
1536  /** \brief Iterator over the acrs (directed edges) of a node (API: LEMON).
1537  */
1538  typedef GridGraphArcIterator<N, false> ArcIt;
1539 
1540  /** \brief Iterator over the incoming arcs of a node (API: LEMON).
1541  */
1542  typedef GridGraphInArcIterator<N> InArcIt;
1543 
1544  /** \brief The edge descriptor (API: LEMON).
1545  */
1547 
1548  /** \brief Iterator over the incident edges of a node (API: LEMON).
1549  */
1550  typedef GridGraphOutEdgeIterator<N> IncEdgeIt;
1551 
1552  /** \brief Iterator over only those incident edges of a node that
1553  end in a node with smaller ID (API: VIGRA).
1554  */
1555  typedef GridGraphOutEdgeIterator<N, true> IncBackEdgeIt;
1556 
1557  /** \brief Iterator over the edges of the graph (API: LEMON).
1558  */
1559  typedef GridGraphEdgeIterator<N, !is_directed> EdgeIt;
1560 
1561  typedef lemon::True NodeNumTag;
1562  typedef lemon::True EdgeNumTag;
1563  typedef lemon::True ArcNumTag;
1564  typedef lemon::True FindEdgeTag;
1565  typedef lemon::True FindArcTag;
1566 
1567  ////////////////////////////////////////////////////////////////////
1568 
1569  /** \brief Type of a node property map that maps node descriptor objects
1570  onto property values of type <tt>T</tt> (API: LEMON).
1571  */
1572  template <class T>
1573  class NodeMap
1574  : public MultiArray<N, T>
1575  {
1576  public:
1577  typedef MultiArray<N, T> base_type;
1578  typedef typename base_type::difference_type difference_type;
1579  typedef typename base_type::key_type key_type;
1580  typedef typename base_type::value_type value_type;
1581  typedef typename base_type::reference reference;
1582  typedef typename base_type::const_reference const_reference;
1583  typedef boost::read_write_property_map_tag category;
1584 
1585  typedef lemon::True ReferenceMapTag;
1586  typedef key_type Key;
1587  typedef value_type Value;
1588  typedef reference Reference;
1589  typedef const_reference ConstReference;
1590 
1591  NodeMap()
1592  : base_type()
1593  {}
1594 
1595  /** \brief Construct property map for the given graph \a g
1596  (preallocates a zero-initialized entry for each node of the graph).
1597  */
1598  explicit NodeMap(GridGraph const & g)
1599  : base_type(g.shape())
1600  {}
1601 
1602  /** \brief Construct property map for the given graph \a g
1603  (preallocates an entry with initial value \a t for each node of the graph).
1604  */
1605  NodeMap(GridGraph const & g, T const & t)
1606  : base_type(g.shape(), t)
1607  {}
1608 
1609  /** \brief Construct property map for the given \a shape.
1610  (preallocates a zero-initialized entry for each node of a grid
1611  graph with this shape).
1612  */
1613  explicit NodeMap(difference_type const & shape)
1614  : base_type(shape)
1615  {}
1616 
1617  /** \brief Construct property map for the given \a shape.
1618  (preallocates an entry with initial value \a t for each node of a grid
1619  graph with this shape).
1620  */
1621  NodeMap(difference_type const & shape, T const & t)
1622  : base_type(shape, t)
1623  {}
1624 
1625  NodeMap & operator=(NodeMap const & m)
1626  {
1628  return *this;
1629  }
1630 
1631  NodeMap & operator=(base_type const & m)
1632  {
1634  return *this;
1635  }
1636 
1637  // appropriate operator[] are inherited
1638 #ifdef DOXYGEN
1639  /** \brief Read/write access to the value associated with node descriptor \a key.
1640  */
1641  Value & operator[](Key const & key);
1642 
1643  /** \brief Read-only access to the value associated with node descriptor \a key.
1644  */
1645  Value const & operator[](Key const & key) const;
1646 #endif // DOXYGEN
1647 
1648  /** \brief Set the property of node desctiptor \a key to value \a v.
1649  */
1650  void set(Key const & k, Value const & v)
1651  {
1652  (*this)[k] = v;
1653  }
1654  };
1655 
1656 
1657  /** \brief Type of an edge property map that maps edge descriptor objects
1658  onto property values of type <tt>T</tt> (API: LEMON).
1659  */
1660  template <class T>
1661  class EdgeMap
1662  : public MultiArray<N+1, Multiband<T> >
1663  {
1664  public:
1666  typedef typename base_type::difference_type difference_type;
1667  typedef typename base_type::key_type key_type;
1668  typedef typename base_type::value_type value_type;
1669  typedef typename base_type::reference reference;
1670  typedef typename base_type::const_reference const_reference;
1671  typedef boost::read_write_property_map_tag category;
1672 
1673  typedef lemon::True ReferenceMapTag;
1674  typedef key_type Key;
1675  typedef value_type Value;
1676  typedef reference Reference;
1677  typedef const_reference ConstReference;
1678 
1679  EdgeMap()
1680  : base_type()
1681  {}
1682 
1683  /** \brief Construct property map for the given graph \a g
1684  (preallocates a zero-initialized entry for each edge of the graph).
1685  */
1686  explicit EdgeMap(GridGraph const & g)
1687  : base_type(g.edge_propmap_shape())
1688  {}
1689 
1690  /** \brief Construct property map for the given graph \a g
1691  (preallocates an entry with initial value \a t for each edge of the graph).
1692  */
1693  EdgeMap(GridGraph const & g, T const & t)
1694  : base_type(g.edge_propmap_shape(), t)
1695  {}
1696 
1697  /** \brief Construct property map for the given \a shape
1698  (preallocates a zero-initialized entry for each edge of
1699  a grid graph with this shape).
1700  */
1701  explicit EdgeMap(difference_type const & shape)
1702  : base_type(shape)
1703  {}
1704 
1705  /** \brief Construct property map for the given \a shape
1706  (preallocates an entry with initial value \a t for each edge
1707  of a grid graph with this shape).
1708  */
1709  EdgeMap(difference_type const & shape, T const & t)
1710  : base_type(shape, t)
1711  {}
1712 
1713  EdgeMap & operator=(EdgeMap const & m)
1714  {
1716  return *this;
1717  }
1718 
1719  EdgeMap & operator=(base_type const & m)
1720  {
1722  return *this;
1723  }
1724 
1725  // appropriate operator[] are inherited
1726 #ifdef DOXYGEN
1727  /** \brief Read/write access to the value associated with edge descriptor \a key.
1728  */
1729  Value & operator[](Key const & key);
1730 
1731  /** \brief Read-only access to the value associated with edge descriptor \a key.
1732  */
1733  Value const & operator[](Key const & key) const;
1734 #endif // DOXYGEN
1735 
1736  /** \brief Set the property of edge desctiptor \a key to value \a v.
1737  */
1738  void set(Key const & k, Value const & v)
1739  {
1740  (*this)[k] = v;
1741  }
1742  };
1743 
1744 #ifdef DOXYGEN
1745  /** \brief Type of an arc property map that maps arc descriptor objects
1746  onto property values of type <tt>T</tt> (API: LEMON).
1747  */
1748  template <class T>
1749  class ArcMap
1750  : public MultiArray<N+1, Multiband<T> >
1751  {
1752  public:
1753 
1754  /** \brief Construct property map for the given graph \a g
1755  (preallocates a zero-initialized entry for each arc of the graph).
1756  */
1757  explicit ArcMap(GridGraph const & g);
1758 
1759  /** \brief Construct property map for the given graph \a g
1760  (preallocates an entry with initial value \a t for each arc of the graph).
1761  */
1762  ArcMap(GridGraph const & g, T const & t);
1763 
1764  /** \brief Construct property map for the given \a shape
1765  (preallocates a zero-initialized entry for each arc of
1766  a grid graph with this shape).
1767  */
1768  explicit ArcMap(difference_type const & shape);
1769 
1770  /** \brief Construct property map for the given \a shape
1771  (preallocates an entry with initial value \a t for each arc of
1772  a grid graph with this shape).
1773  */
1774  ArcMap(difference_type const & shape, T const & t);
1775 
1776  /** \brief Read/write access to the value associated with arc descriptor \a key.
1777  */
1778  Value & operator[](Key const & key);
1779 
1780  /** \brief Read-only access to the value associated with arc descriptor \a key.
1781  */
1782  Value const & operator[](Key const & key) const;
1783 
1784  /** \brief Set the property of arc desctiptor \a key to value \a v.
1785  */
1786  void set(Key const & k, Value const & v);
1787  };
1788 #endif // DOXYGEN
1789 
1790  /** \brief Type of a property map that returns the coordinate of a given node (API: LEMON).
1791  */
1792  class IndexMap
1793  {
1794  public:
1795  typedef Node Key;
1796  typedef Node Value;
1797  typedef Key key_type;
1798  typedef Value value_type;
1799  typedef Value const & reference;
1800  typedef boost::readable_property_map_tag category;
1801 
1802  IndexMap()
1803  {}
1804 
1805  /** \brief Construct property map for the given graph.
1806  */
1807  explicit IndexMap(const GridGraph&)
1808  {}
1809 
1810  /** \brief Get the grid coordinate of the node descriptor \a key.
1811  */
1812  Value const & operator[](Key const & key) const
1813  {
1814  return key;
1815  }
1816  };
1817 
1818  /** \brief Type of a property map that returns the number of incoming edges of a given node (API: LEMON, use via <tt>lemon::InDegMap<Graph></tt>).
1819  */
1820  class InDegMap
1821  {
1822  public:
1823 
1824  /// The graph type of InDegMap (works for directed and undirected graphs)
1825  typedef GridGraph Graph;
1826  typedef GridGraph Digraph;
1827  typedef Node Key;
1828  typedef degree_size_type Value;
1829  typedef Key key_type;
1830  typedef Value value_type;
1831  typedef Value const & reference;
1832  typedef boost::readable_property_map_tag category;
1833 
1834  /** \brief Construct property map for the given graph.
1835  */
1836  explicit InDegMap(const GridGraph& graph)
1837  : graph_(graph)
1838  {}
1839 
1840  /** \brief Get the in-degree of the node descriptor \a key.
1841  */
1842  Value operator[](const Key& key) const
1843  {
1844  return graph_.in_degree(key);
1845  }
1846 
1847  protected:
1848 
1849  GridGraph const & graph_;
1850  };
1851 
1852  /** \brief Type of a property map that returns the number of outgoing edges of a given node (API: LEMON, use via <tt>lemon::OutDegMap<Graph></tt>).
1853  */
1855  {
1856  public:
1857 
1858  /// The graph type of OutDegMap (works for directed and undirected graphs)
1859  typedef GridGraph Graph;
1860  typedef GridGraph Digraph;
1861  typedef Node Key;
1862  typedef degree_size_type Value;
1863  typedef Key key_type;
1864  typedef Value value_type;
1865  typedef Value const & reference;
1866  typedef boost::readable_property_map_tag category;
1867 
1868  /** \brief Construct property map for the given graph.
1869  */
1870  explicit OutDegMap(const GridGraph& graph)
1871  : graph_(graph)
1872  {}
1873 
1874  /** \brief Get the out-degree of the node descriptor \a key.
1875  */
1876  Value operator[](const Key& key) const
1877  {
1878  return graph_.out_degree(key);
1879  }
1880 
1881  protected:
1882 
1883  GridGraph const & graph_;
1884  };
1885 
1886  ////////////////////////////////////////////////////////////////////
1887 
1888  // dummy default constructor to satisfy adjacency_graph concept
1889  GridGraph()
1890  : max_node_id_(-1),
1891  max_arc_id_(-1),
1892  max_edge_id_(-1)
1893  {}
1894 
1895  /** \brief Construct a grid graph with given \a shape and neighborhood type \a ntype.
1896 
1897  The shape must have type <tt>MultiArrayShape<N>::type</tt> with the appropriate
1898  dimension <tt>N</tt>. The neighborhood type can take the values
1899  <tt>DirectNeighborhood</tt> to use only the axis-aligned edges (2N-neighborhood)
1900  and <tt>IndirectNeighborhood</tt> to use all diagonal edges as well
1901  ((3<sup>N</sup>-1)-neighborhood).
1902  */
1903  GridGraph(shape_type const &shape, NeighborhoodType ntype = DirectNeighborhood)
1904  : shape_(shape),
1905  num_vertices_(prod(shape)),
1906  num_edges_(gridGraphEdgeCount(shape, ntype, is_directed)),
1907  max_node_id_(num_vertices_ - 1),
1908  max_arc_id_(-2),
1909  max_edge_id_(-2),
1910  neighborhoodType_(ntype)
1911  {
1912  // populate the neighborhood tables:
1913  // FIXME: this might be static (but make sure that it works with multi-threading)
1914  detail::makeArrayNeighborhood(neighborOffsets_, neighborExists_, neighborhoodType_);
1915  detail::computeNeighborOffsets(neighborOffsets_, neighborExists_, incrementalOffsets_,
1916  edgeDescriptorOffsets_, neighborIndices_, backIndices_, is_directed);
1917 
1918  // compute the neighbor offsets per neighborhood type
1919  // detail::makeArraySubNeighborhood(neighborhood[0], neighborExists, shape_type(1), neighborhoodIndices);
1920  }
1921 
1922  /** \brief Get the ID (i.e. scan-order index) for node desciptor \a v (API: LEMON).
1923  */
1924  index_type id(Node const & v) const
1925  {
1926  return detail::CoordinateToScanOrder<N>::exec(shape(), v);
1927  }
1928 
1929  index_type id(NodeIt const & v) const
1930  {
1931  return v.scanOrderIndex();
1932  }
1933 
1934  index_type id(neighbor_vertex_iterator const & v) const
1935  {
1936  return id(*v);
1937  }
1938 
1939  index_type id(back_neighbor_vertex_iterator const & v) const
1940  {
1941  return id(*v);
1942  }
1943 
1944  /** \brief Get node descriptor for given node ID \a i (API: LEMON).
1945 
1946  Return <tt>Node(lemon::INVALID)</tt> when the ID does not exist in this graph.
1947  */
1948  Node nodeFromId(index_type i) const
1949  {
1950  if(i < 0 || i > maxNodeId())
1951  return Node(lemon::INVALID);
1952 
1953  Node res(SkipInitialization);
1954  detail::ScanOrderToCoordinate<N>::exec(i, shape(), res);
1955  return res;
1956  }
1957 
1958  /** \brief Get the maximum ID of any node in this graph (API: LEMON).
1959  */
1960  index_type maxNodeId() const
1961  {
1962  return prod(shape()) - 1;
1963  }
1964 
1965  /** \brief Get the grid cordinate of the given node \a v (convenience function).
1966  */
1967  Node const & pos(Node const & v) const
1968  {
1969  return v;
1970  }
1971 
1972  /** \brief Get vertex iterator pointing to the first vertex of this graph (convenience function,<br/>
1973  the boost::graph API provides the free function <tt>boost::vertices(graph)</tt>,<br/>
1974  LEMON uses <tt>Graph::NodeIt(graph)</tt>).
1975  */
1976  vertex_iterator get_vertex_iterator() const
1977  {
1978  return vertex_iterator(shape_);
1979  }
1980 
1981  /** \brief Get vertex iterator pointing to the given vertex (API: VIGRA).
1982  */
1983  vertex_iterator get_vertex_iterator(vertex_descriptor const & v) const
1984  {
1985  return vertex_iterator(shape_) + v;
1986  }
1987 
1988  /** \brief Get vertex iterator pointing beyond the valid range of vertices of this graph (convenience function,<br/>
1989  the boost::graph API provides the free function <tt>boost::vertices(graph)</tt>,<br/>
1990  LEMON uses the special value <tt>lemon::INVALID</tt> instead).
1991  */
1992  vertex_iterator get_vertex_end_iterator() const
1993  {
1994  return get_vertex_iterator().getEndIterator();
1995  }
1996 
1997  /** \brief Get an iterator pointing to the first neighbor of the given vertex (convenience function,<br/>
1998  the boost::graph API provides the free function <tt>boost::adjacent_vertices(v, graph)</tt>,<br/>
1999  LEMON uses <tt>Graph::ArcIt(g, v)</tt>).
2000  */
2001  neighbor_vertex_iterator get_neighbor_vertex_iterator(vertex_descriptor const & v) const
2002  {
2003  return neighbor_vertex_iterator(*this, v);
2004  }
2005 
2006  /** \brief Get an iterator pointing beyond the range of neighbors of the given vertex (convenience function,<br/>
2007  the boost::graph API provides the free function <tt>boost::adjacent_vertices(v, graph)</tt>,<br/>
2008  LEMON uses the speical value <tt>lemon::INVALID</tt> instead).
2009  */
2011  {
2012  return get_neighbor_vertex_iterator(v).getEndIterator();
2013  }
2014 
2015  /** \brief Get an iterator pointing to the first backward neighbor of the given vertex (API: VIGRA,<br/>
2016  in analogy to the boost::graph API, we also provide a free function <tt>boost::back_adjacent_vertices(v, g)</tt>,<br/>
2017  and the LEMON analogue is <tt>Graph::OutBackArcIt(graph, v)</tt>).
2018  */
2020  {
2021  return back_neighbor_vertex_iterator(*this, v);
2022  }
2023 
2024  /** \brief Get an iterator pointing beyond the range of backward neighbors of the given vertex (API: VIGRA,<br/>
2025  in analogy to the boost::graph API, we also provide a free function <tt>boost::back_adjacent_vertices(v, g)</tt>,<br/>
2026  and LEMON just uses <tt>lemon::INVALID</tt> instead).
2027  */
2029  {
2030  return get_back_neighbor_vertex_iterator(v).getEndIterator();
2031  }
2032 
2033  // --------------------------------------------------
2034  // support for VertexListGraph:
2035 
2036  /** \brief Get the number of vertices in this graph (convenience function,
2037  the boost::graph API provides the free function <tt>boost::num_vertices(graph)</tt>).
2038  */
2040  {
2041  return num_vertices_;
2042  }
2043 
2044  /** \brief Get the number of nodes in this graph (API: LEMON).
2045  */
2047  {
2048  return num_vertices();
2049  }
2050 
2051  // --------------------------------------------------
2052  // support for IncidenceGraph:
2053 
2054  /** \brief Get the ID (i.e. scan-order index in an edge property map) for the
2055  given edges descriptor \a e (API: LEMON).
2056  */
2057  index_type id(Edge const & e) const
2058  {
2059  return detail::CoordinateToScanOrder<N+1>::exec(edge_propmap_shape(), e);
2060  }
2061 
2062  index_type id(EdgeIt const & e) const
2063  {
2064  return id(*e);
2065  }
2066 
2067  index_type id(IncEdgeIt const & e) const
2068  {
2069  return id(*e);
2070  }
2071 
2072  index_type id(IncBackEdgeIt const & e) const
2073  {
2074  return id(*e);
2075  }
2076 
2077  /** \brief Get the edge descriptor for the given edge ID \a i (API: LEMON).
2078 
2079  Return <tt>Edge(lemon::INVALID)</tt> when the ID does not exist
2080  in this graph.
2081  */
2082  Edge edgeFromId(index_type i) const
2083  {
2084  if(i < 0 || i > maxEdgeId())
2085  return Edge(lemon::INVALID);
2086 
2087  Edge res(SkipInitialization);
2088  detail::ScanOrderToCoordinate<N+1>::exec(i, edge_propmap_shape(), res);
2089 
2090  unsigned int b = detail::BorderTypeImpl<N>::exec(res.template subarray<0, N>(), shape());
2091  if(neighborExists_[b][res[N]])
2092  return res;
2093  else
2094  return Edge(lemon::INVALID);
2095  }
2096 
2097  /** \brief Get the maximum ID of any edge in this graph (API: LEMON).
2098  */
2099  index_type maxEdgeId() const
2100  {
2101  if(max_edge_id_ == -2) // -2 means uninitialized
2102  const_cast<GridGraph *>(this)->computeMaxEdgeAndArcId();
2103  return max_edge_id_;
2104  }
2105 
2106  /* Initial computation of the max_arc_id_ and max_edge_id_ (call in the constructor and
2107  whenever the shape changes).
2108  */
2109  void computeMaxEdgeAndArcId()
2110  {
2111  if(edgeNum() == 0)
2112  {
2113  max_arc_id_ = -1;
2114  max_edge_id_ = -1;
2115  }
2116  else
2117  {
2118  Node lastNode = shape() - shape_type(1);
2119  index_type n = neighborIndices_[get_border_type(lastNode)][0];
2120  Arc a(neighbor(lastNode, n), oppositeIndex(n), false);
2121  max_arc_id_ = detail::CoordinateToScanOrder<N+1>::exec(arc_propmap_shape(), a);
2122 
2123  if(is_directed)
2124  {
2125  max_edge_id_ = max_arc_id_;
2126  }
2127  else
2128  {
2129  Arc a(lastNode, backIndices_[get_border_type(lastNode)].back(), false);
2130  max_edge_id_ = detail::CoordinateToScanOrder<N+1>::exec(edge_propmap_shape(), a);
2131  }
2132  }
2133  }
2134 
2135  /** \brief Get the ID (i.e. scan-order index an an arc property map) for
2136  the given ar \a a (API: LEMON).
2137  */
2138  index_type id(Arc const & a) const
2139  {
2140  return detail::CoordinateToScanOrder<N+1>::exec(arc_propmap_shape(), directedArc(a));
2141  }
2142 
2143  index_type id(ArcIt const & a) const
2144  {
2145  return id(*a);
2146  }
2147 
2148  index_type id(OutArcIt const & a) const
2149  {
2150  return id(*a);
2151  }
2152 
2153  index_type id(OutBackArcIt const & a) const
2154  {
2155  return id(*a);
2156  }
2157 
2158  /** \brief Get an arc descriptor for the given arc ID \a i (API: LEMON).
2159 
2160  Return <tt>Arc(lemon::INVALID)</tt> when the ID does not exist
2161  in this graph.
2162  */
2163  Arc arcFromId(index_type i) const
2164  {
2165  if(i < 0 || i > maxArcId())
2166  return Arc(lemon::INVALID);
2167 
2168  Arc res;
2169  detail::ScanOrderToCoordinate<N+1>::exec(i, arc_propmap_shape(), res);
2170  unsigned int b = detail::BorderTypeImpl<N>::exec(res.template subarray<0, N>(), shape());
2171  if(neighborExists_[b][res[N]])
2172  return undirectedArc(res);
2173  else
2174  return Arc(lemon::INVALID);
2175  }
2176 
2177  /** \brief Get the maximal ID af any arc in this graph (API: LEMON).
2178  */
2179  index_type maxArcId() const
2180  {
2181  if(max_arc_id_ == -2) // -2 means uninitialized
2182  const_cast<GridGraph *>(this)->computeMaxEdgeAndArcId();
2183  return max_arc_id_;
2184  }
2185 
2186  /** \brief Return <tt>true</tt> when the arc is looking on the underlying
2187  edge in its natural (i.e. forward) direction, <tt>false</tt> otherwise (API: LEMON).
2188  */
2189  bool direction(Arc const & a) const
2190  {
2191  return !a.isReversed();
2192  }
2193 
2194  /** \brief Create an arc for the given edge \a e, oriented along the
2195  edge's natural (<tt>forward = true</tt>) or reversed
2196  (<tt>forward = false</tt>) direction (API: LEMON).
2197  */
2198  Arc direct(Edge const & e, bool forward) const
2199  {
2200  if(!is_directed || forward)
2201  return Arc(e, !forward);
2202  else
2203  return Arc(v(e), oppositeIndex(e[N]), true);
2204  }
2205 
2206  /** \brief Create an arc for the given edge \a e oriented
2207  so that node \a n is the starting node of the arc (API: LEMON), or
2208  return <tt>lemon::INVALID</tt> if the edge is not incident to this node.
2209  */
2210  Arc direct(Edge const & e, Node const & n) const
2211  {
2212  if(u(e) == n)
2213  return direct(e, true);
2214  if(v(e) == n)
2215  return direct(e, false);
2216  return Arc(lemon::INVALID);
2217  }
2218 
2219  /** \brief Return the opposite node of the given node \a n
2220  along edge \a e (API: LEMON), or return <tt>lemon::INVALID</tt>
2221  if the edge is not incident to this node.
2222  */
2223  Node oppositeNode(Node const & n, Edge const & e) const
2224  {
2225  Node start(u(e)), end(v(e));
2226  if(n == start)
2227  return end;
2228  if(n == end)
2229  return start;
2230  return Node(lemon::INVALID);
2231  }
2232 
2233  /** \brief Create an arc referring to the same edge as the given
2234  arc \a a, but with reversed direction (API: LEMON).
2235  */
2236  Arc oppositeArc(Arc const & a) const
2237  {
2238  return is_directed
2239  ? Arc(neighbor(a.vertexDescriptor(), a.edgeIndex()), oppositeIndex(a.edgeIndex()), false)
2240  : Arc(a, !a.isReversed());
2241  }
2242 
2243  // internal function
2244  // transforms the arc into its directed form (i.e. a.isReversed() is
2245  // guaranteed to be false in the returned arc).
2246  Arc directedArc(Arc const & a) const
2247  {
2248  return a.isReversed()
2249  ? Arc(neighbor(a.vertexDescriptor(), a.edgeIndex()), oppositeIndex(a.edgeIndex()), false)
2250  : a;
2251  }
2252 
2253  // internal function
2254  // transforms the arc into its undirected form (i.e. a.isReversed() will
2255  // be true in the returned arc if this graph is undirected and the arc
2256  // traverses the edge backwards).
2257  Arc undirectedArc(Arc const & a) const
2258  {
2259  return a.edgeIndex() < maxUniqueDegree()
2260  ? a
2261  : Arc(neighbor(a.vertexDescriptor(), a.edgeIndex()), oppositeIndex(a.edgeIndex()), true);
2262  }
2263 
2264  /** \brief Return the start node of the edge the given iterator is referring to (API: LEMON).
2265  */
2266  Node baseNode(IncEdgeIt const & e) const
2267  {
2268  return source(e.arcDescriptor());
2269  }
2270 
2271  /** \brief Return the start node of the edge the given iterator is referring to (API: VIGRA).
2272  */
2273  Node baseNode(IncBackEdgeIt const & e) const
2274  {
2275  return source(e.arcDescriptor());
2276  }
2277 
2278  /** \brief Return the start node of the edge the given iterator is referring to (API: LEMON).
2279  */
2280  Node baseNode(OutArcIt const & a) const
2281  {
2282  return source(*a);
2283  }
2284 
2285  /** \brief Return the start node of the edge the given iterator is referring to (API: VIGRA).
2286  */
2287  Node baseNode(OutBackArcIt const & a) const
2288  {
2289  return source(*a);
2290  }
2291 
2292  /** \brief Return the end node of the edge the given iterator is referring to (API: LEMON).
2293  */
2294  Node runningNode(IncEdgeIt const & e) const
2295  {
2296  return target(e.arcDescriptor());
2297  }
2298 
2299  /** \brief Return the end node of the edge the given iterator is referring to (API: VIGRA).
2300  */
2301  Node runningNode(IncBackEdgeIt const & e) const
2302  {
2303  return target(e.arcDescriptor());
2304  }
2305 
2306  /** \brief Return the end node of the edge the given iterator is referring to (API: LEMON).
2307  */
2308  Node runningNode(OutArcIt const & a) const
2309  {
2310  return target(*a);
2311  }
2312 
2313  /** \brief Return the end node of the edge the given iterator is referring to (API: VIGRA).
2314  */
2315  Node runningNode(OutBackArcIt const & a) const
2316  {
2317  return target(*a);
2318  }
2319 
2320  /** \brief Get the start node of the given arc \a a (API: LEMON).
2321  */
2322  Node source(Arc const & a) const
2323  {
2324  return source_or_target(a, true);
2325  }
2326 
2327  /** \brief Get the end node of the given arc \a a (API: LEMON).
2328  */
2329  Node target(Arc const & a) const
2330  {
2331  return source_or_target(a, false);
2332  }
2333 
2334  /** \brief Get the start node of the given edge \a e (API: LEMON,<br/>
2335  the boost::graph API provides the free function <tt>boost::source(e, graph)</tt>).
2336  */
2337  Node u(Edge const & e) const
2338  {
2339  return Node(e.template subarray<0,N>());
2340  }
2341 
2342  /** \brief Get the end node of the given edge \a e (API: LEMON,<br/>
2343  the boost::graph API provides the free function <tt>boost::target(e, graph)</tt>).
2344  */
2345  Node v(Edge const & e) const
2346  {
2347  return Node(e.template subarray<0,N>()) + neighborOffsets_[e[N]];
2348  }
2349 
2350  /** \brief Get an iterator pointing to the first outgoing edge of the given vertex (convenience function,<br/>
2351  the boost::graph API provides the free function <tt>boost::out_edges(v, graph)</tt>,<br/>
2352  LEMON uses <tt>Graph::OutArcIt(g, v)</tt>).
2353  */
2354  out_edge_iterator get_out_edge_iterator(vertex_descriptor const & v) const
2355  {
2356  return out_edge_iterator(*this, v);
2357  }
2358 
2359  /** \brief Get an iterator pointing beyond the range of outgoing edges of the given vertex (convenience function,<br/>
2360  the boost::graph API provides the free function <tt>boost::out_edges(v, graph)</tt>,<br/>
2361  LEMON uses the special value <tt>lemon::INVALID</tt> instead).
2362  */
2363  out_edge_iterator get_out_edge_end_iterator(vertex_descriptor const & v) const
2364  {
2365  return get_out_edge_iterator(v).getEndIterator();
2366  }
2367 
2368  /** \brief Get an iterator pointing to the first outgoing backward edge of the given vertex (API: VIGRA,<br/>
2369  in analogy to the boost::graph API, we also provide a free function <tt>boost::out_back_edges(v, g)</tt>,<br/>
2370  and the LEMON analogue is <tt>Graph::IncBackEdgeIt(graph, v)</tt>).
2371  */
2372  out_back_edge_iterator get_out_back_edge_iterator(vertex_descriptor const & v) const
2373  {
2374  return out_back_edge_iterator(*this, v);
2375  }
2376 
2377  /** \brief Get an iterator pointing beyond the range of outgoing backward edges of the given vertex (API: VIGRA,<br/>
2378  in analogy to the boost::graph API, we also provide a free function <tt>boost::out_back_edges(v, g)</tt>,<br/>
2379  and LEMON uses the special value <tt>lemon::INVALID</tt> instead).
2380  */
2381  out_back_edge_iterator get_out_back_edge_end_iterator(vertex_descriptor const & v) const
2382  {
2383  return get_out_back_edge_iterator(v).getEndIterator();
2384  }
2385 
2386  /** \brief Get an iterator pointing to the first incoming edge of the given vertex (convenience function,<br/>
2387  the boost::graph API provides the free function <tt>boost::in_edges(v, graph)</tt>,<br/>
2388  LEMON uses <tt>Graph::InArcIt(g, v)</tt>).
2389  */
2390  in_edge_iterator get_in_edge_iterator(vertex_descriptor const & v) const
2391  {
2392  return in_edge_iterator(*this, v);
2393  }
2394 
2395  /** \brief Get an iterator pointing beyond the range of incoming edges of the given vertex (convenience function,<br/>
2396  the boost::graph API provides the free function <tt>boost::in_edges(v, graph)</tt>,<br/>
2397  LEMON uses the special value <tt>lemon::INVALID</tt> instead).
2398  */
2399  in_edge_iterator get_in_edge_end_iterator(vertex_descriptor const & v) const
2400  {
2401  return get_in_edge_iterator(v).getEndIterator();
2402  }
2403 
2404  /** \brief Get the number of outgoing edges of the given vertex (convenience function,<br/>
2405  the boost::graph API provides the free function <tt>boost::out_degree(v, graph)</tt>,<br/>
2406  LEMON uses a special property map <tt>lemon::OutDegMap<Graph></tt>).
2407  */
2408  degree_size_type out_degree(vertex_descriptor const & v) const
2409  {
2410  return (degree_size_type)neighborIndices_[get_border_type(v)].size();
2411  }
2412 
2413  /** \brief Get the number of outgoing backward edges of the given vertex (API: VIGRA).
2414  */
2415  degree_size_type back_degree(vertex_descriptor const & v) const
2416  {
2417  return (degree_size_type)backIndices_[get_border_type(v)].size();
2418  }
2419 
2420  /** \brief Get the number of outgoing forward edges of the given vertex (API: VIGRA).
2421  */
2422  degree_size_type forward_degree(vertex_descriptor const & v) const
2423  {
2424  unsigned int bt = get_border_type(v);
2425  return (degree_size_type)(neighborIndices_[bt].size() - backIndices_[bt].size());
2426  }
2427 
2428  /** \brief Get the number of incoming edges of the given vertex (convenience function,<br/>
2429  the boost::graph API provides the free function <tt>boost::in_degree(v, graph)</tt>,<br/>
2430  LEMON uses a special property map <tt>lemon::InDegMap<Graph></tt>).
2431  */
2432  degree_size_type in_degree(vertex_descriptor const & v) const
2433  {
2434  return out_degree(v);
2435  }
2436 
2437  /** \brief Get the total number of edges (incoming plus outgoing) of the given vertex (convenience function,<br/>
2438  the boost::graph API provides the free function <tt>boost::degree(v, graph)</tt>,<br/>
2439  LEMON has no analogue).
2440  */
2441  degree_size_type degree(vertex_descriptor const & v) const
2442  {
2443  return is_directed
2444  ? 2*out_degree(v)
2445  : out_degree(v);
2446  }
2447 
2448  // --------------------------------------------------
2449  // support for EdgeListGraph:
2450 
2451  /** \brief Get the number of edges in this graph (convenience function,
2452  boost::graph API provides the free function <tt>boost::num_edges(graph)</tt>).
2453  */
2455  {
2456  return num_edges_;
2457  }
2458 
2459  /** \brief Get the number of edges in this graph (API: LEMON).
2460  */
2462  {
2463  return num_edges();
2464  }
2465 
2466  /** \brief Get the number of arc in this graph (API: LEMON).
2467  */
2469  {
2470  return is_directed
2471  ? num_edges()
2472  : 2*num_edges();
2473  }
2474 
2475  /** \brief Get edge iterator pointing to the first edge of the graph (convenience function,<br/>
2476  the boost::graph API provides the free function <tt>boost::edges(graph)</tt>,<br/>
2477  LEMON uses <tt>Graph::EdgeIt(graph)</tt>).
2478  */
2480  {
2481  return edge_iterator(*this);
2482  }
2483 
2484  /** \brief Get edge iterator pointing beyond the valid range of edges of this graph (convenience function,<br/>
2485  the boost::graph API provides the free function <tt>boost::vertices(graph)</tt>,<br/>
2486  LEMON uses the special value <tt>lemon::INVALID</tt> instead).
2487  */
2489  {
2490  return get_edge_iterator().getEndIterator();
2491  }
2492 
2493  // --------------------------------------------------
2494  // support for AdjacencyMatrix concept:
2495 
2496  /** \brief Get a descriptor for the edge connecting vertices \a u and \a v,<br/>
2497  or <tt>(lemon::INVALID, false)</tt> if no such edge exists (convenience function,<br/>
2498  the boost::graph API provides the free function <tt>boost::edge(u, v, graph)</tt>).
2499  */
2500  std::pair<edge_descriptor, bool>
2501  edge(vertex_descriptor const & u, vertex_descriptor const & v) const
2502  {
2503  std::pair<edge_descriptor, bool> res(lemon::INVALID, false);
2504 
2506  end = i.getEndIterator();
2507  for (; i != end; ++i)
2508  {
2509  if (*i == v)
2510  {
2511  res.first = make_edge_descriptor(u, i.neighborIndex());
2512  res.second = true;
2513  break;
2514  }
2515  }
2516  return res;
2517  }
2518 
2519  /** \brief Get a descriptor for the edge connecting vertices \a u and \a v,<br/>or <tt>lemon::INVALID</tt> if no such edge exists (API: LEMON).
2520  */
2521  Edge findEdge(Node const & u, Node const & v, Edge const & = lemon::INVALID) const
2522  {
2523  return this->edge(u, v).first;
2524  }
2525 
2526  /** \brief Get a descriptor for the arc connecting vertices \a u and \a v,<br/>or <tt>lemon::INVALID</tt> if no such edge exists (API: LEMON).
2527  */
2528  Arc findArc(Node const & u, Node const & v, Arc const & = lemon::INVALID) const
2529  {
2530  return this->edge(u, v).first;
2531  // std::pair<edge_descriptor, bool> res(edge(u, v));
2532  // return res.second
2533  // ? res.first
2534  // : Arc(lemon::INVALID);
2535  }
2536 
2537  /** \brief Create a property map that returns the coordinate of each node (API: LEMON GridGraph).
2538  */
2539  IndexMap indexMap() const
2540  {
2541  return IndexMap();
2542  }
2543 
2544  // --------------------------------------------------
2545  // other helper functions:
2546 
2547  bool isDirected() const
2548  {
2549  return is_directed;
2550  }
2551 
2552  degree_size_type maxDegree() const
2553  {
2554  return (degree_size_type)neighborOffsets_.size();
2555  }
2556 
2557  degree_size_type maxUniqueDegree() const
2558  {
2559  return is_directed
2560  ? maxDegree()
2561  : maxDegree() / 2;
2562  }
2563 
2564  shape_type const & shape() const
2565  {
2566  return shape_;
2567  }
2568 
2569  edge_propmap_shape_type edge_propmap_shape() const
2570  {
2571  edge_propmap_shape_type res(SkipInitialization);
2572  res.template subarray<0, N>() = shape_;
2573  res[N] = maxUniqueDegree();
2574  return res;
2575  }
2576 
2577  edge_propmap_shape_type arc_propmap_shape() const
2578  {
2579  edge_propmap_shape_type res(SkipInitialization);
2580  res.template subarray<0, N>() = shape_;
2581  res[N] = maxDegree();
2582  return res;
2583  }
2584 
2585  unsigned int get_border_type(vertex_descriptor const & v) const
2586  {
2587  return detail::BorderTypeImpl<N>::exec(v, shape_);
2588  }
2589 
2590  unsigned int get_border_type(vertex_iterator const & v) const
2591  {
2592  return v.borderType();
2593  }
2594 
2595  index_type oppositeIndex(index_type neighborIndex) const
2596  {
2597  return maxDegree() - neighborIndex - 1;
2598  }
2599 
2600  /* the given neighborIndex must be valid for the given vertex,
2601  otherwise this function will crash
2602  */
2603  edge_descriptor make_edge_descriptor(vertex_descriptor const & v,
2604  index_type neighborIndex) const
2605  {
2606  if(neighborIndex < maxUniqueDegree())
2607  return edge_descriptor(v, neighborIndex, false);
2608  else
2609  return edge_descriptor(neighbor(v, neighborIndex), oppositeIndex(neighborIndex), true);
2610  }
2611 
2612  shape_type const & neighborOffset(index_type neighborIndex) const
2613  {
2614  return neighborOffsets_[neighborIndex];
2615  }
2616 
2617  vertex_descriptor neighbor(vertex_descriptor const & v, index_type neighborIndex) const
2618  {
2619  return v + neighborOffsets_[neighborIndex];
2620  }
2621 
2622  vertex_descriptor
2623  source_or_target(edge_descriptor const & e, bool return_source) const
2624  {
2625  // source is always the attached node (first coords) unless the
2626  // edge has been reversed.
2627  if ((return_source && e.isReversed()) ||
2628  (!return_source && !e.isReversed()))
2629  {
2630  return neighbor(e.vertexDescriptor(), e.edgeIndex());
2631  }
2632  else
2633  {
2634  return e.vertexDescriptor();
2635  }
2636  }
2637 
2638  NeighborOffsetArray const * neighborOffsetArray() const
2639  {
2640  return &neighborOffsets_;
2641  }
2642 
2643  RelativeNeighborOffsetsArray const * neighborIncrementArray() const
2644  {
2645  return &incrementalOffsets_;
2646  }
2647 
2648  RelativeEdgeOffsetsArray const * edgeIncrementArray() const
2649  {
2650  return &edgeDescriptorOffsets_;
2651  }
2652 
2653  IndexArray const * neighborIndexArray(bool backEdgesOnly) const
2654  {
2655  return backEdgesOnly
2656  ? &backIndices_
2657  : &neighborIndices_;
2658  }
2659 
2660  protected:
2661  NeighborOffsetArray neighborOffsets_;
2662  NeighborExistsArray neighborExists_;
2663  IndexArray neighborIndices_, backIndices_;
2664  RelativeNeighborOffsetsArray incrementalOffsets_;
2665  RelativeEdgeOffsetsArray edgeDescriptorOffsets_;
2666  shape_type shape_;
2667  MultiArrayIndex num_vertices_, num_edges_, max_node_id_, max_arc_id_, max_edge_id_;
2668  NeighborhoodType neighborhoodType_;
2669 };
2670 
2671 //@}
2672 
2673 } // namespace vigra
2674 
2675 namespace boost {
2676 
2677 /** \addtogroup BoostGraphExtensions GridGraph additions to namespace <tt>boost</tt>
2678 
2679  provides the required functionality to make \ref vigra::GridGraph compatible to the boost::graph library.
2680 */
2681 //@{
2682 
2683 
2684 
2685 template <unsigned int N, class T, class Acc>
2686 struct property_traits<vigra::MultiArray<N, T, Acc> >
2687 {
2688  typedef vigra::MultiArray<N, T, Acc> type;
2689  typedef typename type::key_type key_type;
2690  typedef typename type::value_type value_type;
2691  typedef typename type::reference reference;
2692  typedef boost::read_write_property_map_tag category;
2693 };
2694 
2695 template <unsigned int N, class T, class Acc>
2696 struct property_traits<vigra::MultiArray<N, T, Acc> const>
2697 {
2698  typedef vigra::MultiArray<N, T, Acc> const type;
2699  typedef typename type::key_type key_type;
2700  typedef typename type::value_type value_type;
2701  typedef typename type::const_reference reference;
2702  typedef boost::readable_property_map_tag category;
2703 };
2704 
2705 template <unsigned int N, class T, class Stride>
2706 struct property_traits<vigra::MultiArrayView<N, T, Stride> >
2707 {
2709  typedef typename type::key_type key_type;
2710  typedef typename type::value_type value_type;
2711  typedef typename type::reference reference;
2712  typedef boost::read_write_property_map_tag category;
2713 };
2714 
2715 template <unsigned int N, class T, class Stride>
2716 struct property_traits<vigra::MultiArrayView<N, T, Stride> const>
2717 {
2718  typedef vigra::MultiArrayView<N, T, Stride> const type;
2719  typedef typename type::key_type key_type;
2720  typedef typename type::value_type value_type;
2721  typedef typename type::const_reference reference;
2722  typedef boost::readable_property_map_tag category;
2723 };
2724 
2725  /** \brief Return number of outgoing edges of vertex \a v (API: boost).
2726  */
2727 template<unsigned int N, class DirectedTag>
2728 inline
2732 {
2733  return g.out_degree(v);
2734 }
2735 
2736  /** \brief Return number of incoming edges of vertex \a v (API: boost).
2737  */
2738 template<unsigned int N, class DirectedTag>
2739 inline
2743 {
2744  return g.in_degree(v);
2745 }
2746 
2747  /** \brief Return total number of edges (incoming and outgoing) of vertex \a v (API: boost).
2748  */
2749 template<unsigned int N, class DirectedTag>
2750 inline
2754 {
2755  return g.degree(v);
2756 }
2757 
2758  /** \brief Get a (begin, end) iterator pair for the vertices of graph \a g (API: boost).
2759  */
2760 template<unsigned int N, class DirectedTag>
2761 inline
2762 std::pair<typename vigra::GridGraph<N, DirectedTag>::vertex_iterator,
2765 {
2766  return std::make_pair(g.get_vertex_iterator(),
2768 }
2769 
2770  /** \brief Return the number of vertices in graph \a g (API: boost).
2771  */
2772 template<unsigned int N, class DirectedTag>
2773 inline
2775 num_vertices(vigra::GridGraph<N, DirectedTag> const & g)
2776 {
2777  return g.num_vertices();
2778 }
2779 
2780  /** \brief Get a (begin, end) iterator pair for the neighbor vertices of
2781  vertex \a v in graph \a g (API: boost).
2782  */
2783 template<unsigned int N, class DirectedTag>
2784 inline
2785 std::pair<typename vigra::GridGraph<N, DirectedTag>::adjacency_iterator,
2789 {
2790  return std::make_pair(g.get_neighbor_vertex_iterator(v),
2792 }
2793 
2794  /** \brief Get a (begin, end) iterator pair for only thise neighbor vertices of
2795  vertex \a v that have smaller ID than \a v (API: VIGRA).
2796  */
2797 template<unsigned int N, class DirectedTag>
2798 inline
2799 std::pair<typename vigra::GridGraph<N, DirectedTag>::back_neighbor_vertex_iterator,
2803 {
2804  return std::make_pair(g.get_back_neighbor_vertex_iterator(v),
2806 }
2807 
2808 // adjacent_vertices variant in vigra namespace: allows to call adjacent_vertices with vertex_iterator argument
2809 template<unsigned int N, class DirectedTag>
2810 inline
2811 std::pair<typename vigra::GridGraph<N, DirectedTag>::adjacency_iterator,
2813 adjacent_vertices_at_iterator(typename vigra::GridGraph<N, DirectedTag>::vertex_iterator const & v,
2815 {
2816  return std::make_pair(g.get_neighbor_vertex_iterator(v),
2818 }
2819 
2820  /** \brief Get a (begin, end) iterator pair for the outgoing edges of
2821  vertex \a v in graph \a g (API: boost).
2822  */
2823 template<unsigned int N, class DirectedTag>
2824 inline
2825 std::pair<typename vigra::GridGraph<N, DirectedTag>::out_edge_iterator,
2829 {
2830  return std::make_pair(g.get_out_edge_iterator(v),
2832 }
2833 
2834  /** \brief Get a (begin, end) iterator pair for only those outgoing edges of
2835  vertex \a v whose ID is smaller than that of \a v (API: VIGRA).
2836  */
2837 template<unsigned int N, class DirectedTag>
2838 inline
2839 std::pair<typename vigra::GridGraph<N, DirectedTag>::out_back_edge_iterator,
2843 {
2844  return std::make_pair(g.get_out_back_edge_iterator(v),
2846 }
2847 
2848  /** \brief Get a (begin, end) iterator pair for the incoming edges of
2849  vertex \a v in graph \a g (API: boost).
2850  */
2851 template<unsigned int N, class DirectedTag>
2852 inline
2853 std::pair<typename vigra::GridGraph<N, DirectedTag>::in_edge_iterator,
2857 {
2858  return std::make_pair(g.get_in_edge_iterator(v),
2859  g.get_in_edge_end_iterator(v));
2860 }
2861 
2862  /** \brief Get a vertex descriptor for the start vertex of edge \a e in graph \a g (API: boost).
2863  */
2864 template<unsigned int N, class DirectedTag>
2865 inline
2869 {
2870  return g.source(e);
2871 }
2872 
2873  /** \brief Get a vertex descriptor for the end vertex of edge \a e in graph \a g (API: boost).
2874  */
2875 template<unsigned int N, class DirectedTag>
2876 inline
2880 {
2881  return g.target(e);
2882 }
2883 
2884  /** \brief Get a (begin, end) iterator pair for the edges of graph \a g (API: boost).
2885  */
2886 template<unsigned int N, class DirectedTag>
2887 inline
2888 std::pair<typename vigra::GridGraph<N, DirectedTag>::edge_iterator,
2891 {
2892  return std::make_pair(g.get_edge_iterator(), g.get_edge_end_iterator());
2893 }
2894 
2895  /** \brief Return the number of edges in graph \a g (API: boost).
2896  */
2897 template<unsigned int N, class DirectedTag>
2898 inline
2901 {
2902  return g.num_edges();
2903 }
2904 
2905 // --------------------------------------------------
2906 // support for AdjacencyMatrix concept:
2907 
2908 // FIXME: test this
2909  /** \brief Return the pair (edge_descriptor, true) when an edge between vertices
2910  \a u and \a v exists, or (lemon::INVALID, false) otherwise (API: boost).
2911  */
2912 template<unsigned int N, class DirectedTag>
2913 std::pair<typename vigra::GridGraph<N, DirectedTag>::edge_descriptor, bool>
2917 {
2918  return g.edge(u,v);
2919 }
2920 
2921 // provide get / put for MultiArrayViews, indexed by the
2922 // above-defined vertex_descriptor and edge_descriptor (in our case, a coordinate tuple):
2923 // FIXME: place this into multi_array.hxx ?
2924  /** \brief Put value \a val at key \a k in the property map \a pmap (API: boost).
2925  */
2926 template<unsigned int N, class T, class Stride, class U>
2927 inline
2930  U const & val)
2931 {
2932  pmap[k] = val;
2933 }
2934 
2935  /** \brief Read the value at key \a k in property map \a pmap (API: boost).
2936  */
2937 //template<unsigned int N, class T, class Stride>
2938 //inline
2939 //typename vigra::MultiArrayView<N, T, Stride>::const_reference
2940 //get(vigra::MultiArrayView<N, T, Stride> const & pmap,
2941 // typename vigra::MultiArrayView<N, T, Stride>::difference_type const & k)
2942 //{
2943 // return pmap[k];
2944 //}
2945 
2946 
2947 
2948 #if 0
2949 
2950 // property map support for mapping coordinates to scan-order indices:
2951 
2952 template<unsigned int N>
2953 struct IDMapper {
2954  typedef typename vigra::GridGraph<N> graph_type;
2955  typedef boost::readable_property_map_tag category;
2956  typedef typename graph_type::index_type value_type;
2957  typedef typename graph_type::vertex_descriptor key_type;
2958  typedef const value_type& reference;
2959 
2960 
2961  IDMapper(const graph_type &graph)
2962  : map_helper(graph.get_vertex_iterator())
2963  {}
2964 
2965  typename graph_type::vertex_iterator map_helper;
2966 };
2967 
2968 template<unsigned int N>
2969 struct property_map<vigra::GridGraph<N>, boost::vertex_index_t>
2970 {
2971  typedef IDMapper<N> type;
2972  typedef IDMapper<N> const_type;
2973 };
2974 
2975 
2976 template<unsigned int N>
2977 inline
2978 typename IDMapper<N>::value_type
2979 get(const IDMapper<N> & mapper,
2980  const typename IDMapper<N>::key_type &k)
2981 {
2982  return (mapper.map_helper + k).scanOrderIndex();
2983 }
2984 
2985 
2986 template<unsigned int N>
2987 typename boost::property_map<vigra::GridGraph<N>, boost::vertex_index_t>::type
2988 //typename IDMapper<N>
2989 get(boost::vertex_index_t, const vigra::GridGraph<N> &graph) {
2990  // return a lightweight wrapper for the CoupledIterator, which easily allows the conversion of
2991  // coordinates via its += operator followed by index().
2992  return IDMapper<N>(graph);
2993 }
2994 
2995 // CHECK if required: also provide the direct (three-parameter) version for index lookup
2996 template<unsigned int N>
2998 get(boost::vertex_index_t,
2999  const vigra::GridGraph<N> &graph,
3000  const typename vigra::GridGraph<N>::vertex_descriptor &v) {
3001  return (IDMapper<N>(graph).map_helper + v).scanOrderIndex();
3002 }
3003 
3004 
3005 // TODO:
3006 // eventually provide an edge_index property map as well?
3007 // (edge_descriptor -> linear contiguous edge index)
3008 
3009 #endif
3010 
3011 //@}
3012 
3013 } // namespace boost
3014 
3015 namespace lemon {
3016 
3017 template <typename GR>
3018 class InDegMap;
3019 
3020  // LEMON-compatible property map for the in-degree of the nodes
3021 template<unsigned int N, class DirectedTag>
3022 class InDegMap<vigra::GridGraph<N, DirectedTag> >
3023 : public vigra::GridGraph<N, DirectedTag>::InDegMap
3024 {
3025  public:
3026  typedef vigra::GridGraph<N, DirectedTag> Graph;
3027 
3028  explicit InDegMap(const Graph& graph)
3029  : Graph::InDegMap(graph)
3030  {}
3031 };
3032 
3033 template <typename GR>
3034 class OutDegMap;
3035 
3036  // LEMON-compatible property map for the out-degree of the nodes
3037 template<unsigned int N, class DirectedTag>
3038 class OutDegMap<vigra::GridGraph<N, DirectedTag> >
3039 : public vigra::GridGraph<N, DirectedTag>::OutDegMap
3040 {
3041  public:
3042  typedef vigra::GridGraph<N, DirectedTag> Graph;
3043 
3044  explicit OutDegMap(const Graph& graph)
3045  : Graph::OutDegMap(graph)
3046  {}
3047 };
3048 
3049 
3050 } // namespace lemon
3051 
3052 namespace vigra {
3053 namespace boost_graph {
3054 
3055 //using boost::get;
3056 
3057 }} // namespace vigra::boost_graph
3058 
3059 
3060 namespace std {
3061 
3062 template<unsigned int N, class DirectedTag>
3063 ostream& operator<<(ostream& out,
3065 {
3066  out << "v" << arg.scanOrderIndex();
3067  return out;
3068 }
3069 
3070 template<unsigned int N, class DirectedTag>
3071 ostream& operator<<(ostream& out,
3073 {
3074  out << "nb" << arg.index();
3075  return out;
3076 }
3077 
3078 } // namespace std
3079 
3080 
3081 
3082 #endif /* VIGRA_MULTI_GRIDGRAPH_HXX */
3083 
3084 
3085 

© Ullrich Köthe (ullrich.koethe@iwr.uni-heidelberg.de)
Heidelberg Collaboratory for Image Processing, University of Heidelberg, Germany

html generated using doxygen and Python
vigra 1.10.0 (Thu Jan 8 2015)