FullBpGraph implementation (#69)
authorBalazs Dezso <deba@inf.elte.hu>
Sun, 14 Nov 2010 22:48:32 +0100
changeset 10205ef0ab7b61cd
parent 1019 4c89e925cfe2
child 1021 a12cca3ad15a
FullBpGraph implementation (#69)
lemon/bits/graph_extender.h
lemon/core.h
lemon/full_graph.h
lemon/smart_graph.h
test/bpgraph_test.cc
     1.1 --- a/lemon/bits/graph_extender.h	Sun Nov 14 20:06:23 2010 +0100
     1.2 +++ b/lemon/bits/graph_extender.h	Sun Nov 14 22:48:32 2010 +0100
     1.3 @@ -841,11 +841,14 @@
     1.4        return Parent::edgeFromId(id);
     1.5      }
     1.6  
     1.7 +    Node u(Edge e) const { return this->redNode(e); }
     1.8 +    Node v(Edge e) const { return this->blueNode(e); }
     1.9 +
    1.10      Node oppositeNode(const Node &n, const Edge &e) const {
    1.11 -      if( n == Parent::u(e))
    1.12 -        return Parent::v(e);
    1.13 -      else if( n == Parent::v(e))
    1.14 -        return Parent::u(e);
    1.15 +      if( n == u(e))
    1.16 +        return v(e);
    1.17 +      else if( n == v(e))
    1.18 +        return u(e);
    1.19        else
    1.20          return INVALID;
    1.21      }
    1.22 @@ -856,7 +859,7 @@
    1.23  
    1.24      using Parent::direct;
    1.25      Arc direct(const Edge &edge, const Node &node) const {
    1.26 -      return Parent::direct(edge, Parent::u(edge) == node);
    1.27 +      return Parent::direct(edge, Parent::redNode(edge) == node);
    1.28      }
    1.29  
    1.30      // Alterable extension
     2.1 --- a/lemon/core.h	Sun Nov 14 20:06:23 2010 +0100
     2.2 +++ b/lemon/core.h	Sun Nov 14 22:48:32 2010 +0100
     2.3 @@ -164,7 +164,7 @@
     2.4    typedef BpGraph::RedIt RedIt;                                         \
     2.5    typedef BpGraph::RedMap<bool> BoolRedMap;                             \
     2.6    typedef BpGraph::RedMap<int> IntRedMap;                               \
     2.7 -  typedef BpGraph::RedMap<double> DoubleRedMap                          \
     2.8 +  typedef BpGraph::RedMap<double> DoubleRedMap;                         \
     2.9    typedef BpGraph::BlueNode BlueNode;                                   \
    2.10    typedef BpGraph::BlueIt BlueIt;                                       \
    2.11    typedef BpGraph::BlueMap<bool> BoolBlueMap;                           \
     3.1 --- a/lemon/full_graph.h	Sun Nov 14 20:06:23 2010 +0100
     3.2 +++ b/lemon/full_graph.h	Sun Nov 14 22:48:32 2010 +0100
     3.3 @@ -621,6 +621,436 @@
     3.4  
     3.5    };
     3.6  
     3.7 +  class FullBpGraphBase {
     3.8 +
     3.9 +  protected:
    3.10 +
    3.11 +    int _red_num, _blue_num;
    3.12 +    int _node_num, _edge_num;
    3.13 +
    3.14 +  public:
    3.15 +
    3.16 +    typedef FullBpGraphBase Graph;
    3.17 +
    3.18 +    class Node;
    3.19 +    class Arc;
    3.20 +    class Edge;
    3.21 +
    3.22 +    class Node {
    3.23 +      friend class FullBpGraphBase;
    3.24 +    protected:
    3.25 +
    3.26 +      int _id;
    3.27 +      explicit Node(int id) { _id = id;}
    3.28 +
    3.29 +    public:
    3.30 +      Node() {}
    3.31 +      Node (Invalid) { _id = -1; }
    3.32 +      bool operator==(const Node& node) const {return _id == node._id;}
    3.33 +      bool operator!=(const Node& node) const {return _id != node._id;}
    3.34 +      bool operator<(const Node& node) const {return _id < node._id;}
    3.35 +    };
    3.36 +
    3.37 +    class Edge {
    3.38 +      friend class FullBpGraphBase;
    3.39 +    protected:
    3.40 +
    3.41 +      int _id;
    3.42 +      explicit Edge(int id) { _id = id;}
    3.43 +
    3.44 +    public:
    3.45 +      Edge() {}
    3.46 +      Edge (Invalid) { _id = -1; }
    3.47 +      bool operator==(const Edge& arc) const {return _id == arc._id;}
    3.48 +      bool operator!=(const Edge& arc) const {return _id != arc._id;}
    3.49 +      bool operator<(const Edge& arc) const {return _id < arc._id;}
    3.50 +    };
    3.51 +
    3.52 +    class Arc {
    3.53 +      friend class FullBpGraphBase;
    3.54 +    protected:
    3.55 +
    3.56 +      int _id;
    3.57 +      explicit Arc(int id) { _id = id;}
    3.58 +
    3.59 +    public:
    3.60 +      operator Edge() const {
    3.61 +        return _id != -1 ? edgeFromId(_id / 2) : INVALID;
    3.62 +      }
    3.63 +
    3.64 +      Arc() {}
    3.65 +      Arc (Invalid) { _id = -1; }
    3.66 +      bool operator==(const Arc& arc) const {return _id == arc._id;}
    3.67 +      bool operator!=(const Arc& arc) const {return _id != arc._id;}
    3.68 +      bool operator<(const Arc& arc) const {return _id < arc._id;}
    3.69 +    };
    3.70 +
    3.71 +
    3.72 +  protected:
    3.73 +
    3.74 +    FullBpGraphBase()
    3.75 +      : _red_num(0), _blue_num(0), _node_num(0), _edge_num(0) {}
    3.76 +
    3.77 +    void construct(int redNum, int blueNum) {
    3.78 +      _red_num = redNum; _blue_num = blueNum;
    3.79 +      _node_num = redNum + blueNum; _edge_num = redNum * blueNum;
    3.80 +    }
    3.81 +
    3.82 +  public:
    3.83 +
    3.84 +    typedef True NodeNumTag;
    3.85 +    typedef True EdgeNumTag;
    3.86 +    typedef True ArcNumTag;
    3.87 +
    3.88 +    int nodeNum() const { return _node_num; }
    3.89 +    int redNum() const { return _red_num; }
    3.90 +    int blueNum() const { return _blue_num; }
    3.91 +    int edgeNum() const { return _edge_num; }
    3.92 +    int arcNum() const { return 2 * _edge_num; }
    3.93 +
    3.94 +    int maxNodeId() const { return _node_num - 1; }
    3.95 +    int maxRedId() const { return _red_num - 1; }
    3.96 +    int maxBlueId() const { return _blue_num - 1; }
    3.97 +    int maxEdgeId() const { return _edge_num - 1; }
    3.98 +    int maxArcId() const { return 2 * _edge_num - 1; }
    3.99 +
   3.100 +    bool red(Node n) const { return n._id < _red_num; }
   3.101 +    bool blue(Node n) const { return n._id >= _red_num; }
   3.102 +
   3.103 +    Node source(Arc a) const {
   3.104 +      if (a._id & 1) {
   3.105 +        return Node((a._id >> 1) % _red_num);
   3.106 +      } else {
   3.107 +        return Node((a._id >> 1) / _red_num + _red_num);
   3.108 +      }
   3.109 +    }
   3.110 +    Node target(Arc a) const {
   3.111 +      if (a._id & 1) {
   3.112 +        return Node((a._id >> 1) / _red_num + _red_num);
   3.113 +      } else {
   3.114 +        return Node((a._id >> 1) % _red_num);
   3.115 +      }
   3.116 +    }
   3.117 +
   3.118 +    Node redNode(Edge e) const {
   3.119 +      return Node(e._id % _red_num);
   3.120 +    }
   3.121 +    Node blueNode(Edge e) const {
   3.122 +      return Node(e._id / _red_num + _red_num);
   3.123 +    }
   3.124 +
   3.125 +    static bool direction(Arc a) {
   3.126 +      return (a._id & 1) == 1;
   3.127 +    }
   3.128 +
   3.129 +    static Arc direct(Edge e, bool d) {
   3.130 +      return Arc(e._id * 2 + (d ? 1 : 0));
   3.131 +    }
   3.132 +
   3.133 +    void first(Node& node) const {
   3.134 +      node._id = _node_num - 1;
   3.135 +    }
   3.136 +
   3.137 +    static void next(Node& node) {
   3.138 +      --node._id;
   3.139 +    }
   3.140 +
   3.141 +    void firstRed(Node& node) const {
   3.142 +      node._id = _red_num - 1;
   3.143 +    }
   3.144 +
   3.145 +    static void nextRed(Node& node) {
   3.146 +      --node._id;
   3.147 +    }
   3.148 +
   3.149 +    void firstBlue(Node& node) const {
   3.150 +      if (_red_num == _node_num) node._id = -1;
   3.151 +      else node._id = _node_num - 1;
   3.152 +    }
   3.153 +
   3.154 +    void nextBlue(Node& node) const {
   3.155 +      if (node._id == _red_num) node._id = -1;
   3.156 +      else --node._id;
   3.157 +    }
   3.158 +
   3.159 +    void first(Arc& arc) const {
   3.160 +      arc._id = 2 * _edge_num - 1;
   3.161 +    }
   3.162 +
   3.163 +    static void next(Arc& arc) {
   3.164 +      --arc._id;
   3.165 +    }
   3.166 +
   3.167 +    void first(Edge& arc) const {
   3.168 +      arc._id = _edge_num - 1;
   3.169 +    }
   3.170 +
   3.171 +    static void next(Edge& arc) {
   3.172 +      --arc._id;
   3.173 +    }
   3.174 +
   3.175 +    void firstOut(Arc &a, const Node& v) const {
   3.176 +      if (v._id < _red_num) {
   3.177 +        a._id = 2 * (v._id + _red_num * (_blue_num - 1)) + 1;
   3.178 +      } else {
   3.179 +        a._id = 2 * (_red_num - 1 + _red_num * (v._id - _red_num));
   3.180 +      }
   3.181 +    }
   3.182 +    void nextOut(Arc &a) const {
   3.183 +      if (a._id & 1) {
   3.184 +        a._id -= 2 * _red_num;
   3.185 +        if (a._id < 0) a._id = -1;
   3.186 +      } else {
   3.187 +        if (a._id % (2 * _red_num) == 0) a._id = -1;
   3.188 +        else a._id -= 2;
   3.189 +      }
   3.190 +    }
   3.191 +
   3.192 +    void firstIn(Arc &a, const Node& v) const {
   3.193 +      if (v._id < _red_num) {
   3.194 +        a._id = 2 * (v._id + _red_num * (_blue_num - 1));
   3.195 +      } else {
   3.196 +        a._id = 2 * (_red_num - 1 + _red_num * (v._id - _red_num)) + 1;
   3.197 +      }
   3.198 +    }
   3.199 +    void nextIn(Arc &a) const {
   3.200 +      if (a._id & 1) {
   3.201 +        if (a._id % (2 * _red_num) == 1) a._id = -1;
   3.202 +        else a._id -= 2;
   3.203 +      } else {
   3.204 +        a._id -= 2 * _red_num;
   3.205 +        if (a._id < 0) a._id = -1;
   3.206 +      }
   3.207 +    }
   3.208 +
   3.209 +    void firstInc(Edge &e, bool& d, const Node& v) const {
   3.210 +      if (v._id < _red_num) {
   3.211 +        d = true;
   3.212 +        e._id = v._id + _red_num * (_blue_num - 1);
   3.213 +      } else {
   3.214 +        d = false;
   3.215 +        e._id = _red_num - 1 + _red_num * (v._id - _red_num);
   3.216 +      }
   3.217 +    }
   3.218 +    void nextInc(Edge &e, bool& d) const {
   3.219 +      if (d) {
   3.220 +        e._id -= _red_num;
   3.221 +        if (e._id < 0) e._id = -1;
   3.222 +      } else {
   3.223 +        if (e._id % _red_num == 0) e._id = -1;
   3.224 +        else --e._id;
   3.225 +      }
   3.226 +    }
   3.227 +
   3.228 +    static int id(Node v) { return v._id; }
   3.229 +    int redId(Node v) const {
   3.230 +      LEMON_DEBUG(v._id < _red_num, "Node has to be red");
   3.231 +      return v._id;
   3.232 +    }
   3.233 +    int blueId(Node v) const {
   3.234 +      LEMON_DEBUG(v._id >= _red_num, "Node has to be blue");
   3.235 +      return v._id - _red_num;
   3.236 +    }
   3.237 +    static int id(Arc e) { return e._id; }
   3.238 +    static int id(Edge e) { return e._id; }
   3.239 +    
   3.240 +    static Node nodeFromId(int id) { return Node(id);}
   3.241 +    static Arc arcFromId(int id) { return Arc(id);}
   3.242 +    static Edge edgeFromId(int id) { return Edge(id);}
   3.243 +
   3.244 +    bool valid(Node n) const {
   3.245 +      return n._id >= 0 && n._id < _node_num;
   3.246 +    }
   3.247 +    bool valid(Arc a) const {
   3.248 +      return a._id >= 0 && a._id < 2 * _edge_num;
   3.249 +    }
   3.250 +    bool valid(Edge e) const {
   3.251 +      return e._id >= 0 && e._id < _edge_num;
   3.252 +    }
   3.253 +
   3.254 +    Node redNode(int index) const {
   3.255 +      return Node(index);
   3.256 +    }
   3.257 +
   3.258 +    int redIndex(Node n) const {
   3.259 +      return n._id;
   3.260 +    }
   3.261 +
   3.262 +    Node blueNode(int index) const {
   3.263 +      return Node(index + _red_num);
   3.264 +    }
   3.265 +
   3.266 +    int blueIndex(Node n) const {
   3.267 +      return n._id - _red_num;
   3.268 +    }
   3.269 +        
   3.270 +    void clear() {
   3.271 +      _red_num = 0; _blue_num = 0;
   3.272 +      _node_num = 0; _edge_num = 0;
   3.273 +    }
   3.274 +
   3.275 +    Edge edge(const Node& u, const Node& v) const { 
   3.276 +      if (u._id < _red_num) {
   3.277 +        if (v._id < _red_num) {
   3.278 +          return Edge(-1);
   3.279 +        } else {
   3.280 +          return Edge(u._id + _red_num * (v._id - _red_num));
   3.281 +        }
   3.282 +      } else {
   3.283 +        if (v._id < _red_num) {
   3.284 +          return Edge(v._id + _red_num * (u._id - _red_num));
   3.285 +        } else {
   3.286 +          return Edge(-1);
   3.287 +        }
   3.288 +      }
   3.289 +    }
   3.290 +
   3.291 +    Arc arc(const Node& u, const Node& v) const { 
   3.292 +      if (u._id < _red_num) {
   3.293 +        if (v._id < _red_num) {
   3.294 +          return Arc(-1);
   3.295 +        } else {
   3.296 +          return Arc(2 * (u._id + _red_num * (v._id - _red_num)) + 1);
   3.297 +        }
   3.298 +      } else {
   3.299 +        if (v._id < _red_num) {
   3.300 +          return Arc(2 * (v._id + _red_num * (u._id - _red_num)));
   3.301 +        } else {
   3.302 +          return Arc(-1);
   3.303 +        }
   3.304 +      }
   3.305 +    }
   3.306 +
   3.307 +    typedef True FindEdgeTag;
   3.308 +    typedef True FindArcTag;
   3.309 +
   3.310 +    Edge findEdge(Node u, Node v, Edge prev = INVALID) const {
   3.311 +      return prev != INVALID ? INVALID : edge(u, v);
   3.312 +    }
   3.313 +
   3.314 +    Arc findArc(Node s, Node t, Arc prev = INVALID) const {
   3.315 +      return prev != INVALID ? INVALID : arc(s, t);
   3.316 +    }
   3.317 +
   3.318 +  };
   3.319 +
   3.320 +  typedef BpGraphExtender<FullBpGraphBase> ExtendedFullBpGraphBase;
   3.321 +
   3.322 +  /// \ingroup graphs
   3.323 +  ///
   3.324 +  /// \brief An undirected full bipartite graph class.
   3.325 +  ///
   3.326 +  /// FullBpGraph is a simple and fast implmenetation of undirected
   3.327 +  /// full bipartite graphs. It contains an edge between every
   3.328 +  /// red-blue pairs of nodes, therefore the number of edges is
   3.329 +  /// <tt>nr*nb</tt>.  This class is completely static and it needs
   3.330 +  /// constant memory space.  Thus you can neither add nor delete
   3.331 +  /// nodes or edges, however the structure can be resized using
   3.332 +  /// resize().
   3.333 +  ///
   3.334 +  /// This type fully conforms to the \ref concepts::BpGraph "BpGraph concept".
   3.335 +  /// Most of its member functions and nested classes are documented
   3.336 +  /// only in the concept class.
   3.337 +  ///
   3.338 +  /// This class provides constant time counting for nodes, edges and arcs.
   3.339 +  ///
   3.340 +  /// \sa FullGraph
   3.341 +  class FullBpGraph : public ExtendedFullBpGraphBase {
   3.342 +  public:
   3.343 +
   3.344 +    typedef ExtendedFullBpGraphBase Parent;
   3.345 +
   3.346 +    /// \brief Default constructor.
   3.347 +    ///
   3.348 +    /// Default constructor. The number of nodes and edges will be zero.
   3.349 +    FullBpGraph() { construct(0, 0); }
   3.350 +
   3.351 +    /// \brief Constructor
   3.352 +    ///
   3.353 +    /// Constructor.
   3.354 +    /// \param redNum The number of the red nodes.
   3.355 +    /// \param blueNum The number of the blue nodes.
   3.356 +    FullBpGraph(int redNum, int blueNum) { construct(redNum, blueNum); }
   3.357 +
   3.358 +    /// \brief Resizes the graph
   3.359 +    ///
   3.360 +    /// This function resizes the graph. It fully destroys and
   3.361 +    /// rebuilds the structure, therefore the maps of the graph will be
   3.362 +    /// reallocated automatically and the previous values will be lost.
   3.363 +    void resize(int redNum, int blueNum) {
   3.364 +      Parent::notifier(Arc()).clear();
   3.365 +      Parent::notifier(Edge()).clear();
   3.366 +      Parent::notifier(Node()).clear();
   3.367 +      Parent::notifier(BlueNode()).clear();
   3.368 +      Parent::notifier(RedNode()).clear();
   3.369 +      construct(redNum, blueNum);
   3.370 +      Parent::notifier(RedNode()).build();
   3.371 +      Parent::notifier(BlueNode()).build();
   3.372 +      Parent::notifier(Node()).build();
   3.373 +      Parent::notifier(Edge()).build();
   3.374 +      Parent::notifier(Arc()).build();
   3.375 +    }
   3.376 +
   3.377 +    /// \brief Returns the red node with the given index.
   3.378 +    ///
   3.379 +    /// Returns the red node with the given index. Since this
   3.380 +    /// structure is completely static, the red nodes can be indexed
   3.381 +    /// with integers from the range <tt>[0..redNum()-1]</tt>.
   3.382 +    /// \sa redIndex()
   3.383 +    Node redNode(int index) const { return Parent::redNode(index); }
   3.384 +
   3.385 +    /// \brief Returns the index of the given red node.
   3.386 +    ///
   3.387 +    /// Returns the index of the given red node. Since this structure
   3.388 +    /// is completely static, the red nodes can be indexed with
   3.389 +    /// integers from the range <tt>[0..redNum()-1]</tt>.
   3.390 +    ///
   3.391 +    /// \sa operator()()
   3.392 +    int redIndex(Node node) const { return Parent::redIndex(node); }
   3.393 +
   3.394 +    /// \brief Returns the blue node with the given index.
   3.395 +    ///
   3.396 +    /// Returns the blue node with the given index. Since this
   3.397 +    /// structure is completely static, the blue nodes can be indexed
   3.398 +    /// with integers from the range <tt>[0..blueNum()-1]</tt>.
   3.399 +    /// \sa blueIndex()
   3.400 +    Node blueNode(int index) const { return Parent::blueNode(index); }
   3.401 +
   3.402 +    /// \brief Returns the index of the given blue node.
   3.403 +    ///
   3.404 +    /// Returns the index of the given blue node. Since this structure
   3.405 +    /// is completely static, the blue nodes can be indexed with
   3.406 +    /// integers from the range <tt>[0..blueNum()-1]</tt>.
   3.407 +    ///
   3.408 +    /// \sa operator()()
   3.409 +    int blueIndex(Node node) const { return Parent::blueIndex(node); }
   3.410 +
   3.411 +    /// \brief Returns the edge which connects the given nodes.
   3.412 +    ///
   3.413 +    /// Returns the edge which connects the given nodes.
   3.414 +    Edge edge(const Node& u, const Node& v) const {
   3.415 +      return Parent::edge(u, v);
   3.416 +    }
   3.417 +
   3.418 +    /// \brief Returns the arc which connects the given nodes.
   3.419 +    ///
   3.420 +    /// Returns the arc which connects the given nodes.
   3.421 +    Arc arc(const Node& u, const Node& v) const {
   3.422 +      return Parent::arc(u, v);
   3.423 +    }
   3.424 +
   3.425 +    /// \brief Number of nodes.
   3.426 +    int nodeNum() const { return Parent::nodeNum(); }
   3.427 +    /// \brief Number of red nodes.
   3.428 +    int redNum() const { return Parent::redNum(); }
   3.429 +    /// \brief Number of blue nodes.
   3.430 +    int blueNum() const { return Parent::blueNum(); }
   3.431 +    /// \brief Number of arcs.
   3.432 +    int arcNum() const { return Parent::arcNum(); }
   3.433 +    /// \brief Number of edges.
   3.434 +    int edgeNum() const { return Parent::edgeNum(); }
   3.435 +  };
   3.436 +
   3.437  
   3.438  } //namespace lemon
   3.439  
     4.1 --- a/lemon/smart_graph.h	Sun Nov 14 20:06:23 2010 +0100
     4.2 +++ b/lemon/smart_graph.h	Sun Nov 14 22:48:32 2010 +0100
     4.3 @@ -925,9 +925,6 @@
     4.4      Node redNode(Edge e) const { return Node(arcs[2 * e._id].target); }
     4.5      Node blueNode(Edge e) const { return Node(arcs[2 * e._id + 1].target); }
     4.6  
     4.7 -    Node u(Edge e) const { return redNode(e); }
     4.8 -    Node v(Edge e) const { return blueNode(e); }
     4.9 -
    4.10      static bool direction(Arc a) {
    4.11        return (a._id & 1) == 1;
    4.12      }
    4.13 @@ -1101,22 +1098,22 @@
    4.14  
    4.15    /// \ingroup graphs
    4.16    ///
    4.17 -  /// \brief A smart undirected graph class.
    4.18 +  /// \brief A smart undirected bipartite graph class.
    4.19    ///
    4.20 -  /// \ref SmartBpGraph is a simple and fast graph implementation.
    4.21 +  /// \ref SmartBpGraph is a simple and fast bipartite graph implementation.
    4.22    /// It is also quite memory efficient but at the price
    4.23    /// that it does not support node and edge deletion
    4.24    /// (except for the Snapshot feature).
    4.25    ///
    4.26 -  /// This type fully conforms to the \ref concepts::Graph "Graph concept"
    4.27 +  /// This type fully conforms to the \ref concepts::BpGraph "BpGraph concept"
    4.28    /// and it also provides some additional functionalities.
    4.29    /// Most of its member functions and nested classes are documented
    4.30    /// only in the concept class.
    4.31    ///
    4.32    /// This class provides constant time counting for nodes, edges and arcs.
    4.33    ///
    4.34 -  /// \sa concepts::Graph
    4.35 -  /// \sa SmartDigraph
    4.36 +  /// \sa concepts::BpGraph
    4.37 +  /// \sa SmartGraph
    4.38    class SmartBpGraph : public ExtendedSmartBpGraphBase {
    4.39      typedef ExtendedSmartBpGraphBase Parent;
    4.40  
     5.1 --- a/test/bpgraph_test.cc	Sun Nov 14 20:06:23 2010 +0100
     5.2 +++ b/test/bpgraph_test.cc	Sun Nov 14 22:48:32 2010 +0100
     5.3 @@ -19,7 +19,7 @@
     5.4  #include <lemon/concepts/bpgraph.h>
     5.5  //#include <lemon/list_graph.h>
     5.6  #include <lemon/smart_graph.h>
     5.7 -//#include <lemon/full_graph.h>
     5.8 +#include <lemon/full_graph.h>
     5.9  
    5.10  #include "test_tools.h"
    5.11  #include "graph_test.h"
    5.12 @@ -250,12 +250,90 @@
    5.13    }
    5.14  }
    5.15  
    5.16 +void checkFullBpGraph(int redNum, int blueNum) {
    5.17 +  typedef FullBpGraph BpGraph;
    5.18 +  BPGRAPH_TYPEDEFS(BpGraph);
    5.19 +
    5.20 +  BpGraph G(redNum, blueNum);
    5.21 +  checkGraphNodeList(G, redNum + blueNum);
    5.22 +  checkGraphRedNodeList(G, redNum);
    5.23 +  checkGraphBlueNodeList(G, blueNum);
    5.24 +  checkGraphEdgeList(G, redNum * blueNum);
    5.25 +  checkGraphArcList(G, 2 * redNum * blueNum);
    5.26 +
    5.27 +  G.resize(redNum, blueNum);
    5.28 +  checkGraphNodeList(G, redNum + blueNum);
    5.29 +  checkGraphRedNodeList(G, redNum);
    5.30 +  checkGraphBlueNodeList(G, blueNum);
    5.31 +  checkGraphEdgeList(G, redNum * blueNum);
    5.32 +  checkGraphArcList(G, 2 * redNum * blueNum);
    5.33 +
    5.34 +  for (RedIt n(G); n != INVALID; ++n) {
    5.35 +    checkGraphOutArcList(G, n, blueNum);
    5.36 +    checkGraphInArcList(G, n, blueNum);
    5.37 +    checkGraphIncEdgeList(G, n, blueNum);
    5.38 +  }
    5.39 +
    5.40 +  for (BlueIt n(G); n != INVALID; ++n) {
    5.41 +    checkGraphOutArcList(G, n, redNum);
    5.42 +    checkGraphInArcList(G, n, redNum);
    5.43 +    checkGraphIncEdgeList(G, n, redNum);
    5.44 +  }
    5.45 +
    5.46 +  checkGraphConArcList(G, 2 * redNum * blueNum);
    5.47 +  checkGraphConEdgeList(G, redNum * blueNum);
    5.48 +
    5.49 +  checkArcDirections(G);
    5.50 +
    5.51 +  checkNodeIds(G);
    5.52 +  checkRedNodeIds(G);
    5.53 +  checkBlueNodeIds(G);
    5.54 +  checkArcIds(G);
    5.55 +  checkEdgeIds(G);
    5.56 +
    5.57 +  checkGraphNodeMap(G);
    5.58 +  checkGraphRedMap(G);
    5.59 +  checkGraphBlueMap(G);
    5.60 +  checkGraphArcMap(G);
    5.61 +  checkGraphEdgeMap(G);
    5.62 +
    5.63 +  for (int i = 0; i < G.redNum(); ++i) {
    5.64 +    check(G.red(G.redNode(i)), "Wrong node");
    5.65 +    check(G.redIndex(G.redNode(i)) == i, "Wrong index");
    5.66 +  }
    5.67 +
    5.68 +  for (int i = 0; i < G.blueNum(); ++i) {
    5.69 +    check(G.blue(G.blueNode(i)), "Wrong node");
    5.70 +    check(G.blueIndex(G.blueNode(i)) == i, "Wrong index");
    5.71 +  }
    5.72 +
    5.73 +  for (NodeIt u(G); u != INVALID; ++u) {
    5.74 +    for (NodeIt v(G); v != INVALID; ++v) {
    5.75 +      Edge e = G.edge(u, v);
    5.76 +      Arc a = G.arc(u, v);
    5.77 +      if (G.red(u) == G.red(v)) {
    5.78 +        check(e == INVALID, "Wrong edge lookup");
    5.79 +        check(a == INVALID, "Wrong arc lookup");
    5.80 +      } else {
    5.81 +        check((G.u(e) == u && G.v(e) == v) ||
    5.82 +              (G.u(e) == v && G.v(e) == u), "Wrong edge lookup");
    5.83 +        check(G.source(a) == u && G.target(a) == v, "Wrong arc lookup");
    5.84 +      }
    5.85 +    }
    5.86 +  }
    5.87 +
    5.88 +}
    5.89 +
    5.90  void checkGraphs() {
    5.91    { // Checking SmartGraph
    5.92      checkBpGraphBuild<SmartBpGraph>();
    5.93      checkBpGraphSnapshot<SmartBpGraph>();
    5.94      checkBpGraphValidity<SmartBpGraph>();
    5.95    }
    5.96 +  { // Checking FullBpGraph
    5.97 +    checkFullBpGraph(6, 8);
    5.98 +    checkFullBpGraph(7, 4);
    5.99 +  }
   5.100  }
   5.101  
   5.102  int main() {