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//-----------------------------------------------------------------------------
42template < typename TGraph, typename TVertexFunctor, typename TMarkSet >
44DGtal::DistanceBreadthFirstVisitor<TGraph,TVertexFunctor,TMarkSet>::
45~DistanceBreadthFirstVisitor()
48//-----------------------------------------------------------------------------
49template < typename TGraph, typename TVertexFunctor, typename TMarkSet >
51DGtal::DistanceBreadthFirstVisitor<TGraph,TVertexFunctor,TMarkSet>::
52DistanceBreadthFirstVisitor( const DistanceBreadthFirstVisitor & other )
53 : myGraph( other.myGraph ), myDistance( other.myDistance ),
54 myMarkedVertices( other.myMarkedVertices ), myQueue( other.myQueue )
57//-----------------------------------------------------------------------------
58template < typename TGraph, typename TVertexFunctor, typename TMarkSet >
60DGtal::DistanceBreadthFirstVisitor<TGraph,TVertexFunctor,TMarkSet>::
61DistanceBreadthFirstVisitor( ConstAlias<Graph> g,
62 const VertexFunctor & distance,
64 : myGraph( &g ), myDistance( distance )
66 myMarkedVertices.insert( p );
67 myQueue.push( Node( p, myDistance( p ) ) );
69//-----------------------------------------------------------------------------
70template < typename TGraph, typename TVertexFunctor, typename TMarkSet >
71template <typename VertexIterator>
73DGtal::DistanceBreadthFirstVisitor<TGraph,TVertexFunctor,TMarkSet>::
74DistanceBreadthFirstVisitor( 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//-----------------------------------------------------------------------------
86template < typename TGraph, typename TVertexFunctor, typename TMarkSet >
88const typename DGtal::DistanceBreadthFirstVisitor<TGraph,TVertexFunctor,TMarkSet>::Graph &
89DGtal::DistanceBreadthFirstVisitor<TGraph,TVertexFunctor,TMarkSet>::
94//-----------------------------------------------------------------------------
95template < typename TGraph, typename TVertexFunctor, typename TMarkSet >
98DGtal::DistanceBreadthFirstVisitor<TGraph,TVertexFunctor,TMarkSet>::
101 return myQueue.empty();
103//-----------------------------------------------------------------------------
104template < typename TGraph, typename TVertexFunctor, typename TMarkSet >
106const typename DGtal::DistanceBreadthFirstVisitor<TGraph,TVertexFunctor,TMarkSet>::Node &
107DGtal::DistanceBreadthFirstVisitor<TGraph,TVertexFunctor,TMarkSet>::
110 ASSERT( ! finished() );
111 return myQueue.top();
113//-----------------------------------------------------------------------------
114template < typename TGraph, typename TVertexFunctor, typename TMarkSet >
115template < typename TBackInsertionSequence >
118DGtal::DistanceBreadthFirstVisitor<TGraph,TVertexFunctor,TMarkSet>::
119getCurrentLayer( 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//-----------------------------------------------------------------------------
139template < typename TGraph, typename TVertexFunctor, typename TMarkSet >
142DGtal::DistanceBreadthFirstVisitor<TGraph,TVertexFunctor,TMarkSet>::
145 ASSERT( ! finished() );
148//-----------------------------------------------------------------------------
149template < typename TGraph, typename TVertexFunctor, typename TMarkSet >
152DGtal::DistanceBreadthFirstVisitor<TGraph,TVertexFunctor,TMarkSet>::
153pushAgain( const Node & node )
155 ASSERT( myMarkedVertices.find( node.first ) != myMarkedVertices.end() );
156 myQueue.push( node );
158//-----------------------------------------------------------------------------
159template < typename TGraph, typename TVertexFunctor, typename TMarkSet >
162DGtal::DistanceBreadthFirstVisitor<TGraph,TVertexFunctor,TMarkSet>::
165 ASSERT( ! finished() );
166 Node node = current();
171 while ( ! finished() && ( node.second == current().second ) );
173//-----------------------------------------------------------------------------
174template < typename TGraph, typename TVertexFunctor, typename TMarkSet >
177DGtal::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//-----------------------------------------------------------------------------
201template < typename TGraph, typename TVertexFunctor, typename TMarkSet >
204DGtal::DistanceBreadthFirstVisitor<TGraph,TVertexFunctor,TMarkSet>::
207 ASSERT( ! finished() );
208 Node node = current();
213 while ( ! finished() && ( node.second == current().second ) );
215//-----------------------------------------------------------------------------
216template < typename TGraph, typename TVertexFunctor, typename TMarkSet >
217template <typename VertexPredicate>
220DGtal::DistanceBreadthFirstVisitor<TGraph,TVertexFunctor,TMarkSet>::
221expand( 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//-----------------------------------------------------------------------------
244template < typename TGraph, typename TVertexFunctor, typename TMarkSet >
245template <typename VertexPredicate>
248DGtal::DistanceBreadthFirstVisitor<TGraph,TVertexFunctor,TMarkSet>::
249expandLayer( const VertexPredicate & authorized_vtx )
251 ASSERT( ! finished() );
252 Node node = current();
255 expand( authorized_vtx );
257 while ( ! finished() && ( node.second == current().second ) );
259//-----------------------------------------------------------------------------
260template < typename TGraph, typename TVertexFunctor, typename TMarkSet >
263DGtal::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//-----------------------------------------------------------------------------
276template < typename TGraph, typename TVertexFunctor, typename TMarkSet >
278const typename DGtal::DistanceBreadthFirstVisitor<TGraph,TVertexFunctor,TMarkSet>::MarkSet &
279DGtal::DistanceBreadthFirstVisitor<TGraph,TVertexFunctor,TMarkSet>::
280markedVertices() const
282 return myMarkedVertices;
284//-----------------------------------------------------------------------------
285template < typename TGraph, typename TVertexFunctor, typename TMarkSet >
287typename DGtal::DistanceBreadthFirstVisitor<TGraph,TVertexFunctor,TMarkSet>::MarkSet
288DGtal::DistanceBreadthFirstVisitor<TGraph,TVertexFunctor,TMarkSet>::
289visitedVertices() 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//-----------------------------------------------------------------------------
302template < typename TGraph, typename TVertexFunctor, typename TMarkSet >
305DGtal::DistanceBreadthFirstVisitor<TGraph,TVertexFunctor,TMarkSet>::
306swap( 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.
320template < typename TGraph, typename TVertexFunctor, typename TMarkSet >
323DGtal::DistanceBreadthFirstVisitor<TGraph,TVertexFunctor,TMarkSet>::
324selfDisplay ( 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.
335template < typename TGraph, typename TVertexFunctor, typename TMarkSet >
338DGtal::DistanceBreadthFirstVisitor<TGraph,TVertexFunctor,TMarkSet>::
346///////////////////////////////////////////////////////////////////////////////
347// Implementation of inline functions //
349template < typename TGraph, typename TVertexFunctor, typename TMarkSet >
352DGtal::operator<< ( std::ostream & out,
353 const DistanceBreadthFirstVisitor<TGraph,TVertexFunctor,TMarkSet> & object )
355 object.selfDisplay( out );
360///////////////////////////////////////////////////////////////////////////////