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
00076 struct Neighbor {
00078 size_t iter;
00080 size_t node;
00082 size_t dual;
00083
00085 Neighbor() {}
00087 Neighbor( size_t iter, size_t node, size_t dual ) : iter(iter), node(node), dual(dual) {}
00088
00090 operator size_t () const { return node; }
00091 };
00092
00093
00095 typedef std::vector<Neighbor> Neighbors;
00096
00097
00099
00103 typedef std::pair<size_t,size_t> Edge;
00104
00105
00107
00117 class GraphAL {
00118 private:
00120 std::vector<Neighbors> _nb;
00121
00122 public:
00124
00125
00126 GraphAL() : _nb() {}
00127
00129 GraphAL( size_t nr ) : _nb( nr ) {}
00130
00132
00138 template<typename EdgeInputIterator>
00139 GraphAL( size_t nr, EdgeInputIterator begin, EdgeInputIterator end, bool check=true ) : _nb() {
00140 construct( nr, begin, end, check );
00141 }
00143
00145
00146
00147 const Neighbor & nb( size_t n1, size_t _n2 ) const {
00148 DAI_DEBASSERT( n1 < _nb.size() );
00149 DAI_DEBASSERT( _n2 < _nb[n1].size() );
00150 return _nb[n1][_n2];
00151 }
00153 Neighbor & nb( size_t n1, size_t _n2 ) {
00154 DAI_DEBASSERT( n1 < _nb.size() );
00155 DAI_DEBASSERT( _n2 < _nb[n1].size() );
00156 return _nb[n1][_n2];
00157 }
00158
00160 const Neighbors & nb( size_t n ) const {
00161 DAI_DEBASSERT( n < _nb.size() );
00162 return _nb[n];
00163 }
00165 Neighbors & nb( size_t n ) {
00166 DAI_DEBASSERT( n < _nb.size() );
00167 return _nb[n];
00168 }
00170
00172
00173
00174
00180 template<typename EdgeInputIterator>
00181 void construct( size_t nr, EdgeInputIterator begin, EdgeInputIterator end, bool check=true );
00182
00184 size_t addNode() { _nb.push_back( Neighbors() ); return _nb.size() - 1; }
00185
00187
00193 template <typename NodeInputIterator>
00194 size_t addNode( NodeInputIterator begin, NodeInputIterator end, size_t sizeHint = 0 ) {
00195 Neighbors nbsnew;
00196 nbsnew.reserve( sizeHint );
00197 size_t iter = 0;
00198 for( NodeInputIterator it = begin; it != end; ++it ) {
00199 DAI_ASSERT( *it < nrNodes() );
00200 Neighbor nb1new( iter, *it, nb(*it).size() );
00201 Neighbor nb2new( nb(*it).size(), nrNodes(), iter++ );
00202 nbsnew.push_back( nb1new );
00203 nb( *it ).push_back( nb2new );
00204 }
00205 _nb.push_back( nbsnew );
00206 return _nb.size() - 1;
00207 }
00208
00210
00212 GraphAL& addEdge( size_t n1, size_t n2, bool check = true );
00214
00216
00217
00218 void eraseNode( size_t n );
00219
00221 void eraseEdge( size_t n1, size_t n2 );
00223
00225
00226
00227 size_t nrNodes() const { return _nb.size(); }
00228
00230 size_t nrEdges() const {
00231 size_t sum = 0;
00232 for( size_t i = 0; i < nrNodes(); i++ )
00233 sum += nb(i).size();
00234 return sum / 2;
00235 }
00236
00238
00240 bool hasEdge( size_t n1, size_t n2 ) const {
00241 if( nb(n1).size() < nb(n2).size() ) {
00242 for( size_t _n2 = 0; _n2 < nb(n1).size(); _n2++ )
00243 if( nb( n1, _n2 ) == n2 )
00244 return true;
00245 } else {
00246 for( size_t _n1 = 0; _n1 < nb(n2).size(); _n1++ )
00247 if( nb( n2, _n1 ) == n1 )
00248 return true;
00249 }
00250 return false;
00251 }
00252
00254
00257 size_t findNb( size_t n1, size_t n2 ) {
00258 for( size_t _n2 = 0; _n2 < nb(n1).size(); _n2++ )
00259 if( nb( n1, _n2 ) == n2 )
00260 return _n2;
00261 DAI_THROW(OBJECT_NOT_FOUND);
00262 return nb(n1).size();
00263 }
00264
00266 SmallSet<size_t> nbSet( size_t n ) const;
00267
00269 bool isConnected() const;
00270
00272 bool isTree() const;
00273
00275 void checkConsistency() const;
00276
00278
00282 bool operator==( const GraphAL& x ) const {
00283 if( nrNodes() != x.nrNodes() )
00284 return false;
00285 for( size_t n1 = 0; n1 < nrNodes(); n1++ ) {
00286 if( nb(n1).size() != x.nb(n1).size() )
00287 return false;
00288 foreach( const Neighbor &n2, nb(n1) )
00289 if( !x.hasEdge( n1, n2 ) )
00290 return false;
00291 foreach( const Neighbor &n2, x.nb(n1) )
00292 if( !hasEdge( n1, n2 ) )
00293 return false;
00294 }
00295 return true;
00296 }
00298
00300
00301
00302 void printDot( std::ostream& os ) const;
00303
00305 friend std::ostream& operator<<( std::ostream& os, const GraphAL& g ) {
00306 g.printDot( os );
00307 return os;
00308 }
00310 };
00311
00312
00313 template<typename EdgeInputIterator>
00314 void GraphAL::construct( size_t nr, EdgeInputIterator begin, EdgeInputIterator end, bool check ) {
00315 _nb.clear();
00316 _nb.resize( nr );
00317
00318 for( EdgeInputIterator e = begin; e != end; e++ )
00319 addEdge( e->first, e->second, check );
00320 }
00321
00322
00324 GraphAL createGraphFull( size_t N );
00326 GraphAL createGraphGrid( size_t N1, size_t N2, bool periodic );
00328 GraphAL createGraphGrid3D( size_t N1, size_t N2, size_t N3, bool periodic );
00330 GraphAL createGraphLoop( size_t N );
00332 GraphAL createGraphTree( size_t N );
00334
00340 GraphAL createGraphRegular( size_t N, size_t d );
00341
00342
00343 }
00344
00345
00346 #endif