00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00014
00015
00016 #ifndef __defined_libdai_graph_h
00017 #define __defined_libdai_graph_h
00018
00019
00020 #include <ostream>
00021 #include <vector>
00022 #include <algorithm>
00023 #include <dai/util.h>
00024 #include <dai/exceptions.h>
00025 #include <dai/smallset.h>
00026
00027
00028 namespace dai {
00029
00030
00032
00042 class GraphAL {
00043 public:
00045
00096 struct Neighbor {
00098 size_t iter;
00100 size_t node;
00102 size_t dual;
00103
00105 Neighbor() {}
00107 Neighbor( size_t iter, size_t node, size_t dual ) : iter(iter), node(node), dual(dual) {}
00108
00110 operator size_t () const { return node; }
00111 };
00112
00114 typedef std::vector<Neighbor> Neighbors;
00115
00117 typedef std::pair<size_t,size_t> Edge;
00118
00119 private:
00121 std::vector<Neighbors> _nb;
00122
00123 public:
00125
00126
00127 GraphAL() : _nb() {}
00128
00130 GraphAL( size_t nr ) : _nb( nr ) {}
00131
00133
00139 template<typename EdgeInputIterator>
00140 GraphAL( size_t nr, EdgeInputIterator begin, EdgeInputIterator end, bool check=true ) : _nb() {
00141 construct( nr, begin, end, check );
00142 }
00144
00146
00147
00148 const Neighbor & nb( size_t n1, size_t _n2 ) const {
00149 DAI_DEBASSERT( n1 < _nb.size() );
00150 DAI_DEBASSERT( _n2 < _nb[n1].size() );
00151 return _nb[n1][_n2];
00152 }
00154 Neighbor & nb( size_t n1, size_t _n2 ) {
00155 DAI_DEBASSERT( n1 < _nb.size() );
00156 DAI_DEBASSERT( _n2 < _nb[n1].size() );
00157 return _nb[n1][_n2];
00158 }
00159
00161 const Neighbors & nb( size_t n ) const {
00162 DAI_DEBASSERT( n < _nb.size() );
00163 return _nb[n];
00164 }
00166 Neighbors & nb( size_t n ) {
00167 DAI_DEBASSERT( n < _nb.size() );
00168 return _nb[n];
00169 }
00171
00173
00174
00175
00181 template<typename EdgeInputIterator>
00182 void construct( size_t nr, EdgeInputIterator begin, EdgeInputIterator end, bool check=true );
00183
00185 size_t addNode() { _nb.push_back( Neighbors() ); return _nb.size() - 1; }
00186
00188
00194 template <typename NodeInputIterator>
00195 size_t addNode( NodeInputIterator begin, NodeInputIterator end, size_t sizeHint = 0 ) {
00196 Neighbors nbsnew;
00197 nbsnew.reserve( sizeHint );
00198 size_t iter = 0;
00199 for( NodeInputIterator it = begin; it != end; ++it ) {
00200 DAI_ASSERT( *it < nrNodes() );
00201 Neighbor nb1new( iter, *it, nb(*it).size() );
00202 Neighbor nb2new( nb(*it).size(), nrNodes(), iter++ );
00203 nbsnew.push_back( nb1new );
00204 nb( *it ).push_back( nb2new );
00205 }
00206 _nb.push_back( nbsnew );
00207 return _nb.size() - 1;
00208 }
00209
00211
00213 GraphAL& addEdge( size_t n1, size_t n2, bool check = true );
00215
00217
00218
00219 void eraseNode( size_t n );
00220
00222 void eraseEdge( size_t n1, size_t n2 );
00224
00226
00227
00228 size_t nrNodes() const { return _nb.size(); }
00229
00231 size_t nrEdges() const {
00232 size_t sum = 0;
00233 for( size_t i = 0; i < nrNodes(); i++ )
00234 sum += nb(i).size();
00235 return sum / 2;
00236 }
00237
00239
00241 bool hasEdge( size_t n1, size_t n2 ) const {
00242 if( nb(n1).size() < nb(n2).size() ) {
00243 for( size_t _n2 = 0; _n2 < nb(n1).size(); _n2++ )
00244 if( nb( n1, _n2 ) == n2 )
00245 return true;
00246 } else {
00247 for( size_t _n1 = 0; _n1 < nb(n2).size(); _n1++ )
00248 if( nb( n2, _n1 ) == n1 )
00249 return true;
00250 }
00251 return false;
00252 }
00253
00255
00258 size_t findNb( size_t n1, size_t n2 ) {
00259 for( size_t _n2 = 0; _n2 < nb(n1).size(); _n2++ )
00260 if( nb( n1, _n2 ) == n2 )
00261 return _n2;
00262 DAI_THROW(OBJECT_NOT_FOUND);
00263 return nb(n1).size();
00264 }
00265
00267 SmallSet<size_t> nbSet( size_t n ) const;
00268
00270 bool isConnected() const;
00271
00273 bool isTree() const;
00274
00276 void checkConsistency() const;
00277
00279
00283 bool operator==( const GraphAL& x ) const {
00284 if( nrNodes() != x.nrNodes() )
00285 return false;
00286 for( size_t n1 = 0; n1 < nrNodes(); n1++ ) {
00287 if( nb(n1).size() != x.nb(n1).size() )
00288 return false;
00289 foreach( const Neighbor &n2, nb(n1) )
00290 if( !x.hasEdge( n1, n2 ) )
00291 return false;
00292 foreach( const Neighbor &n2, x.nb(n1) )
00293 if( !hasEdge( n1, n2 ) )
00294 return false;
00295 }
00296 return true;
00297 }
00299
00301
00302
00303 void printDot( std::ostream& os ) const;
00304
00306 friend std::ostream& operator<<( std::ostream& os, const GraphAL& g ) {
00307 g.printDot( os );
00308 return os;
00309 }
00311 };
00312
00313
00314 template<typename EdgeInputIterator>
00315 void GraphAL::construct( size_t nr, EdgeInputIterator begin, EdgeInputIterator end, bool check ) {
00316 _nb.clear();
00317 _nb.resize( nr );
00318
00319 for( EdgeInputIterator e = begin; e != end; e++ )
00320 addEdge( e->first, e->second, check );
00321 }
00322
00323
00325 GraphAL createGraphFull( size_t N );
00327 GraphAL createGraphGrid( size_t N1, size_t N2, bool periodic );
00329 GraphAL createGraphGrid3D( size_t N1, size_t N2, size_t N3, bool periodic );
00331 GraphAL createGraphLoop( size_t N );
00333 GraphAL createGraphTree( size_t N );
00335
00341 GraphAL createGraphRegular( size_t N, size_t d );
00342
00343
00344 }
00345
00346
00347 #endif