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 DepthFirstVisitor.ih
19 * @author Jacques-Olivier Lachaud (\c jacques-olivier.lachaud@univ-savoie.fr )
20 * Laboratory of Mathematics (CNRS, UMR 5807), University of Savoie, France
21 * @author David Coeurjolly (\c david.coeurjolly@liris.cnrs.fr )
22 * Laboratoire d'InfoRmatique en Image et Systèmes d'information - LIRIS (CNRS, UMR 5205), CNRS, France
26 * Implementation of inline methods defined in DepthFirstVisitor.h
28 * This file is part of the DGtal library.
32 //////////////////////////////////////////////////////////////////////////////
34 //////////////////////////////////////////////////////////////////////////////
36 ///////////////////////////////////////////////////////////////////////////////
37 // IMPLEMENTATION of inline methods.
38 ///////////////////////////////////////////////////////////////////////////////
40 ///////////////////////////////////////////////////////////////////////////////
41 // ----------------------- Standard services ------------------------------
43 //-----------------------------------------------------------------------------
44 template < typename TGraph, typename TMarkSet >
46 DGtal::DepthFirstVisitor<TGraph,TMarkSet>::~DepthFirstVisitor()
49 //-----------------------------------------------------------------------------
50 template < typename TGraph, typename TMarkSet >
52 DGtal::DepthFirstVisitor<TGraph,TMarkSet>
53 ::DepthFirstVisitor( const DepthFirstVisitor & other )
54 : myGraph( other.myGraph ),
55 myMarkedVertices( other.myMarkedVertices ),
56 myQueue( other.myQueue )
59 //-----------------------------------------------------------------------------
60 template < typename TGraph, typename TMarkSet >
62 DGtal::DepthFirstVisitor<TGraph,TMarkSet>
63 ::DepthFirstVisitor( ConstAlias<Graph> g )
67 //-----------------------------------------------------------------------------
68 template < typename TGraph, typename TMarkSet >
70 DGtal::DepthFirstVisitor<TGraph,TMarkSet>
71 ::DepthFirstVisitor( ConstAlias<Graph> g, const Vertex & p )
74 myMarkedVertices.insert( p );
75 myQueue.push( std::make_pair( p, 0 ) );
77 //-----------------------------------------------------------------------------
78 template < typename TGraph, typename TMarkSet >
79 template <typename VertexIterator>
81 DGtal::DepthFirstVisitor<TGraph,TMarkSet>
82 ::DepthFirstVisitor( ConstAlias<Graph> g,
83 VertexIterator b, VertexIterator e )
88 myMarkedVertices.insert( *b );
89 myQueue.push( std::make_pair( *b, 0 ) );
92 //-----------------------------------------------------------------------------
93 template < typename TGraph, typename TMarkSet >
95 const typename DGtal::DepthFirstVisitor<TGraph,TMarkSet>::Graph &
96 DGtal::DepthFirstVisitor<TGraph,TMarkSet>::graph() const
100 //-----------------------------------------------------------------------------
101 template < typename TGraph, typename TMarkSet >
104 DGtal::DepthFirstVisitor<TGraph,TMarkSet>::finished() const
106 return myQueue.empty();
108 //-----------------------------------------------------------------------------
109 template < typename TGraph, typename TMarkSet >
111 const typename DGtal::DepthFirstVisitor<TGraph,TMarkSet>::Node &
112 DGtal::DepthFirstVisitor<TGraph,TMarkSet>::current() const
114 ASSERT( ! finished() );
115 return myQueue.top();
117 //-----------------------------------------------------------------------------
118 template < typename TGraph, typename TMarkSet >
121 DGtal::DepthFirstVisitor<TGraph,TMarkSet>::ignore()
123 ASSERT( ! finished() );
126 //-----------------------------------------------------------------------------
127 template < typename TGraph, typename TMarkSet >
130 DGtal::DepthFirstVisitor<TGraph,TMarkSet>::expand()
132 ASSERT( ! finished() );
133 Node node = myQueue.top();
134 Data d = node.second + 1;
137 tmp.reserve( myGraph.bestCapacity() );
138 std::back_insert_iterator<VertexList> write_it = std::back_inserter( tmp );
139 myGraph.writeNeighbors( write_it, node.first );
140 for ( typename VertexList::const_iterator it = tmp.begin(),
141 it_end = tmp.end(); it != it_end; ++it )
143 typename MarkSet::const_iterator mark_it = myMarkedVertices.find( *it );
144 if ( mark_it == myMarkedVertices.end() )
146 myMarkedVertices.insert( *it );
147 myQueue.push( std::make_pair( *it, d ) );
151 //-----------------------------------------------------------------------------
152 template < typename TGraph, typename TMarkSet >
153 template <typename VertexPredicate>
156 DGtal::DepthFirstVisitor<TGraph,TMarkSet>::expand
157 ( const VertexPredicate & authorized_vtx )
159 ASSERT( ! finished() );
160 Node node = myQueue.top();
161 Data d = node.second + 1;
164 tmp.reserve( myGraph.bestCapacity() );
165 std::back_insert_iterator<VertexList> write_it = std::back_inserter( tmp );
166 myGraph.writeNeighbors( write_it,
169 for ( typename VertexList::const_iterator it = tmp.begin(),
170 it_end = tmp.end(); it != it_end; ++it )
172 typename MarkSet::const_iterator mark_it = myMarkedVertices.find( *it );
173 if ( mark_it == myMarkedVertices.end() )
175 myMarkedVertices.insert( *it );
176 myQueue.push( std::make_pair( *it, d ) );
180 //-----------------------------------------------------------------------------
181 template < typename TGraph, typename TMarkSet >
184 DGtal::DepthFirstVisitor<TGraph,TMarkSet>::terminate()
186 while ( ! finished() )
188 Node node = myQueue.top();
190 typename MarkSet::iterator mark_it = myMarkedVertices.find( node.first );
191 ASSERT( mark_it != myMarkedVertices.end() );
192 myMarkedVertices.erase( mark_it );
195 //-----------------------------------------------------------------------------
196 template < typename TGraph, typename TMarkSet >
198 const typename DGtal::DepthFirstVisitor<TGraph,TMarkSet>::MarkSet &
199 DGtal::DepthFirstVisitor<TGraph,TMarkSet>::markedVertices() const
201 return myMarkedVertices;
203 //-----------------------------------------------------------------------------
204 template < typename TGraph, typename TMarkSet >
206 typename DGtal::DepthFirstVisitor<TGraph,TMarkSet>::MarkSet
207 DGtal::DepthFirstVisitor<TGraph,TMarkSet>::visitedVertices() const
209 if ( finished() ) return myMarkedVertices;
210 MarkSet visitedVtx = myMarkedVertices;
211 NodeQueue copyQ( myQueue );
212 while ( ! copyQ.empty() )
214 Node node = copyQ.top();
216 typename MarkSet::iterator mark_it = visitedVtx.find( node.first );
217 ASSERT( mark_it != visitedVtx.end() );
218 visitedVtx.erase( mark_it );
223 ///////////////////////////////////////////////////////////////////////////////
224 // Interface - public :
227 * Writes/Displays the object on an output stream.
228 * @param out the output stream where the object is written.
230 template < typename TGraph, typename TMarkSet >
233 DGtal::DepthFirstVisitor<TGraph,TMarkSet>::selfDisplay ( std::ostream & out ) const
235 out << "[DepthFirstVisitor"
236 << " #queue=" << myQueue.size()
241 * Checks the validity/consistency of the object.
242 * @return 'true' if the object is valid, 'false' otherwise.
244 template < typename TGraph, typename TMarkSet >
247 DGtal::DepthFirstVisitor<TGraph,TMarkSet>::isValid() const
254 ///////////////////////////////////////////////////////////////////////////////
255 // Implementation of inline functions //
257 template < typename TGraph, typename TMarkSet >
260 DGtal::operator<< ( std::ostream & out,
261 const DepthFirstVisitor<TGraph,TMarkSet> & object )
263 object.selfDisplay( out );
268 ///////////////////////////////////////////////////////////////////////////////