libDAI
bipgraph.h
Go to the documentation of this file.
1 /* This file is part of libDAI - http://www.libdai.org/
2  *
3  * Copyright (c) 2006-2011, The libDAI authors. All rights reserved.
4  *
5  * Use of this source code is governed by a BSD-style license that can be found in the LICENSE file.
6  */
7 
8 
11 
12 
13 #ifndef __defined_libdai_bipgraph_h
14 #define __defined_libdai_bipgraph_h
15 
16 
17 #include <ostream>
18 #include <vector>
19 #include <algorithm>
20 #include <dai/util.h>
21 #include <dai/smallset.h>
22 #include <dai/exceptions.h>
23 #include <dai/graph.h>
24 
25 
26 namespace dai {
27 
28 
30 
46  private:
48  std::vector<Neighbors> _nb1;
49 
51  std::vector<Neighbors> _nb2;
52 
54  struct levelType {
56  std::vector<size_t> ind1;
58  std::vector<size_t> ind2;
59  };
60 
61  public:
63 
64  BipartiteGraph() : _nb1(), _nb2() {}
66 
68  BipartiteGraph( size_t nr1, size_t nr2 ) : _nb1(nr1), _nb2(nr2) {}
69 
71 
78  template<typename EdgeInputIterator>
79  BipartiteGraph( size_t nrNodes1, size_t nrNodes2, EdgeInputIterator begin, EdgeInputIterator end, bool check=true ) : _nb1(), _nb2() {
80  construct( nrNodes1, nrNodes2, begin, end, check );
81  }
83 
85 
86  const Neighbor & nb1( size_t i1, size_t _i2 ) const {
88  DAI_DEBASSERT( i1 < _nb1.size() );
89  DAI_DEBASSERT( _i2 < _nb1[i1].size() );
90  return _nb1[i1][_i2];
91  }
93  Neighbor & nb1( size_t i1, size_t _i2 ) {
94  DAI_DEBASSERT( i1 < _nb1.size() );
95  DAI_DEBASSERT( _i2 < _nb1[i1].size() );
96  return _nb1[i1][_i2];
97  }
98 
100  const Neighbor & nb2( size_t i2, size_t _i1 ) const {
101  DAI_DEBASSERT( i2 < _nb2.size() );
102  DAI_DEBASSERT( _i1 < _nb2[i2].size() );
103  return _nb2[i2][_i1];
104  }
106  Neighbor & nb2( size_t i2, size_t _i1 ) {
107  DAI_DEBASSERT( i2 < _nb2.size() );
108  DAI_DEBASSERT( _i1 < _nb2[i2].size() );
109  return _nb2[i2][_i1];
110  }
111 
113  const Neighbors & nb1( size_t i1 ) const {
114  DAI_DEBASSERT( i1 < _nb1.size() );
115  return _nb1[i1];
116  }
118  Neighbors & nb1( size_t i1 ) {
119  DAI_DEBASSERT( i1 < _nb1.size() );
120  return _nb1[i1];
121  }
122 
124  const Neighbors & nb2( size_t i2 ) const {
125  DAI_DEBASSERT( i2 < _nb2.size() );
126  return _nb2[i2];
127  }
129  Neighbors & nb2( size_t i2 ) {
130  DAI_DEBASSERT( i2 < _nb2.size() );
131  return _nb2[i2];
132  }
134 
136 
137 
145  template<typename EdgeInputIterator>
146  void construct( size_t nrNodes1, size_t nrNodes2, EdgeInputIterator begin, EdgeInputIterator end, bool check=true );
147 
149  size_t addNode1() { _nb1.push_back( Neighbors() ); return _nb1.size() - 1; }
150 
152  size_t addNode2() { _nb2.push_back( Neighbors() ); return _nb2.size() - 1; }
153 
154 
156 
162  template <typename NodeInputIterator>
163  size_t addNode1( NodeInputIterator begin, NodeInputIterator end, size_t sizeHint = 0 ) {
164  Neighbors nbs1new;
165  nbs1new.reserve( sizeHint );
166  size_t iter = 0;
167  for( NodeInputIterator it = begin; it != end; ++it ) {
168  DAI_ASSERT( *it < nrNodes2() );
169  Neighbor nb1new( iter, *it, nb2(*it).size() );
170  Neighbor nb2new( nb2(*it).size(), nrNodes1(), iter++ );
171  nbs1new.push_back( nb1new );
172  nb2( *it ).push_back( nb2new );
173  }
174  _nb1.push_back( nbs1new );
175  return _nb1.size() - 1;
176  }
177 
179 
185  template <typename NodeInputIterator>
186  size_t addNode2( NodeInputIterator begin, NodeInputIterator end, size_t sizeHint = 0 ) {
187  Neighbors nbs2new;
188  nbs2new.reserve( sizeHint );
189  size_t iter = 0;
190  for( NodeInputIterator it = begin; it != end; ++it ) {
191  DAI_ASSERT( *it < nrNodes1() );
192  Neighbor nb2new( iter, *it, nb1(*it).size() );
193  Neighbor nb1new( nb1(*it).size(), nrNodes2(), iter++ );
194  nbs2new.push_back( nb2new );
195  nb1( *it ).push_back( nb1new );
196  }
197  _nb2.push_back( nbs2new );
198  return _nb2.size() - 1;
199  }
200 
202 
204  BipartiteGraph& addEdge( size_t n1, size_t n2, bool check = true );
206 
208 
209  void eraseNode1( size_t n1 );
211 
213  void eraseNode2( size_t n2 );
214 
216  void eraseEdge( size_t n1, size_t n2 );
218 
220 
221  size_t nrNodes1() const { return _nb1.size(); }
224  size_t nrNodes2() const { return _nb2.size(); }
225 
227  size_t nrEdges() const {
228  size_t sum = 0;
229  for( size_t i1 = 0; i1 < nrNodes1(); i1++ )
230  sum += nb1(i1).size();
231  return sum;
232  }
233 
235 
237  bool hasEdge( size_t n1, size_t n2 ) const {
238  if( nb1(n1).size() < nb2(n2).size() ) {
239  for( size_t _n2 = 0; _n2 < nb1(n1).size(); _n2++ )
240  if( nb1( n1, _n2 ) == n2 )
241  return true;
242  } else {
243  for( size_t _n1 = 0; _n1 < nb2(n2).size(); _n1++ )
244  if( nb2( n2, _n1 ) == n1 )
245  return true;
246  }
247  return false;
248  }
249 
251 
254  size_t findNb1( size_t n1, size_t n2 ) {
255  for( size_t _n2 = 0; _n2 < nb1(n1).size(); _n2++ )
256  if( nb1( n1, _n2 ) == n2 )
257  return _n2;
258  DAI_THROW(OBJECT_NOT_FOUND);
259  return nb1(n1).size();
260  }
261 
263 
266  size_t findNb2( size_t n1, size_t n2 ) {
267  for( size_t _n1 = 0; _n1 < nb2(n2).size(); _n1++ )
268  if( nb2( n2, _n1 ) == n1 )
269  return _n1;
270  DAI_THROW(OBJECT_NOT_FOUND);
271  return nb2(n2).size();
272  }
273 
275  SmallSet<size_t> nb1Set( size_t n1 ) const;
276 
278  SmallSet<size_t> nb2Set( size_t n2 ) const;
279 
281 
284  SmallSet<size_t> delta1( size_t n1, bool include = false ) const;
285 
287 
290  SmallSet<size_t> delta2( size_t n2, bool include = false ) const;
291 
293  bool isConnected() const;
294 
296  bool isTree() const;
297 
299 
303  bool operator==( const BipartiteGraph& x ) const {
304  if( nrNodes1() != x.nrNodes1() )
305  return false;
306  if( nrNodes2() != x.nrNodes2() )
307  return false;
308  for( size_t n1 = 0; n1 < nrNodes1(); n1++ ) {
309  if( nb1(n1).size() != x.nb1(n1).size() )
310  return false;
311  bforeach( const Neighbor &n2, nb1(n1) )
312  if( !x.hasEdge( n1, n2 ) )
313  return false;
314  bforeach( const Neighbor &n2, x.nb1(n1) )
315  if( !hasEdge( n1, n2 ) )
316  return false;
317  }
318  return true;
319  }
320 
322  void checkConsistency() const;
324 
326 
327  void printDot( std::ostream& os ) const;
329 
331  friend std::ostream& operator<<( std::ostream& os, const BipartiteGraph& g ) {
332  g.printDot( os );
333  return os;
334  }
335 
337  std::string toString() const {
338  std::stringstream ss;
339  ss << *this;
340  return ss.str();
341  }
343 };
344 
345 
346 template<typename EdgeInputIterator>
347 void BipartiteGraph::construct( size_t nrNodes1, size_t nrNodes2, EdgeInputIterator begin, EdgeInputIterator end, bool check ) {
348  _nb1.clear();
349  _nb1.resize( nrNodes1 );
350  _nb2.clear();
351  _nb2.resize( nrNodes2 );
352 
353  for( EdgeInputIterator e = begin; e != end; e++ )
354  addEdge( e->first, e->second, check );
355 }
356 
357 
358 } // end of namespace dai
359 
360 
396 #endif
BipartiteGraph & addEdge(size_t n1, size_t n2, bool check=true)
Adds an edge between node n1 of type 1 and node n2 of type 2.
Definition: bipgraph.cpp:18
std::vector< Neighbor > Neighbors
Describes the set of neighbors of some node in a graph.
Definition: graph.h:92
SmallSet< size_t > delta1(size_t n1, bool include=false) const
Calculates second-order neighbors (i.e., neighbors of neighbors) of node n1 of type 1...
Definition: bipgraph.cpp:135
void eraseNode1(size_t n1)
Removes node n1 of type 1 and all incident edges; indices of other nodes are changed accordingly...
Definition: bipgraph.cpp:40
bool isTree() const
Returns true if the graph is a tree, i.e., if it is singly connected and connected.
Definition: bipgraph.cpp:230
size_t addNode2()
Adds a node of type 2 without neighbors and returns the index of the added node.
Definition: bipgraph.h:152
std::vector< Neighbors > _nb1
Contains for each node of type 1 a vector of its neighbors.
Definition: bipgraph.h:48
size_t nrNodes1() const
Returns number of nodes of type 1.
Definition: bipgraph.h:222
SmallSet< size_t > nb2Set(size_t n2) const
Returns neighbors of node n2 of type 2 as a SmallSet.
Definition: bipgraph.cpp:127
const Neighbor & nb1(size_t i1, size_t _i2) const
Returns constant reference to the _i2 'th neighbor of node i1 of type 1.
Definition: bipgraph.h:87
std::string toString() const
Formats a BipartiteGraph as a string.
Definition: bipgraph.h:337
void checkConsistency() const
Asserts internal consistency.
Definition: bipgraph.cpp:314
const Neighbors & nb2(size_t i2) const
Returns constant reference to all neighbors of node i2 of type 2.
Definition: bipgraph.h:124
size_t nrEdges() const
Calculates the number of edges, time complexity: O(nrNodes1())
Definition: bipgraph.h:227
void printDot(std::ostream &os) const
Writes a BipartiteGraph to an output stream in GraphViz .dot syntax.
Definition: bipgraph.cpp:299
Represents the neighborhood structure of nodes in an undirected, bipartite graph. ...
Definition: bipgraph.h:45
size_t nrNodes2() const
Returns number of nodes of type 2.
Definition: bipgraph.h:224
Neighbor & nb1(size_t i1, size_t _i2)
Returns reference to the _i2 'th neighbor of node i1 of type 1.
Definition: bipgraph.h:93
size_t addNode1(NodeInputIterator begin, NodeInputIterator end, size_t sizeHint=0)
Adds a node of type 1, with neighbors specified by a range of nodes of type 2.
Definition: bipgraph.h:163
size_t findNb1(size_t n1, size_t n2)
Returns the index of a given node n2 of type 2 amongst the neighbors of node n1 of type 1...
Definition: bipgraph.h:254
size_t addNode1()
Adds a node of type 1 without neighbors and returns the index of the added node.
Definition: bipgraph.h:149
SmallSet< size_t > delta2(size_t n2, bool include=false) const
Calculates second-order neighbors (i.e., neighbors of neighbors) of node n2 of type 2...
Definition: bipgraph.cpp:146
BipartiteGraph()
Default constructor (creates an empty bipartite graph)
Definition: bipgraph.h:65
Neighbors & nb2(size_t i2)
Returns reference to all neighbors of node i2 of type 2.
Definition: bipgraph.h:129
const Neighbor & nb2(size_t i2, size_t _i1) const
Returns constant reference to the _i1 'th neighbor of node i2 of type 2.
Definition: bipgraph.h:100
Neighbor & nb2(size_t i2, size_t _i1)
Returns reference to the _i1 'th neighbor of node i2 of type 2.
Definition: bipgraph.h:106
#define bforeach
An alias to the BOOST_FOREACH macro from the boost::bforeach library.
Definition: util.h:48
void eraseNode2(size_t n2)
Removes node n2 of type 2 and all incident edges; indices of other nodes are changed accordingly...
Definition: bipgraph.cpp:63
Defines the Exception class and macros for throwing exceptions and doing assertions.
std::vector< size_t > ind1
Indices of nodes of type 1.
Definition: bipgraph.h:56
Defines general utility functions and adds an abstraction layer for platform-dependent functionality...
BipartiteGraph(size_t nrNodes1, size_t nrNodes2, EdgeInputIterator begin, EdgeInputIterator end, bool check=true)
Constructs BipartiteGraph from a range of edges.
Definition: bipgraph.h:79
void eraseEdge(size_t n1, size_t n2)
Removes edge between node n1 of type 1 and node n2 of type 2.
Definition: bipgraph.cpp:86
std::vector< Neighbors > _nb2
Contains for each node of type 2 a vector of its neighbors.
Definition: bipgraph.h:51
Defines the GraphAL class, which represents an undirected graph as an adjacency list.
Used internally by isTree()
Definition: bipgraph.h:54
Defines the SmallSet<> class, which represents a set (optimized for a small number of elements)...
Describes the neighbor relationship of two nodes in a graph.
Definition: graph.h:73
size_t addNode2(NodeInputIterator begin, NodeInputIterator end, size_t sizeHint=0)
Adds a node of type 2, with neighbors specified by a range of nodes of type 1.
Definition: bipgraph.h:186
std::vector< size_t > ind2
Indices of nodes of type 2.
Definition: bipgraph.h:58
const Neighbors & nb1(size_t i1) const
Returns constant reference to all neighbors of node i1 of type 1.
Definition: bipgraph.h:113
bool hasEdge(size_t n1, size_t n2) const
Returns true if the graph contains an edge between node n1 of type 1 and node n2 of type 2...
Definition: bipgraph.h:237
Namespace for libDAI.
Definition: alldai.cpp:16
friend std::ostream & operator<<(std::ostream &os, const BipartiteGraph &g)
Writes a BipartiteGraph to an output stream.
Definition: bipgraph.h:331
bool operator==(const BipartiteGraph &x) const
Comparison operator which returns true if two graphs are identical.
Definition: bipgraph.h:303
void construct(size_t nrNodes1, size_t nrNodes2, EdgeInputIterator begin, EdgeInputIterator end, bool check=true)
(Re)constructs BipartiteGraph from a range of edges.
Definition: bipgraph.h:347
#define DAI_ASSERT(condition)
Assertion mechanism, similar to the standard assert() macro. It is always active, even if NDEBUG is d...
Definition: exceptions.h:60
#define DAI_DEBASSERT(x)
Assertion mechanism similar to DAI_ASSERT which is only active if DAI_DEBUG is defined.
Definition: exceptions.h:65
BipartiteGraph(size_t nr1, size_t nr2)
Constructs BipartiteGraph with nr1 nodes of type 1, nr2 nodes of type 2 and no edges.
Definition: bipgraph.h:68
bool isConnected() const
Returns true if the graph is connected.
Definition: bipgraph.cpp:157
Neighbors & nb1(size_t i1)
Returns reference to all neighbors of node i1 of type 1.
Definition: bipgraph.h:118
size_t findNb2(size_t n1, size_t n2)
Returns the index of a given node n1 of type 1 amongst the neighbors of node n2 of type 2...
Definition: bipgraph.h:266
SmallSet< size_t > nb1Set(size_t n1) const
Returns neighbors of node n1 of type 1 as a SmallSet.
Definition: bipgraph.cpp:119