2 * This program is free software: you can redistribute it and/or modify
3 * it under the terms of the GNU Lesser General Public License as
4 * published by the Free Software Foundation, either version 3 of the
5 * License, or (at your option) any later version.
7 * This program is distributed in the hope that it will be useful,
8 * but WITHOUT ANY WARRANTY; without even the implied warranty of
9 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
10 * GNU General Public License for more details.
12 * You should have received a copy of the GNU General Public License
13 * along with this program. If not, see <http://www.gnu.org/licenses/>.
18 * @file DistanceBreadthFirstVisitor.ih
19 * @author Jacques-Olivier Lachaud (\c jacques-olivier.lachaud@univ-savoie.fr )
20 * Laboratory of Mathematics (CNRS, UMR 5807), University of Savoie, France
24 * Implementation of inline methods defined in DistanceBreadthFirstVisitor.h
26 * This file is part of the DGtal library.
30 //////////////////////////////////////////////////////////////////////////////
32 //////////////////////////////////////////////////////////////////////////////
34 ///////////////////////////////////////////////////////////////////////////////
35 // IMPLEMENTATION of inline methods.
36 ///////////////////////////////////////////////////////////////////////////////
38 ///////////////////////////////////////////////////////////////////////////////
39 // ----------------------- Standard services ------------------------------
41 //-----------------------------------------------------------------------------
42 template < typename TGraph, typename TVertexFunctor, typename TMarkSet >
44 DGtal::DistanceBreadthFirstVisitor<TGraph,TVertexFunctor,TMarkSet>::
45 ~DistanceBreadthFirstVisitor()
48 //-----------------------------------------------------------------------------
49 template < typename TGraph, typename TVertexFunctor, typename TMarkSet >
51 DGtal::DistanceBreadthFirstVisitor<TGraph,TVertexFunctor,TMarkSet>::
52 DistanceBreadthFirstVisitor( const DistanceBreadthFirstVisitor & other )
53 : myGraph( other.myGraph ), myDistance( other.myDistance ),
54 myMarkedVertices( other.myMarkedVertices ), myQueue( other.myQueue )
57 //-----------------------------------------------------------------------------
58 template < typename TGraph, typename TVertexFunctor, typename TMarkSet >
60 DGtal::DistanceBreadthFirstVisitor<TGraph,TVertexFunctor,TMarkSet>::
61 DistanceBreadthFirstVisitor( ConstAlias<Graph> g,
62 const VertexFunctor & distance,
64 : myGraph( &g ), myDistance( distance )
66 myMarkedVertices.insert( p );
67 myQueue.push( Node( p, myDistance( p ) ) );
69 //-----------------------------------------------------------------------------
70 template < typename TGraph, typename TVertexFunctor, typename TMarkSet >
71 template <typename VertexIterator>
73 DGtal::DistanceBreadthFirstVisitor<TGraph,TVertexFunctor,TMarkSet>::
74 DistanceBreadthFirstVisitor( const Graph & g,
75 const VertexFunctor & distance,
76 VertexIterator b, VertexIterator e )
77 : myGraph( &g ), myDistance( distance )
81 myMarkedVertices.insert( *b );
82 myQueue.push( Node( *b, myDistance( *b ) ) );
85 //-----------------------------------------------------------------------------
86 template < typename TGraph, typename TVertexFunctor, typename TMarkSet >
88 const typename DGtal::DistanceBreadthFirstVisitor<TGraph,TVertexFunctor,TMarkSet>::Graph &
89 DGtal::DistanceBreadthFirstVisitor<TGraph,TVertexFunctor,TMarkSet>::
94 //-----------------------------------------------------------------------------
95 template < typename TGraph, typename TVertexFunctor, typename TMarkSet >
98 DGtal::DistanceBreadthFirstVisitor<TGraph,TVertexFunctor,TMarkSet>::
101 return myQueue.empty();
103 //-----------------------------------------------------------------------------
104 template < typename TGraph, typename TVertexFunctor, typename TMarkSet >
106 const typename DGtal::DistanceBreadthFirstVisitor<TGraph,TVertexFunctor,TMarkSet>::Node &
107 DGtal::DistanceBreadthFirstVisitor<TGraph,TVertexFunctor,TMarkSet>::
110 ASSERT( ! finished() );
111 return myQueue.top();
113 //-----------------------------------------------------------------------------
114 template < typename TGraph, typename TVertexFunctor, typename TMarkSet >
115 template < typename TBackInsertionSequence >
118 DGtal::DistanceBreadthFirstVisitor<TGraph,TVertexFunctor,TMarkSet>::
119 getCurrentLayer( TBackInsertionSequence & layer )
121 BOOST_CONCEPT_ASSERT(( boost::BackInsertionSequence< TBackInsertionSequence > ));
122 ASSERT( ! finished() );
124 Node node = current();
127 layer.push_back( current() );
130 while ( ( ! finished() ) && ( node.second == current().second ) );
131 for ( typename TBackInsertionSequence::const_iterator it = layer.begin(),
138 //-----------------------------------------------------------------------------
139 template < typename TGraph, typename TVertexFunctor, typename TMarkSet >
142 DGtal::DistanceBreadthFirstVisitor<TGraph,TVertexFunctor,TMarkSet>::
145 ASSERT( ! finished() );
148 //-----------------------------------------------------------------------------
149 template < typename TGraph, typename TVertexFunctor, typename TMarkSet >
152 DGtal::DistanceBreadthFirstVisitor<TGraph,TVertexFunctor,TMarkSet>::
153 pushAgain( const Node & node )
155 ASSERT( myMarkedVertices.find( node.first ) != myMarkedVertices.end() );
156 myQueue.push( node );
158 //-----------------------------------------------------------------------------
159 template < typename TGraph, typename TVertexFunctor, typename TMarkSet >
162 DGtal::DistanceBreadthFirstVisitor<TGraph,TVertexFunctor,TMarkSet>::
165 ASSERT( ! finished() );
166 Node node = current();
171 while ( ! finished() && ( node.second == current().second ) );
173 //-----------------------------------------------------------------------------
174 template < typename TGraph, typename TVertexFunctor, typename TMarkSet >
177 DGtal::DistanceBreadthFirstVisitor<TGraph,TVertexFunctor,TMarkSet>::
180 ASSERT( ! finished() );
181 Node node = myQueue.top();
185 tmp.reserve( myGraph->bestCapacity() );
186 std::back_insert_iterator<VertexList> write_it = std::back_inserter( tmp );
187 myGraph->writeNeighbors( write_it, node.first );
188 for ( typename VertexList::const_iterator it = tmp.begin(),
189 it_end = tmp.end(); it != it_end; ++it )
192 typename MarkSet::const_iterator mark_it = myMarkedVertices.find( vtx );
193 if ( mark_it == myMarkedVertices.end() )
195 myMarkedVertices.insert( vtx );
196 myQueue.push( Node( vtx, myDistance( vtx ) ) );
200 //-----------------------------------------------------------------------------
201 template < typename TGraph, typename TVertexFunctor, typename TMarkSet >
204 DGtal::DistanceBreadthFirstVisitor<TGraph,TVertexFunctor,TMarkSet>::
207 ASSERT( ! finished() );
208 Node node = current();
213 while ( ! finished() && ( node.second == current().second ) );
215 //-----------------------------------------------------------------------------
216 template < typename TGraph, typename TVertexFunctor, typename TMarkSet >
217 template <typename VertexPredicate>
220 DGtal::DistanceBreadthFirstVisitor<TGraph,TVertexFunctor,TMarkSet>::
221 expand( const VertexPredicate & authorized_vtx )
223 ASSERT( ! finished() );
224 Node node = myQueue.top();
228 tmp.reserve( myGraph->bestCapacity() );
229 std::back_insert_iterator<VertexList> write_it = std::back_inserter( tmp );
230 myGraph->writeNeighbors( write_it, node.first, authorized_vtx );
231 for ( typename VertexList::const_iterator it = tmp.begin(),
232 it_end = tmp.end(); it != it_end; ++it )
235 typename MarkSet::const_iterator mark_it = myMarkedVertices.find( vtx );
236 if ( mark_it == myMarkedVertices.end() )
238 myMarkedVertices.insert( vtx );
239 myQueue.push( Node( vtx, myDistance( vtx ) ) );
243 //-----------------------------------------------------------------------------
244 template < typename TGraph, typename TVertexFunctor, typename TMarkSet >
245 template <typename VertexPredicate>
248 DGtal::DistanceBreadthFirstVisitor<TGraph,TVertexFunctor,TMarkSet>::
249 expandLayer( const VertexPredicate & authorized_vtx )
251 ASSERT( ! finished() );
252 Node node = current();
255 expand( authorized_vtx );
257 while ( ! finished() && ( node.second == current().second ) );
259 //-----------------------------------------------------------------------------
260 template < typename TGraph, typename TVertexFunctor, typename TMarkSet >
263 DGtal::DistanceBreadthFirstVisitor<TGraph,TVertexFunctor,TMarkSet>::
266 while ( ! finished() )
268 Node node = myQueue.top();
270 typename MarkSet::iterator mark_it = myMarkedVertices.find( node.first );
271 ASSERT( mark_it != myMarkedVertices.end() );
272 myMarkedVertices.erase( mark_it );
275 //-----------------------------------------------------------------------------
276 template < typename TGraph, typename TVertexFunctor, typename TMarkSet >
278 const typename DGtal::DistanceBreadthFirstVisitor<TGraph,TVertexFunctor,TMarkSet>::MarkSet &
279 DGtal::DistanceBreadthFirstVisitor<TGraph,TVertexFunctor,TMarkSet>::
280 markedVertices() const
282 return myMarkedVertices;
284 //-----------------------------------------------------------------------------
285 template < typename TGraph, typename TVertexFunctor, typename TMarkSet >
287 typename DGtal::DistanceBreadthFirstVisitor<TGraph,TVertexFunctor,TMarkSet>::MarkSet
288 DGtal::DistanceBreadthFirstVisitor<TGraph,TVertexFunctor,TMarkSet>::
289 visitedVertices() const
291 if ( finished() ) return myMarkedVertices;
292 MarkSet visitedVtx = myMarkedVertices;
293 NodeQueue q = myQueue; // duplicate queue
294 while ( ! q.empty() )
296 visitedVtx.erase( q.top().first );
301 //-----------------------------------------------------------------------------
302 template < typename TGraph, typename TVertexFunctor, typename TMarkSet >
305 DGtal::DistanceBreadthFirstVisitor<TGraph,TVertexFunctor,TMarkSet>::
306 swap( DistanceBreadthFirstVisitor & other )
308 std::swap( myGraph, other.myGraph );
309 std::swap( myDistance, other.myDistance );
310 myMarkedVertices.swap( other.myMarkedVertices );
311 myQueue.swap( other.myQueue );
313 ///////////////////////////////////////////////////////////////////////////////
314 // Interface - public :
317 * Writes/Displays the object on an output stream.
318 * @param out the output stream where the object is written.
320 template < typename TGraph, typename TVertexFunctor, typename TMarkSet >
323 DGtal::DistanceBreadthFirstVisitor<TGraph,TVertexFunctor,TMarkSet>::
324 selfDisplay ( std::ostream & out ) const
326 out << "[DistanceBreadthFirstVisitor"
327 << " #queue=" << myQueue.size()
332 * Checks the validity/consistency of the object.
333 * @return 'true' if the object is valid, 'false' otherwise.
335 template < typename TGraph, typename TVertexFunctor, typename TMarkSet >
338 DGtal::DistanceBreadthFirstVisitor<TGraph,TVertexFunctor,TMarkSet>::
346 ///////////////////////////////////////////////////////////////////////////////
347 // Implementation of inline functions //
349 template < typename TGraph, typename TVertexFunctor, typename TMarkSet >
352 DGtal::operator<< ( std::ostream & out,
353 const DistanceBreadthFirstVisitor<TGraph,TVertexFunctor,TMarkSet> & object )
355 object.selfDisplay( out );
360 ///////////////////////////////////////////////////////////////////////////////