1 #ifndef __FPA__BASE__ALGORITHM__HXX__
2 #define __FPA__BASE__ALGORITHM__HXX__
5 #include <itkProcessObject.h>
7 // -------------------------------------------------------------------------
8 template< class V, class C, class R, class S, class VC, class B >
9 fpa::Base::Algorithm< V, C, R, S, VC, B >::_TNode::
11 : Result( TResult( 0 ) ),
13 Label( Self::FarLabel )
17 // -------------------------------------------------------------------------
18 template< class V, class C, class R, class S, class VC, class B >
19 fpa::Base::Algorithm< V, C, R, S, VC, B >::_TNode::
24 // -------------------------------------------------------------------------
25 template< class V, class C, class R, class S, class VC, class B >
26 typename fpa::Base::Algorithm< V, C, R, S, VC, B >::
27 TMinimumSpanningTree* fpa::Base::Algorithm< V, C, R, S, VC, B >::
28 GetMinimumSpanningTree( )
31 dynamic_cast< TMinimumSpanningTree* >(
32 this->itk::ProcessObject::GetOutput(
33 this->m_MinimumSpanningTreeIndex
39 // -------------------------------------------------------------------------
40 template< class V, class C, class R, class S, class VC, class B >
41 const typename fpa::Base::Algorithm< V, C, R, S, VC, B >::
42 TMinimumSpanningTree* fpa::Base::Algorithm< V, C, R, S, VC, B >::
43 GetMinimumSpanningTree( ) const
46 dynamic_cast< const TMinimumSpanningTree* >(
47 this->itk::ProcessObject::GetOutput(
48 this->m_MinimumSpanningTreeIndex
54 // -------------------------------------------------------------------------
55 template< class V, class C, class R, class S, class VC, class B >
56 void fpa::Base::Algorithm< V, C, R, S, VC, B >::
57 GraftMinimumSpanningTree( itk::DataObject* obj )
59 TMinimumSpanningTree* mst = dynamic_cast< TMinimumSpanningTree* >( obj );
61 this->GraftNthOutput( this->m_MinimumSpanningTreeIndex, mst );
64 // -------------------------------------------------------------------------
65 template< class V, class C, class R, class S, class VC, class B >
66 void fpa::Base::Algorithm< V, C, R, S, VC, B >::
67 InvokeEvent( const itk::EventObject& e )
69 if( this->m_ThrowEvents )
70 this->Superclass::InvokeEvent( e );
73 // -------------------------------------------------------------------------
74 template< class V, class C, class R, class S, class VC, class B >
75 void fpa::Base::Algorithm< V, C, R, S, VC, B >::
76 InvokeEvent( const itk::EventObject& e ) const
78 if( this->m_ThrowEvents )
79 this->Superclass::InvokeEvent( e );
82 // -------------------------------------------------------------------------
83 template< class V, class C, class R, class S, class VC, class B >
84 void fpa::Base::Algorithm< V, C, R, S, VC, B >::
85 AddSeed( const TVertex& s, const TResult& r )
90 ns.FrontId = this->m_SeedVertices.size( );
91 ns.Label = Self::FrontLabel;
92 this->m_Seeds[ s ] = ns;
93 this->m_SeedVertices.push_back( s );
97 // -------------------------------------------------------------------------
98 template< class V, class C, class R, class S, class VC, class B >
99 const typename fpa::Base::Algorithm< V, C, R, S, VC, B >::
100 TVertex& fpa::Base::Algorithm< V, C, R, S, VC, B >::
101 GetSeed( const unsigned int& id ) const
103 return( this->m_SeedVertices[ id ] );
106 // -------------------------------------------------------------------------
107 template< class V, class C, class R, class S, class VC, class B >
108 void fpa::Base::Algorithm< V, C, R, S, VC, B >::
111 this->m_Seeds.clear( );
112 this->m_SeedVertices.clear( );
116 // -------------------------------------------------------------------------
117 template< class V, class C, class R, class S, class VC, class B >
118 unsigned long fpa::Base::Algorithm< V, C, R, S, VC, B >::
119 GetNumberOfSeeds( ) const
121 return( this->m_Seeds.size( ) );
124 // -------------------------------------------------------------------------
125 template< class V, class C, class R, class S, class VC, class B >
126 fpa::Base::Algorithm< V, C, R, S, VC, B >::
129 m_ThrowEvents( false ),
130 m_StopAtOneFront( false )
132 this->m_MinimumSpanningTreeIndex = this->GetNumberOfRequiredOutputs( );
133 this->SetNumberOfRequiredOutputs( this->m_MinimumSpanningTreeIndex + 1 );
134 this->itk::ProcessObject::SetNthOutput(
135 this->m_MinimumSpanningTreeIndex, TMinimumSpanningTree::New( )
139 // -------------------------------------------------------------------------
140 template< class V, class C, class R, class S, class VC, class B >
141 fpa::Base::Algorithm< V, C, R, S, VC, B >::
146 // -------------------------------------------------------------------------
147 template< class V, class C, class R, class S, class VC, class B >
148 void fpa::Base::Algorithm< V, C, R, S, VC, B >::
151 unsigned long N = this->m_Seeds.size( );
155 this->InvokeEvent( TStartEvent( ) );
156 this->_BeforeGenerateData( );
158 this->m_Collisions.clear( );
160 resize( N, _TCollisionsRow( N, _TCollision( TVertex( ), false ) ) );
161 this->_InitResults( );
165 this->_AfterGenerateData( );
166 this->InvokeEvent( TEndEvent( ) );
169 // -------------------------------------------------------------------------
170 template< class V, class C, class R, class S, class VC, class B >
171 void fpa::Base::Algorithm< V, C, R, S, VC, B >::
174 this->InvokeEvent( TStartLoopEvent( ) );
175 this->_BeforeLoop( );
176 while( !( this->_IsQueueEmpty( ) ) )
178 // Get next candidate
181 this->_QueuePop( vertex, node );
182 if( this->_Node( vertex ).Label == Self::AliveLabel )
185 // Mark it as "Alive" and update final result
186 node.Label = Self::AliveLabel;
187 this->_Mark( vertex, node );
188 this->_SetResult( vertex, node );
189 this->InvokeEvent( TAliveEvent( vertex, node.FrontId ) );
191 // Check if a forced stop condition arises
192 if( !( this->_NeedToStop( ) ) )
194 // Compute neighborhood
195 _TVertices neighborhood;
196 this->_Neighborhood( neighborhood, vertex );
198 // Iterate over neighbors
199 typename _TVertices::iterator nIt = neighborhood.begin( );
200 while( nIt != neighborhood.end( ) )
202 _TNode neighbor = this->_Node( *nIt );
203 if( neighbor.Label == Self::AliveLabel )
206 if( this->_UpdateCollisions( vertex, *nIt ) )
208 this->_QueueClear( );
209 nIt = neighborhood.end( );
216 // Add new candidate to queue
217 if( this->_ComputeNeighborResult( neighbor.Result, *nIt, vertex ) )
219 neighbor.FrontId = node.FrontId;
220 neighbor.Parent = vertex;
221 neighbor.Label = Self::FrontLabel;
222 this->_QueuePush( *nIt, neighbor );
223 this->_Mark( *nIt, neighbor );
224 this->InvokeEvent( TFrontEvent( *nIt, node.FrontId ) );
227 this->InvokeEvent( TFreezeEvent( *nIt, node.FrontId ) );
235 this->_QueueClear( );
239 this->InvokeEvent( TEndLoopEvent( ) );
242 // -------------------------------------------------------------------------
243 template< class V, class C, class R, class S, class VC, class B >
244 void fpa::Base::Algorithm< V, C, R, S, VC, B >::
245 _BeforeGenerateData( )
249 // -------------------------------------------------------------------------
250 template< class V, class C, class R, class S, class VC, class B >
251 void fpa::Base::Algorithm< V, C, R, S, VC, B >::
252 _AfterGenerateData( )
256 // -------------------------------------------------------------------------
257 template< class V, class C, class R, class S, class VC, class B >
258 void fpa::Base::Algorithm< V, C, R, S, VC, B >::
263 // -------------------------------------------------------------------------
264 template< class V, class C, class R, class S, class VC, class B >
265 void fpa::Base::Algorithm< V, C, R, S, VC, B >::
270 // -------------------------------------------------------------------------
271 template< class V, class C, class R, class S, class VC, class B >
272 bool fpa::Base::Algorithm< V, C, R, S, VC, B >::
273 _UpdateCollisions( const TVertex& a, const TVertex& b )
276 _TNode na = this->_Node( a );
277 _TNode nb = this->_Node( b );
278 long fa = na.FrontId;
279 long fb = nb.FrontId;
283 // Mark collision, if it is new
284 bool exists = this->m_Collisions[ fa ][ fb ].second;
285 exists &= this->m_Collisions[ fb ][ fa ].second;
289 this->m_Collisions[ fa ][ fb ].first = a;
290 this->m_Collisions[ fa ][ fb ].second = true;
291 this->m_Collisions[ fb ][ fa ].first = b;
292 this->m_Collisions[ fb ][ fa ].second = true;
294 // Stop if one front is desired
295 if( this->m_StopAtOneFront )
297 // Perform a depth-first iteration on front graph
298 unsigned long N = this->GetNumberOfSeeds( );
299 unsigned long count = 0;
300 std::vector< bool > m( N, false );
301 std::queue< unsigned long > q;
305 unsigned long f = q.front( );
313 for( unsigned int n = 0; n < N; ++n )
314 if( this->m_Collisions[ f ][ n ].second && !m[ n ] )
318 ret = ( count == N );
328 // -------------------------------------------------------------------------
329 template< class V, class C, class R, class S, class VC, class B >
330 bool fpa::Base::Algorithm< V, C, R, S, VC, B >::
336 // -------------------------------------------------------------------------
337 template< class V, class C, class R, class S, class VC, class B >
338 typename fpa::Base::Algorithm< V, C, R, S, VC, B >::
339 _TNode& fpa::Base::Algorithm< V, C, R, S, VC, B >::
340 _Node( const TVertex& v )
342 typename _TNodes::iterator vIt = this->m_Marks.find( v );
343 if( vIt == this->m_Marks.end( ) )
347 new_node.Result = TResult( 0 );
348 new_node.FrontId = -1;
349 new_node.Label = Self::FarLabel;
350 this->m_Marks[ v ] = new_node;
351 vIt = this->m_Marks.find( v );
354 return( vIt->second );
357 // -------------------------------------------------------------------------
358 template< class V, class C, class R, class S, class VC, class B >
359 const typename fpa::Base::Algorithm< V, C, R, S, VC, B >::
360 _TNode& fpa::Base::Algorithm< V, C, R, S, VC, B >::
361 _Node( const TVertex& v ) const
363 typename _TNodes::const_iterator vIt = this->m_Marks.find( v );
364 return( vIt->second );
367 // -------------------------------------------------------------------------
368 template< class V, class C, class R, class S, class VC, class B >
369 void fpa::Base::Algorithm< V, C, R, S, VC, B >::
372 this->m_Marks.clear( );
375 // -------------------------------------------------------------------------
376 template< class V, class C, class R, class S, class VC, class B >
377 void fpa::Base::Algorithm< V, C, R, S, VC, B >::
378 _Mark( const TVertex& v, const _TNode& node )
380 this->m_Marks[ v ] = node;
383 // -------------------------------------------------------------------------
384 template< class V, class C, class R, class S, class VC, class B >
385 void fpa::Base::Algorithm< V, C, R, S, VC, B >::
388 this->_QueueClear( );
390 typename _TNodes::const_iterator sIt = this->m_Seeds.begin( );
391 sIt != this->m_Seeds.end( );
395 this->_QueuePush( sIt->first, sIt->second );
396 this->_Mark( sIt->first, sIt->second );
401 #endif // __FPA__BASE__ALGORITHM__HXX__