vigra - vigra/multi_gridgraph.hxx Source File

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

multi_gridgraph.hxx |

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
51 typename vigra::MultiArrayView<N, T, Stride>::const_reference
52 get(vigra::MultiArrayView<N, T, Stride> const & pmap,
53 typename vigra::MultiArrayView<N, T, Stride>::difference_type const & k)
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>
181 MultiArrayIndex
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;
1390 typedef GridGraph<N, DirectedTag> self_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 */
1398 typedef typename MultiArrayShape<N>::type shape_type;
1399
1400 /** \brief Shape type of an edge property map (must have one additional dimension).
1401 */
1402 typedef typename MultiArrayShape<N+1>::type edge_propmap_shape_type;
1403
1404 /** \brief Type of node and edge IDs.
1405 */
1406 typedef MultiArrayIndex index_type;
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 */
1411 typedef MultiArrayIndex vertices_size_type;
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 */
1416 typedef MultiArrayIndex edges_size_type;
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 */
1421 typedef MultiArrayIndex degree_size_type;
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 */
1426 typedef MultiCoordinateIterator<N> vertex_iterator;
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 */
1435 typedef adjacency_iterator neighbor_vertex_iterator;
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 */
1493 struct traversal_category
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
1502 typedef ArrayVector<shape_type> NeighborOffsetArray;
1503 typedef ArrayVector<NeighborOffsetArray> RelativeNeighborOffsetsArray;
1504 typedef ArrayVector<ArrayVector<edge_descriptor> > RelativeEdgeOffsetsArray;
1505 typedef ArrayVector<ArrayVector<MultiArrayIndex> > IndexArray;
1506 typedef ArrayVector<ArrayVector<bool> > NeighborExistsArray;
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 */
1546 typedef typename MultiArrayShape<N+1>::type Edge;
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 {
1627 base_type::operator=(m);
1628 return *this;
1629 }
1630
1631 NodeMap & operator=(base_type const & m)
1632 {
1633 base_type::operator=(m);
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:
1665 typedef MultiArray<N+1, Multiband<T> > base_type;
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 {
1715 base_type::operator=(m);
1716 return *this;
1717 }
1718
1719 EdgeMap & operator=(base_type const & m)
1720 {
1721 base_type::operator=(m);
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 */
1854 class OutDegMap
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 */
2010 neighbor_vertex_iterator get_neighbor_vertex_end_iterator(vertex_descriptor const & v) const
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 */
2019 back_neighbor_vertex_iterator get_back_neighbor_vertex_iterator(vertex_descriptor const & v) const
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 */
2028 back_neighbor_vertex_iterator get_back_neighbor_vertex_end_iterator(vertex_descriptor const & v) const
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 */
2039 vertices_size_type num_vertices() const
2040 {
2041 return num_vertices_;
2042 }
2043
2044 /** \brief Get the number of nodes in this graph (API: LEMON).
2045 */
2046 vertices_size_type nodeNum() const
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 */
2454 edges_size_type num_edges() const
2455 {
2456 return num_edges_;
2457 }
2458
2459 /** \brief Get the number of edges in this graph (API: LEMON).
2460 */
2461 edges_size_type edgeNum() const
2462 {
2463 return num_edges();
2464 }
2465
2466 /** \brief Get the number of arc in this graph (API: LEMON).
2467 */
2468 edges_size_type arcNum() const
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 */
2479 edge_iterator get_edge_iterator() const
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 */
2488 edge_iterator get_edge_end_iterator() const
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
2505 neighbor_vertex_iterator i = get_neighbor_vertex_iterator(u),
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 {
2708 typedef vigra::MultiArrayView<N, T, Stride> type;
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
2729 typename vigra::GridGraph<N, DirectedTag>::degree_size_type
2730 out_degree(typename vigra::GridGraph<N, DirectedTag>::vertex_descriptor const & v,
2731 vigra::GridGraph<N, DirectedTag> const & g)
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
2740 typename vigra::GridGraph<N, DirectedTag>::degree_size_type
2741 in_degree(typename vigra::GridGraph<N, DirectedTag>::vertex_descriptor const & v,
2742 vigra::GridGraph<N, DirectedTag> const & g)
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
2751 typename vigra::GridGraph<N, DirectedTag>::degree_size_type
2752 degree(typename vigra::GridGraph<N, DirectedTag>::vertex_descriptor const & v,
2753 vigra::GridGraph<N, DirectedTag> const & g)
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,
2763 typename vigra::GridGraph<N, DirectedTag>::vertex_iterator>
2764 vertices(vigra::GridGraph<N, DirectedTag> const & g)
2765 {
2766 return std::make_pair(g.get_vertex_iterator(),
2767 g.get_vertex_end_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
2774 typename vigra::GridGraph<N, DirectedTag>::vertices_size_type
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,
2786 typename vigra::GridGraph<N, DirectedTag>::adjacency_iterator>
2787 adjacent_vertices(typename vigra::GridGraph<N, DirectedTag>::vertex_descriptor const & v,
2788 vigra::GridGraph<N, DirectedTag> const & g)
2789 {
2790 return std::make_pair(g.get_neighbor_vertex_iterator(v),
2791 g.get_neighbor_vertex_end_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,
2800 typename vigra::GridGraph<N, DirectedTag>::back_neighbor_vertex_iterator>
2801 back_adjacent_vertices(typename vigra::GridGraph<N, DirectedTag>::vertex_descriptor const & v,
2802 vigra::GridGraph<N, DirectedTag> const & g)
2803 {
2804 return std::make_pair(g.get_back_neighbor_vertex_iterator(v),
2805 g.get_back_neighbor_vertex_end_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,
2812 typename vigra::GridGraph<N, DirectedTag>::adjacency_iterator>
2813 adjacent_vertices_at_iterator(typename vigra::GridGraph<N, DirectedTag>::vertex_iterator const & v,
2814 vigra::GridGraph<N, DirectedTag> const & g)
2815 {
2816 return std::make_pair(g.get_neighbor_vertex_iterator(v),
2817 g.get_neighbor_vertex_end_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,
2826 typename vigra::GridGraph<N, DirectedTag>::out_edge_iterator>
2827 out_edges(typename vigra::GridGraph<N, DirectedTag>::vertex_descriptor const & v,
2828 vigra::GridGraph<N, DirectedTag> const & g)
2829 {
2830 return std::make_pair(g.get_out_edge_iterator(v),
2831 g.get_out_edge_end_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,
2840 typename vigra::GridGraph<N, DirectedTag>::out_back_edge_iterator>
2841 out_back_edges(typename vigra::GridGraph<N, DirectedTag>::vertex_descriptor const & v,
2842 vigra::GridGraph<N, DirectedTag> const & g)
2843 {
2844 return std::make_pair(g.get_out_back_edge_iterator(v),
2845 g.get_out_back_edge_end_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,
2854 typename vigra::GridGraph<N, DirectedTag>::in_edge_iterator>
2855 in_edges(typename vigra::GridGraph<N, DirectedTag>::vertex_descriptor const & v,
2856 vigra::GridGraph<N, DirectedTag> const & g)
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
2866 typename vigra::GridGraph<N, DirectedTag>::vertex_descriptor
2867 source(typename vigra::GridGraph<N, DirectedTag>::edge_descriptor const & e,
2868 vigra::GridGraph<N, DirectedTag> const & g)
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
2877 typename vigra::GridGraph<N, DirectedTag>::vertex_descriptor
2878 target(typename vigra::GridGraph<N, DirectedTag>::edge_descriptor const & e,
2879 vigra::GridGraph<N, DirectedTag> const & g)
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,
2889 typename vigra::GridGraph<N, DirectedTag>::edge_iterator>
2890 edges(vigra::GridGraph<N, DirectedTag> const & g)
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
2899 typename vigra::GridGraph<N, DirectedTag>::edges_size_type
2900 num_edges(vigra::GridGraph<N, DirectedTag> const & g)
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>
2914 edge(typename vigra::GridGraph<N, DirectedTag>::vertex_descriptor const & u,
2915 typename vigra::GridGraph<N, DirectedTag>::vertex_descriptor const & v,
2916 vigra::GridGraph<N, DirectedTag> const & g)
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
2928 void put(vigra::MultiArrayView<N, T, Stride> & pmap,
2929 typename vigra::MultiArrayView<N, T, Stride>::difference_type const & k,
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>
2997 typename vigra::GridGraph<N>::vertices_size_type
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,
3064 typename vigra::GridGraph<N, DirectedTag>::vertex_iterator const & arg)
3065 {
3066 out << "v" << arg.scanOrderIndex();
3067 return out;
3068 }
3069
3070 template<unsigned int N, class DirectedTag>
3071 ostream& operator<<(ostream& out,
3072 typename vigra::GridGraph<N, DirectedTag>::adjacency_iterator const & arg)
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)