lemon/full_graph.h
changeset 1935 67b38d699ea7
parent 1909 2d806130e700
child 1956 a055123339d5
equal deleted inserted replaced
12:f1795a0cc47f 13:b288123b6fa2
   401   public:
   401   public:
   402     FullUGraph(int n) { construct(n); }
   402     FullUGraph(int n) { construct(n); }
   403   };
   403   };
   404 
   404 
   405 
   405 
   406   class FullUBipartiteGraphBase {
   406   class FullBpUGraphBase {
   407   protected:
   407   protected:
   408 
   408 
   409     int _upperNodeNum;
   409     int _aNodeNum;
   410     int _lowerNodeNum;
   410     int _bNodeNum;
   411 
   411 
   412     int _edgeNum;
   412     int _edgeNum;
   413 
   413 
   414   public:
   414   public:
   415 
   415 
   416     class NodeSetError : public LogicError {
   416     class NodeSetError : public LogicError {
   417       virtual const char* exceptionName() const { 
   417       virtual const char* exceptionName() const { 
   418 	return "lemon::FullUBipartiteGraph::NodeSetError";
   418 	return "lemon::FullBpUGraph::NodeSetError";
   419       }
   419       }
   420     };
   420     };
   421   
   421   
   422     class Node {
   422     class Node {
   423       friend class FullUBipartiteGraphBase;
   423       friend class FullBpUGraphBase;
   424     protected:
   424     protected:
   425       int id;
   425       int id;
   426 
   426 
   427       Node(int _id) : id(_id) {}
   427       Node(int _id) : id(_id) {}
   428     public:
   428     public:
   432       bool operator!=(const Node i) const {return id!=i.id;}
   432       bool operator!=(const Node i) const {return id!=i.id;}
   433       bool operator<(const Node i) const {return id<i.id;}
   433       bool operator<(const Node i) const {return id<i.id;}
   434     };
   434     };
   435 
   435 
   436     class Edge {
   436     class Edge {
   437       friend class FullUBipartiteGraphBase;
   437       friend class FullBpUGraphBase;
   438     protected:
   438     protected:
   439       int id;
   439       int id;
   440 
   440 
   441       Edge(int _id) { id = _id;}
   441       Edge(int _id) { id = _id;}
   442     public:
   442     public:
   445       bool operator==(const Edge i) const {return id==i.id;}
   445       bool operator==(const Edge i) const {return id==i.id;}
   446       bool operator!=(const Edge i) const {return id!=i.id;}
   446       bool operator!=(const Edge i) const {return id!=i.id;}
   447       bool operator<(const Edge i) const {return id<i.id;}
   447       bool operator<(const Edge i) const {return id<i.id;}
   448     };
   448     };
   449 
   449 
   450     void construct(int upperNodeNum, int lowerNodeNum) {
   450     void construct(int aNodeNum, int bNodeNum) {
   451       _upperNodeNum = upperNodeNum;
   451       _aNodeNum = aNodeNum;
   452       _lowerNodeNum = lowerNodeNum;
   452       _bNodeNum = bNodeNum;
   453       _edgeNum = upperNodeNum * lowerNodeNum;
   453       _edgeNum = aNodeNum * bNodeNum;
   454     }
   454     }
   455 
   455 
   456     void firstUpper(Node& node) const {
   456     void firstANode(Node& node) const {
   457       node.id = 2 * _upperNodeNum - 2;
   457       node.id = 2 * _aNodeNum - 2;
   458       if (node.id < 0) node.id = -1; 
   458       if (node.id < 0) node.id = -1; 
   459     }
   459     }
   460     void nextUpper(Node& node) const {
   460     void nextANode(Node& node) const {
   461       node.id -= 2;
   461       node.id -= 2;
   462       if (node.id < 0) node.id = -1; 
   462       if (node.id < 0) node.id = -1; 
   463     }
   463     }
   464 
   464 
   465     void firstLower(Node& node) const {
   465     void firstBNode(Node& node) const {
   466       node.id = 2 * _lowerNodeNum - 1;
   466       node.id = 2 * _bNodeNum - 1;
   467     }
   467     }
   468     void nextLower(Node& node) const {
   468     void nextBNode(Node& node) const {
   469       node.id -= 2;
   469       node.id -= 2;
   470     }
   470     }
   471 
   471 
   472     void first(Node& node) const {
   472     void first(Node& node) const {
   473       if (_upperNodeNum > 0) {
   473       if (_aNodeNum > 0) {
   474 	node.id = 2 * _upperNodeNum - 2;
   474 	node.id = 2 * _aNodeNum - 2;
   475       } else {
   475       } else {
   476 	node.id = 2 * _lowerNodeNum - 1;
   476 	node.id = 2 * _bNodeNum - 1;
   477       }
   477       }
   478     }
   478     }
   479     void next(Node& node) const {
   479     void next(Node& node) const {
   480       node.id -= 2;
   480       node.id -= 2;
   481       if (node.id == -2) {
   481       if (node.id == -2) {
   482 	node.id = 2 * _lowerNodeNum - 1;
   482 	node.id = 2 * _bNodeNum - 1;
   483       }
   483       }
   484     }
   484     }
   485   
   485   
   486     void first(Edge& edge) const {
   486     void first(Edge& edge) const {
   487       edge.id = _edgeNum - 1;
   487       edge.id = _edgeNum - 1;
   488     }
   488     }
   489     void next(Edge& edge) const {
   489     void next(Edge& edge) const {
   490       --edge.id;
   490       --edge.id;
   491     }
   491     }
   492 
   492 
   493     void firstDown(Edge& edge, const Node& node) const {
   493     void firstOut(Edge& edge, const Node& node) const {
   494       LEMON_ASSERT((node.id & 1) == 0, NodeSetError());
   494       LEMON_ASSERT((node.id & 1) == 0, NodeSetError());
   495       edge.id = (node.id >> 1) * _lowerNodeNum;
   495       edge.id = (node.id >> 1) * _bNodeNum;
   496     }
   496     }
   497     void nextDown(Edge& edge) const {
   497     void nextOut(Edge& edge) const {
   498       ++(edge.id);
   498       ++(edge.id);
   499       if (edge.id % _lowerNodeNum == 0) edge.id = -1;
   499       if (edge.id % _bNodeNum == 0) edge.id = -1;
   500     }
   500     }
   501 
   501 
   502     void firstUp(Edge& edge, const Node& node) const {
   502     void firstIn(Edge& edge, const Node& node) const {
   503       LEMON_ASSERT((node.id & 1) == 1, NodeSetError());
   503       LEMON_ASSERT((node.id & 1) == 1, NodeSetError());
   504       edge.id = (node.id >> 1);
   504       edge.id = (node.id >> 1);
   505     }
   505     }
   506     void nextUp(Edge& edge) const {
   506     void nextIn(Edge& edge) const {
   507       edge.id += _lowerNodeNum;
   507       edge.id += _bNodeNum;
   508       if (edge.id >= _edgeNum) edge.id = -1;
   508       if (edge.id >= _edgeNum) edge.id = -1;
   509     }
   509     }
   510 
   510 
   511     static int id(const Node& node) {
   511     static int id(const Node& node) {
   512       return node.id;
   512       return node.id;
   513     }
   513     }
   514     static Node nodeFromId(int id) {
   514     static Node nodeFromId(int id) {
   515       return Node(id);
   515       return Node(id);
   516     }
   516     }
   517     int maxNodeId() const {
   517     int maxNodeId() const {
   518       return _upperNodeNum > _lowerNodeNum ? 
   518       return _aNodeNum > _bNodeNum ? 
   519 	_upperNodeNum * 2 - 2 : _lowerNodeNum * 2 - 1;
   519 	_aNodeNum * 2 - 2 : _bNodeNum * 2 - 1;
   520     }
   520     }
   521   
   521   
   522     static int id(const Edge& edge) {
   522     static int id(const Edge& edge) {
   523       return edge.id;
   523       return edge.id;
   524     }
   524     }
   527     }
   527     }
   528     int maxEdgeId() const {
   528     int maxEdgeId() const {
   529       return _edgeNum - 1;
   529       return _edgeNum - 1;
   530     }
   530     }
   531   
   531   
   532     static int upperId(const Node& node) {
   532     static int aNodeId(const Node& node) {
   533       return node.id >> 1;
   533       return node.id >> 1;
   534     }
   534     }
   535     static Node fromUpperId(int id, Node) {
   535     static Node fromANodeId(int id, Node) {
   536       return Node(id << 1);
   536       return Node(id << 1);
   537     }
   537     }
   538     int maxUpperId() const {
   538     int maxANodeId() const {
   539       return _upperNodeNum;
   539       return _aNodeNum;
   540     }
   540     }
   541 
   541 
   542     static int lowerId(const Node& node) {
   542     static int bNodeId(const Node& node) {
   543       return node.id >> 1;
   543       return node.id >> 1;
   544     }
   544     }
   545     static Node fromLowerId(int id) {
   545     static Node fromBNodeId(int id) {
   546       return Node((id << 1) + 1);
   546       return Node((id << 1) + 1);
   547     }
   547     }
   548     int maxLowerId() const {
   548     int maxBNodeId() const {
   549       return _lowerNodeNum;
   549       return _bNodeNum;
   550     }
   550     }
   551 
   551 
   552     Node upperNode(const Edge& edge) const {
   552     Node aNode(const Edge& edge) const {
   553       return Node((edge.id / _lowerNodeNum) << 1);
   553       return Node((edge.id / _bNodeNum) << 1);
   554     }
   554     }
   555     Node lowerNode(const Edge& edge) const {
   555     Node bNode(const Edge& edge) const {
   556       return Node(((edge.id % _lowerNodeNum) << 1) + 1);
   556       return Node(((edge.id % _bNodeNum) << 1) + 1);
   557     }
   557     }
   558 
   558 
   559     static bool upper(const Node& node) {
   559     static bool aNode(const Node& node) {
   560       return (node.id & 1) == 0;
   560       return (node.id & 1) == 0;
   561     }
   561     }
   562 
   562 
   563     static bool lower(const Node& node) {
   563     static bool bNode(const Node& node) {
   564       return (node.id & 1) == 1;
   564       return (node.id & 1) == 1;
   565     }
   565     }
   566 
   566 
   567     static Node upperNode(int index) {
   567     static Node aNode(int index) {
   568       return Node(index << 1);
   568       return Node(index << 1);
   569     }
   569     }
   570 
   570 
   571     static Node lowerNode(int index) {
   571     static Node bNode(int index) {
   572       return Node((index << 1) + 1);
   572       return Node((index << 1) + 1);
   573     }
   573     }
   574 
   574 
   575   };
   575   };
   576 
   576 
   577 
   577 
   578   typedef StaticMappableUBipartiteGraphExtender<
   578   typedef StaticMappableBpUGraphExtender<
   579     IterableUBipartiteGraphExtender<
   579     IterableBpUGraphExtender<
   580     AlterableUBipartiteGraphExtender<
   580     AlterableBpUGraphExtender<
   581     UBipartiteGraphExtender <
   581     BpUGraphExtender <
   582     FullUBipartiteGraphBase> > > >
   582     FullBpUGraphBase> > > >
   583   ExtendedFullUBipartiteGraphBase;
   583   ExtendedFullBpUGraphBase;
   584 
   584 
   585 
   585 
   586   class FullUBipartiteGraph : 
   586   /// \ingroup graphs
   587     public ExtendedFullUBipartiteGraphBase {
   587   ///
   588   public:
   588   /// \brief An undirected full bipartite graph class.
   589     typedef ExtendedFullUBipartiteGraphBase Parent;
   589   ///
   590     FullUBipartiteGraph(int upperNodeNum, int lowerNodeNum) {
   590   /// This is a simple and fast bipartite undirected full graph implementation.
   591       Parent::construct(upperNodeNum, lowerNodeNum);
   591   /// It is completely static, so you can neither add nor delete either
       
   592   /// edges or nodes.
       
   593   ///
       
   594   /// \sa FullGraph
       
   595   ///
       
   596   /// \author Balazs Dezso
       
   597   class FullBpUGraph : 
       
   598     public ExtendedFullBpUGraphBase {
       
   599   public:
       
   600     typedef ExtendedFullBpUGraphBase Parent;
       
   601     FullBpUGraph(int aNodeNum, int bNodeNum) {
       
   602       Parent::construct(aNodeNum, bNodeNum);
   592     }
   603     }
   593   };
   604   };
   594 
   605 
   595 } //namespace lemon
   606 } //namespace lemon
   596 
   607