1 #ifndef __FPA__BASE__MINIMUMSPANNINGTREE__HXX__
2 #define __FPA__BASE__MINIMUMSPANNINGTREE__HXX__
6 // -------------------------------------------------------------------------
7 template< class V, class C, class B >
8 const unsigned long fpa::Base::MinimumSpanningTree< V, C, B >::INF_VALUE =
9 std::numeric_limits< unsigned long >::max( ) >> 1;
11 // -------------------------------------------------------------------------
12 template< class V, class C, class B >
13 void fpa::Base::MinimumSpanningTree< V, C, B >::
14 SetCollisions( const TCollisions& collisions )
16 this->m_Collisions = collisions;
18 // Prepare fronts graph using Floyd-Warshall
19 unsigned long nSeeds = this->m_Collisions.size( );
20 _TMatrix dist( nSeeds, _TRow( nSeeds, Self::INF_VALUE ) );
21 this->m_FrontPaths = dist;
23 for( unsigned long i = 0; i < nSeeds; ++i )
25 for( unsigned long j = 0; j < nSeeds; ++j )
27 if( this->m_Collisions[ i ][ j ].second )
31 this->m_FrontPaths[ i ][ j ] = j;
32 this->m_FrontPaths[ j ][ i ] = i;
38 this->m_FrontPaths[ i ][ i ] = i;
41 for( unsigned long k = 0; k < nSeeds; ++k )
43 for( unsigned long i = 0; i < nSeeds; ++i )
45 for( unsigned long j = 0; j < nSeeds; ++j )
47 if( ( dist[ i ][ k ] + dist[ k ][ j ] ) < dist[ i ][ j ] )
49 dist[ i ][ j ] = dist[ i ][ k ] + dist[ k ][ j ];
50 this->m_FrontPaths[ i ][ j ] = this->m_FrontPaths[ i ][ k ];
63 // -------------------------------------------------------------------------
64 template< class V, class C, class B >
65 void fpa::Base::MinimumSpanningTree< V, C, B >::
66 GetPath( std::vector< V >& path, const V& a, const V& b ) const
68 long fa = this->_FrontId( a );
69 long fb = this->_FrontId( b );
73 std::vector< V > ap, bp;
78 typename std::vector< V >::const_reverse_iterator raIt, rbIt;
81 while( *raIt == *rbIt && raIt != ap.rend( ) && rbIt != bp.rend( ) )
87 if( raIt != ap.rbegin( ) ) --raIt;
88 if( rbIt != bp.rbegin( ) ) --rbIt;
91 typename std::vector< V >::const_iterator iaIt = ap.begin( );
92 for( ; iaIt != ap.end( ) && *iaIt != *raIt; ++iaIt )
93 path.push_back( *iaIt );
96 for( ; rbIt != bp.rend( ); ++rbIt )
97 path.push_back( *rbIt );
101 // Use this->m_FrontPaths from Floyd-Warshall
102 if( this->m_FrontPaths[ fa ][ fb ] != Self::INF_VALUE )
104 // Compute front path
105 std::vector< long > fpath;
106 fpath.push_back( fa );
109 fa = this->m_FrontPaths[ fa ][ fb ];
110 fpath.push_back( fa );
114 // Continue only if both fronts are connected
115 unsigned int N = fpath.size( );
118 // First path: from start vertex to first collision
120 path, a, this->m_Collisions[ fpath[ 0 ] ][ fpath[ 1 ] ].first
123 // Intermediary paths
124 for( unsigned int i = 1; i < N - 1; ++i )
128 this->m_Collisions[ fpath[ i ] ][ fpath[ i - 1 ] ].first,
129 this->m_Collisions[ fpath[ i ] ][ fpath[ i + 1 ] ].first
134 // Final path: from last collision to end point
137 this->m_Collisions[ fpath[ N - 1 ] ][ fpath[ N - 2 ] ].first, b
147 // -------------------------------------------------------------------------
148 template< class V, class C, class B >
149 fpa::Base::MinimumSpanningTree< V, C, B >::
150 MinimumSpanningTree( )
155 // -------------------------------------------------------------------------
156 template< class V, class C, class B >
157 fpa::Base::MinimumSpanningTree< V, C, B >::
158 ~MinimumSpanningTree( )
162 // -------------------------------------------------------------------------
163 template< class V, class C, class B >
164 void fpa::Base::MinimumSpanningTree< V, C, B >::
165 _Path( std::vector< V >& path, const V& a ) const
170 path.push_back( it );
171 it = this->_Parent( it );
173 } while( it != this->_Parent( it ) );
174 path.push_back( it );
177 #endif // __FPA__BASE__MINIMUMSPANNINGTREE__HXX__