]> Creatis software - cpPlugins.git/blobdiff - lib/cpExtensions/DataStructures/Graph.hxx
Skeleton representation added.
[cpPlugins.git] / lib / cpExtensions / DataStructures / Graph.hxx
index c9c67cf4d709a77be4cfb264d56acc356715003b..62c6b75c60012c7f9584e470f300451f01880822 100644 (file)
@@ -1,81 +1,9 @@
-#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( )
-{
-  return( this->m_Vertices.begin( ) );
-}
-
-// -------------------------------------------------------------------------
-template< class V, class C, class I >
-typename cpExtensions::DataStructures::Graph< V, C, I >::
-TVertices::iterator cpExtensions::DataStructures::Graph< V, C, I >::
-EndVertices( )
-{
-  return( this->m_Vertices.end( ) );
-}
-
-// -------------------------------------------------------------------------
-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( ) );
-}
-
-// -------------------------------------------------------------------------
-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( ) );
-}
-
-// -------------------------------------------------------------------------
-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( ) );
-}
-
-// -------------------------------------------------------------------------
-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( ) );
-}
-
-// -------------------------------------------------------------------------
-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( ) );
-}
-
-// -------------------------------------------------------------------------
-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( ) );
-}
-
-// -------------------------------------------------------------------------
-template< class V, class C, class I >
-void cpExtensions::DataStructures::Graph< V, C, I >::
+template< class _TVertex, class _TCost, class _TIndex, class _TIndexCompare >
+void cpExtensions::DataStructures::Graph< _TVertex, _TCost, _TIndex, _TIndexCompare >::
 Clear( )
 {
   this->m_Vertices.clear( );
@@ -83,33 +11,16 @@ Clear( )
 }
 
 // -------------------------------------------------------------------------
-template< class V, class C, class I >
-bool cpExtensions::DataStructures::Graph< V, C, I >::
-HasVertexIndex( const I& index ) const
-{
-  return( this->m_Vertices.find( index ) != this->m_Vertices.end( ) );
-}
-
-// -------------------------------------------------------------------------
-template< class V, class C, class I >
-void cpExtensions::DataStructures::Graph< V, C, I >::
-SetVertex( const I& index, V& vertex )
-{
-  this->m_Vertices[ index ] = vertex;
-}
-
-// -------------------------------------------------------------------------
-template< class V, class C, class I >
-bool cpExtensions::DataStructures::Graph< V, C, I >::
-RenameVertex( const I& old_index, const I& new_index )
+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 )
 {
   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
-    typename TVertices::value_type new_entry( new_index, old_v->second );
-    new_v = this->m_Vertices.insert( new_entry ).first;
+    this->m_Vertices[ new_index ] = old_v->second;
     this->m_Vertices.erase( old_index );
 
     // Duplicate edges
@@ -160,35 +71,171 @@ RenameVertex( const I& old_index, const I& new_index )
 }
 
 // -------------------------------------------------------------------------
-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 >
+void cpExtensions::DataStructures::Graph< _TVertex, _TCost, _TIndex, _TIndexCompare >::
+RemoveVertex( const TIndex& index )
+{
+  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 _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 )
+{
+  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 _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
+{
+  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 _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 )
@@ -201,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$