X-Git-Url: https://git.creatis.insa-lyon.fr/pubgit/?a=blobdiff_plain;f=lib%2FcpExtensions%2FDataStructures%2FGraph.hxx;h=62c6b75c60012c7f9584e470f300451f01880822;hb=510ac31d52c1ac725baf278243c958e6c564b5b3;hp=c567f39dafe16c315623f3d20f20f423df68f1fc;hpb=ef8b6e12859181d3faa8019ce7319c539c0f86ec;p=cpPlugins.git diff --git a/lib/cpExtensions/DataStructures/Graph.hxx b/lib/cpExtensions/DataStructures/Graph.hxx index c567f39..62c6b75 100644 --- a/lib/cpExtensions/DataStructures/Graph.hxx +++ b/lib/cpExtensions/DataStructures/Graph.hxx @@ -1,133 +1,241 @@ -#ifndef __CPEXTENSIONS__DATASTRUCTURES__GRAPH__HXX__ -#define __CPEXTENSIONS__DATASTRUCTURES__GRAPH__HXX__ +#ifndef __cpExtensions__DataStructures__Graph__hxx__ +#define __cpExtensions__DataStructures__Graph__hxx__ // ------------------------------------------------------------------------- -template< class V, class C, class I > -typename cpExtensions::DataStructures::Graph< V, C, I >:: -TVertices::iterator cpExtensions::DataStructures::Graph< V, C, I >:: -BeginVertices( ) +template< class _TVertex, class _TCost, class _TIndex, class _TIndexCompare > +void cpExtensions::DataStructures::Graph< _TVertex, _TCost, _TIndex, _TIndexCompare >:: +Clear( ) { - return( this->m_Vertices.begin( ) ); + this->m_Vertices.clear( ); + this->m_Matrix.clear( ); } // ------------------------------------------------------------------------- -template< class V, class C, class I > -typename cpExtensions::DataStructures::Graph< V, C, I >:: -TVertices::iterator cpExtensions::DataStructures::Graph< V, C, I >:: -EndVertices( ) +template< class _TVertex, class _TCost, class _TIndex, class _TIndexCompare > +bool cpExtensions::DataStructures::Graph< _TVertex, _TCost, _TIndex, _TIndexCompare >:: +RenameVertex( const TIndex& old_index, const TIndex& new_index ) { - return( this->m_Vertices.end( ) ); -} + auto old_v = this->m_Vertices.find( old_index ); + auto new_v = this->m_Vertices.find( new_index ); + if( old_v != this->m_Vertices.end( ) && new_v == this->m_Vertices.end( ) ) + { + // Replace vertex + this->m_Vertices[ new_index ] = old_v->second; + this->m_Vertices.erase( old_index ); -// ------------------------------------------------------------------------- -template< class V, class C, class I > -typename cpExtensions::DataStructures::Graph< V, C, I >:: -TVertices::const_iterator cpExtensions::DataStructures::Graph< V, C, I >:: -BeginVertices( ) const -{ - return( this->m_Vertices.begin( ) ); -} + // Duplicate edges + auto mIt = this->m_Matrix.begin( ); + auto found_row = this->m_Matrix.end( ); + for( ; mIt != this->m_Matrix.end( ); ++mIt ) + { + if( mIt->first == old_index ) + found_row = mIt; -// ------------------------------------------------------------------------- -template< class V, class C, class I > -typename cpExtensions::DataStructures::Graph< V, C, I >:: -TVertices::const_iterator cpExtensions::DataStructures::Graph< V, C, I >:: -EndVertices( ) const -{ - return( this->m_Vertices.end( ) ); -} + auto rIt = mIt->second.begin( ); + for( ; rIt != mIt->second.end( ); ++rIt ) + { + if( mIt->first == old_index ) + this->m_Matrix[ new_index ][ rIt->first ] = rIt->second; + else if( rIt->first == old_index ) + this->m_Matrix[ mIt->first ][ new_index ] = rIt->second; -// ------------------------------------------------------------------------- -template< class V, class C, class I > -typename cpExtensions::DataStructures::Graph< V, C, I >:: -TMatrix::iterator cpExtensions::DataStructures::Graph< V, C, I >:: -BeginEdgesRows( ) -{ - return( this->m_Matrix.begin( ) ); -} + } // rof -// ------------------------------------------------------------------------- -template< class V, class C, class I > -typename cpExtensions::DataStructures::Graph< V, C, I >:: -TMatrix::iterator cpExtensions::DataStructures::Graph< V, C, I >:: -EndEdgetsRows( ) -{ - return( this->m_Matrix.end( ) ); -} + } // rof -// ------------------------------------------------------------------------- -template< class V, class C, class I > -typename cpExtensions::DataStructures::Graph< V, C, I >:: -TMatrix::const_iterator cpExtensions::DataStructures::Graph< V, C, I >:: -BeginEdgesRows( ) const -{ - return( this->m_Matrix.begin( ) ); -} + // Delete old edges + if( found_row != this->m_Matrix.end( ) ) + this->m_Matrix.erase( found_row ); -// ------------------------------------------------------------------------- -template< class V, class C, class I > -typename cpExtensions::DataStructures::Graph< V, C, I >:: -TMatrix::const_iterator cpExtensions::DataStructures::Graph< V, C, I >:: -EndEdgesRows( ) const -{ - return( this->m_Matrix.end( ) ); + mIt = this->m_Matrix.begin( ); + for( ; mIt != this->m_Matrix.end( ); ++mIt ) + { + auto rIt = mIt->second.begin( ); + while( rIt != mIt->second.end( ) ) + { + if( rIt->first == old_index ) + { + mIt->second.erase( rIt ); + rIt = mIt->second.begin( ); + } + else + ++rIt; + + } // elihw + + } // rof + return( true ); + } + else + return( false ); } // ------------------------------------------------------------------------- -template< class V, class C, class I > -void cpExtensions::DataStructures::Graph< V, C, I >:: -Clear( ) +template< class _TVertex, class _TCost, class _TIndex, class _TIndexCompare > +void cpExtensions::DataStructures::Graph< _TVertex, _TCost, _TIndex, _TIndexCompare >:: +RemoveVertex( const TIndex& index ) { - this->m_Vertices.clear( ); - this->m_Matrix.clear( ); + auto i = this->m_Vertices.find( index ); + if( i != this->m_Vertices.end( ) ) + { + // Delete vertex + this->m_Vertices.erase( i ); + + // Delete edges starting from given vertex + auto mIt = this->m_Matrix.find( index ); + if( mIt != this->m_Matrix.end( ) ) + this->m_Matrix.erase( mIt ); + + // Delete edges arriving to given vertex + mIt = this->m_Matrix.begin( ); + for( ; mIt != this->m_Matrix.end( ); ++mIt ) + { + auto rIt = mIt->second.begin( ); + while( rIt != mIt->second.end( ) ) + { + if( rIt->first == index ) + { + mIt->second.erase( rIt ); + rIt = mIt->second.begin( ); + } + else + ++rIt; + + } // elihw + + } // rof + + } // fi } // ------------------------------------------------------------------------- -template< class V, class C, class I > -bool cpExtensions::DataStructures::Graph< V, C, I >:: -HasVertexIndex( const I& index ) const +template< class _TVertex, class _TCost, class _TIndex, class _TIndexCompare > +typename +cpExtensions::DataStructures::Graph< _TVertex, _TCost, _TIndex, _TIndexCompare >:: +TEdges& +cpExtensions::DataStructures::Graph< _TVertex, _TCost, _TIndex, _TIndexCompare >:: +GetEdges( const TIndex& orig, const TIndex& dest ) { - return( this->m_Vertices.find( index ) != this->m_Vertices.end( ) ); + static TEdges null_edges; + auto o = this->m_Matrix.find( orig ); + if( o != this->m_Matrix.find( orig ) ) + { + auto d = o->second.find( dest ); + if( d == o->second.end( ) ) + { + null_edges.clear( ); + return( null_edges ); + } + else + return( d->second ); + } + else + { + null_edges.clear( ); + return( null_edges ); + + } // fi } // ------------------------------------------------------------------------- -template< class V, class C, class I > -void cpExtensions::DataStructures::Graph< V, C, I >:: -InsertVertex( const I& index, V& vertex ) +template< class _TVertex, class _TCost, class _TIndex, class _TIndexCompare > +const typename +cpExtensions::DataStructures::Graph< _TVertex, _TCost, _TIndex, _TIndexCompare >:: +TEdges& +cpExtensions::DataStructures::Graph< _TVertex, _TCost, _TIndex, _TIndexCompare >:: +GetEdges( const TIndex& orig, const TIndex& dest ) const { - this->m_Vertices[ index ] = vertex; + static const TEdges null_edges; + auto o = this->m_Matrix.find( orig ); + if( o != this->m_Matrix.find( orig ) ) + { + auto d = o->second.find( dest ); + if( d == o->second.end( ) ) + return( null_edges ); + else + return( d->second ); + } + else + return( null_edges ); } // ------------------------------------------------------------------------- -template< class V, class C, class I > -V& cpExtensions::DataStructures::Graph< V, C, I >:: -GetVertex( const I& index ) +template< class _TVertex, class _TCost, class _TIndex, class _TIndexCompare > +bool cpExtensions::DataStructures::Graph< _TVertex, _TCost, _TIndex, _TIndexCompare >:: +HasEdge( const TIndex& orig, const TIndex& dest ) const { - return( this->m_Vertices[ index ] ); + auto mIt = this->m_Matrix.find( orig ); + if( mIt != this->m_Matrix.end( ) ) + return( mIt->second.find( dest ) != mIt->second.end( ) ); + else + return( false ); } // ------------------------------------------------------------------------- -template< class V, class C, class I > -const V& cpExtensions::DataStructures::Graph< V, C, I >:: -GetVertex( const I& index ) const +template< class _TVertex, class _TCost, class _TIndex, class _TIndexCompare > +void cpExtensions::DataStructures::Graph< _TVertex, _TCost, _TIndex, _TIndexCompare >:: +RemoveEdge( const TIndex& orig, const TIndex& dest, const TCost& cost ) { - return( this->m_Vertices[ index ] ); + auto m = this->m_Matrix.find( orig ); + if( m != this->m_Matrix.end( ) ) + { + auto r = m->second.find( dest ); + if( r != m->second.end( ) ) + { + auto e = r->second.end( ); + for( + auto i = r->second.begin( ); + i != r->second.end( ) && e == r->second.end( ); + ++i + ) + if( *i == cost ) + e = i; + if( e != r->second.end( ) ) + { + r->second.erase( e ); + if( r->second.size( ) == 0 ) + { + m->second.erase( r ); + if( m->second.size( ) == 0 ) + this->m_Matrix.erase( m ); + + } // fi + + } // fi + + } // fi + + } // fi } // ------------------------------------------------------------------------- -template< class V, class C, class I > -void cpExtensions::DataStructures::Graph< V, C, I >:: -AddConnection( const I& orig, const I& dest, const C& cost ) +template< class _TVertex, class _TCost, class _TIndex, class _TIndexCompare > +void cpExtensions::DataStructures::Graph< _TVertex, _TCost, _TIndex, _TIndexCompare >:: +RemoveEdges( const TIndex& orig, const TIndex& dest ) { - this->m_Matrix[ orig ][ dest ].push_back( cost ); + auto m = this->m_Matrix.find( orig ); + if( m != this->m_Matrix.end( ) ) + { + auto r = m->second.find( dest ); + if( r != m->second.end( ) ) + { + m->second.erase( r ); + if( m->second.size( ) == 0 ) + this->m_Matrix.erase( m ); + + } // fi + + } // fi + } // ------------------------------------------------------------------------- -template< class V, class C, class I > -std::set< I > cpExtensions::DataStructures::Graph< V, C, I >:: +template< class _TVertex, class _TCost, class _TIndex, class _TIndexCompare > +std::set< _TIndex, _TIndexCompare > +cpExtensions::DataStructures::Graph< _TVertex, _TCost, _TIndex, _TIndexCompare >:: GetSinks( ) const { - std::set< I > sinks; + std::set< _TIndex, _TIndexCompare > sinks; auto vIt = this->m_Vertices.begin( ); for( ; vIt != this->m_Vertices.end( ); ++vIt ) @@ -140,20 +248,20 @@ GetSinks( ) const } // ------------------------------------------------------------------------- -template< class V, class C, class I > -cpExtensions::DataStructures::Graph< V, C, I >:: +template< class _TVertex, class _TCost, class _TIndex, class _TIndexCompare > +cpExtensions::DataStructures::Graph< _TVertex, _TCost, _TIndex, _TIndexCompare >:: Graph( ) : Superclass( ) { } // ------------------------------------------------------------------------- -template< class V, class C, class I > -cpExtensions::DataStructures::Graph< V, C, I >:: +template< class _TVertex, class _TCost, class _TIndex, class _TIndexCompare > +cpExtensions::DataStructures::Graph< _TVertex, _TCost, _TIndex, _TIndexCompare >:: ~Graph( ) { } -#endif // __CPEXTENSIONS__DATASTRUCTURES__GRAPH__HXX__ +#endif // __cpExtensions__DataStructures__Graph__hxx__ // eof - $RCSfile$