lemon/full_graph.h
author deba
Mon, 27 Feb 2006 10:17:33 +0000
changeset 1985 8782ff6fd98a
parent 1956 a055123339d5
child 1986 9b56cca61e2e
permissions -rw-r--r--
Bug fix
     1 /* -*- C++ -*-
     2  *
     3  * This file is a part of LEMON, a generic C++ optimization library
     4  *
     5  * Copyright (C) 2003-2006
     6  * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
     7  * (Egervary Research Group on Combinatorial Optimization, EGRES).
     8  *
     9  * Permission to use, modify and distribute this software is granted
    10  * provided that this copyright notice appears in all copies. For
    11  * precise terms see the accompanying LICENSE file.
    12  *
    13  * This software is provided "AS IS" with no warranty of any kind,
    14  * express or implied, and with no claim as to its suitability for any
    15  * purpose.
    16  *
    17  */
    18 
    19 #ifndef LEMON_FULL_GRAPH_H
    20 #define LEMON_FULL_GRAPH_H
    21 
    22 #include <cmath>
    23 
    24 
    25 #include <lemon/bits/graph_extender.h>
    26 
    27 
    28 #include <lemon/invalid.h>
    29 #include <lemon/utility.h>
    30 
    31 
    32 ///\ingroup graphs
    33 ///\file
    34 ///\brief FullGraph and FullUGraph classes.
    35 
    36 
    37 namespace lemon {
    38 
    39   class FullGraphBase {
    40     int _nodeNum;
    41     int _edgeNum;
    42   public:
    43 
    44     typedef FullGraphBase Graph;
    45 
    46     class Node;
    47     class Edge;
    48 
    49   public:
    50 
    51     FullGraphBase() {}
    52 
    53 
    54     ///Creates a full graph with \c n nodes.
    55     void construct(int n) { _nodeNum = n; _edgeNum = n * n; }
    56     ///
    57     //    FullGraphBase(const FullGraphBase &_g)
    58     //      : _nodeNum(_g.nodeNum()), _edgeNum(_nodeNum*_nodeNum) { }
    59     
    60     typedef True NodeNumTag;
    61     typedef True EdgeNumTag;
    62 
    63     ///Number of nodes.
    64     int nodeNum() const { return _nodeNum; }
    65     ///Number of edges.
    66     int edgeNum() const { return _edgeNum; }
    67 
    68     /// Maximum node ID.
    69     
    70     /// Maximum node ID.
    71     ///\sa id(Node)
    72     int maxNodeId() const { return _nodeNum-1; }
    73     /// Maximum edge ID.
    74     
    75     /// Maximum edge ID.
    76     ///\sa id(Edge)
    77     int maxEdgeId() const { return _edgeNum-1; }
    78 
    79     Node source(Edge e) const { return e.id % _nodeNum; }
    80     Node target(Edge e) const { return e.id / _nodeNum; }
    81 
    82 
    83     /// Node ID.
    84     
    85     /// The ID of a valid Node is a nonnegative integer not greater than
    86     /// \ref maxNodeId(). The range of the ID's is not surely continuous
    87     /// and the greatest node ID can be actually less then \ref maxNodeId().
    88     ///
    89     /// The ID of the \ref INVALID node is -1.
    90     ///\return The ID of the node \c v. 
    91 
    92     static int id(Node v) { return v.id; }
    93     /// Edge ID.
    94     
    95     /// The ID of a valid Edge is a nonnegative integer not greater than
    96     /// \ref maxEdgeId(). The range of the ID's is not surely continuous
    97     /// and the greatest edge ID can be actually less then \ref maxEdgeId().
    98     ///
    99     /// The ID of the \ref INVALID edge is -1.
   100     ///\return The ID of the edge \c e. 
   101     static int id(Edge e) { return e.id; }
   102 
   103     static Node nodeFromId(int id) { return Node(id);}
   104     
   105     static Edge edgeFromId(int id) { return Edge(id);}
   106 
   107     typedef True FindEdgeTag;
   108 
   109     /// Finds an edge between two nodes.
   110     
   111     /// Finds an edge from node \c u to node \c v.
   112     ///
   113     /// If \c prev is \ref INVALID (this is the default value), then
   114     /// It finds the first edge from \c u to \c v. Otherwise it looks for
   115     /// the next edge from \c u to \c v after \c prev.
   116     /// \return The found edge or INVALID if there is no such an edge.
   117     Edge findEdge(Node u,Node v, Edge prev = INVALID) const {
   118       return prev.id == -1 ? Edge(*this, u.id, v.id) : INVALID;
   119     }
   120     
   121       
   122     class Node {
   123       friend class FullGraphBase;
   124 
   125     protected:
   126       int id;
   127       Node(int _id) : id(_id) {}
   128     public:
   129       Node() {}
   130       Node (Invalid) : id(-1) {}
   131       bool operator==(const Node node) const {return id == node.id;}
   132       bool operator!=(const Node node) const {return id != node.id;}
   133       bool operator<(const Node node) const {return id < node.id;}
   134     };
   135     
   136 
   137 
   138     class Edge {
   139       friend class FullGraphBase;
   140       
   141     protected:
   142       int id;  // _nodeNum * target + source;
   143 
   144       Edge(int _id) : id(_id) {}
   145 
   146       Edge(const FullGraphBase& _graph, int source, int target) 
   147 	: id(_graph._nodeNum * target+source) {}
   148     public:
   149       Edge() { }
   150       Edge (Invalid) { id = -1; }
   151       bool operator==(const Edge edge) const {return id == edge.id;}
   152       bool operator!=(const Edge edge) const {return id != edge.id;}
   153       bool operator<(const Edge edge) const {return id < edge.id;}
   154     };
   155 
   156     void first(Node& node) const {
   157       node.id = _nodeNum-1;
   158     }
   159 
   160     static void next(Node& node) {
   161       --node.id;
   162     }
   163 
   164     void first(Edge& edge) const {
   165       edge.id = _edgeNum-1;
   166     }
   167 
   168     static void next(Edge& edge) {
   169       --edge.id;
   170     }
   171 
   172     void firstOut(Edge& edge, const Node& node) const {
   173       edge.id = _edgeNum + node.id - _nodeNum;
   174     }
   175 
   176     void nextOut(Edge& edge) const {
   177       edge.id -= _nodeNum;
   178       if (edge.id < 0) edge.id = -1;
   179     }
   180 
   181     void firstIn(Edge& edge, const Node& node) const {
   182       edge.id = node.id * _nodeNum;
   183     }
   184     
   185     void nextIn(Edge& edge) const {
   186       ++edge.id;
   187       if (edge.id % _nodeNum == 0) edge.id = -1;
   188     }
   189 
   190   };
   191 
   192   typedef GraphExtender<FullGraphBase> ExtendedFullGraphBase;
   193 
   194   /// \ingroup graphs
   195   ///
   196   /// \brief A full graph class.
   197   ///
   198   /// This is a simple and fast directed full graph implementation.
   199   /// It is completely static, so you can neither add nor delete either
   200   /// edges or nodes.
   201   /// Thus it conforms to
   202   /// the \ref concept::StaticGraph "StaticGraph" concept
   203   /// \sa concept::StaticGraph.
   204   ///
   205   /// \author Alpar Juttner
   206   class FullGraph : public ExtendedFullGraphBase {
   207   public:
   208 
   209     typedef ExtendedFullGraphBase Parent;
   210 
   211     /// \brief Constructor
   212     ///
   213     FullGraph(int n) { construct(n); }
   214 
   215     /// \brief Resize the graph
   216     ///
   217     void resize(int n) {
   218       Parent::getNotifier(Edge()).clear();
   219       Parent::getNotifier(Node()).clear();
   220       construct(n);
   221       Parent::getNotifier(Node()).build();
   222       Parent::getNotifier(Edge()).build();
   223     }
   224   };
   225 
   226 
   227   class FullUGraphBase {
   228     int _nodeNum;
   229     int _edgeNum;
   230   public:
   231 
   232     typedef FullUGraphBase Graph;
   233 
   234     class Node;
   235     class Edge;
   236 
   237   public:
   238 
   239     FullUGraphBase() {}
   240 
   241 
   242     ///Creates a full graph with \c n nodes.
   243     void construct(int n) { _nodeNum = n; _edgeNum = n * (n - 1) / 2; }
   244     ///
   245     //    FullGraphBase(const FullGraphBase &_g)
   246     //      : _nodeNum(_g.nodeNum()), _edgeNum(_nodeNum*_nodeNum) { }
   247     
   248     typedef True NodeNumTag;
   249     typedef True EdgeNumTag;
   250 
   251     ///Number of nodes.
   252     int nodeNum() const { return _nodeNum; }
   253     ///Number of edges.
   254     int edgeNum() const { return _edgeNum; }
   255 
   256     /// Maximum node ID.
   257     
   258     /// Maximum node ID.
   259     ///\sa id(Node)
   260     int maxNodeId() const { return _nodeNum-1; }
   261     /// Maximum edge ID.
   262     
   263     /// Maximum edge ID.
   264     ///\sa id(Edge)
   265     int maxEdgeId() const { return _edgeNum-1; }
   266 
   267     Node source(Edge e) const { 
   268       /// \todo we may do it faster
   269       return Node(((int)sqrt((double)(1 + 8 * e.id)) + 1) / 2);
   270     }
   271 
   272     Node target(Edge e) const { 
   273       int source = ((int)sqrt((double)(1 + 8 * e.id)) + 1) / 2;;
   274       return Node(e.id - (source) * (source - 1) / 2);
   275     }
   276 
   277 
   278     /// Node ID.
   279     
   280     /// The ID of a valid Node is a nonnegative integer not greater than
   281     /// \ref maxNodeId(). The range of the ID's is not surely continuous
   282     /// and the greatest node ID can be actually less then \ref maxNodeId().
   283     ///
   284     /// The ID of the \ref INVALID node is -1.
   285     ///\return The ID of the node \c v. 
   286 
   287     static int id(Node v) { return v.id; }
   288     /// Edge ID.
   289     
   290     /// The ID of a valid Edge is a nonnegative integer not greater than
   291     /// \ref maxEdgeId(). The range of the ID's is not surely continuous
   292     /// and the greatest edge ID can be actually less then \ref maxEdgeId().
   293     ///
   294     /// The ID of the \ref INVALID edge is -1.
   295     ///\return The ID of the edge \c e. 
   296     static int id(Edge e) { return e.id; }
   297 
   298     /// Finds an edge between two nodes.
   299     
   300     /// Finds an edge from node \c u to node \c v.
   301     ///
   302     /// If \c prev is \ref INVALID (this is the default value), then
   303     /// It finds the first edge from \c u to \c v. Otherwise it looks for
   304     /// the next edge from \c u to \c v after \c prev.
   305     /// \return The found edge or INVALID if there is no such an edge.
   306     Edge findEdge(Node u, Node v, Edge prev = INVALID) const {
   307       if (prev.id != -1 || u.id <= v.id) return -1;
   308       return Edge(u.id * (u.id - 1) / 2 + v.id);
   309     }
   310 
   311     typedef True FindEdgeTag;
   312     
   313       
   314     class Node {
   315       friend class FullUGraphBase;
   316 
   317     protected:
   318       int id;
   319       Node(int _id) { id = _id;}
   320     public:
   321       Node() {}
   322       Node (Invalid) { id = -1; }
   323       bool operator==(const Node node) const {return id == node.id;}
   324       bool operator!=(const Node node) const {return id != node.id;}
   325       bool operator<(const Node node) const {return id < node.id;}
   326     };
   327     
   328 
   329 
   330     class Edge {
   331       friend class FullUGraphBase;
   332       
   333     protected:
   334       int id;  // _nodeNum * target + source;
   335 
   336       Edge(int _id) : id(_id) {}
   337 
   338     public:
   339       Edge() { }
   340       Edge (Invalid) { id = -1; }
   341       bool operator==(const Edge edge) const {return id == edge.id;}
   342       bool operator!=(const Edge edge) const {return id != edge.id;}
   343       bool operator<(const Edge edge) const {return id < edge.id;}
   344     };
   345 
   346     void first(Node& node) const {
   347       node.id = _nodeNum - 1;
   348     }
   349 
   350     static void next(Node& node) {
   351       --node.id;
   352     }
   353 
   354     void first(Edge& edge) const {
   355       edge.id = _edgeNum - 1;
   356     }
   357 
   358     static void next(Edge& edge) {
   359       --edge.id;
   360     }
   361 
   362     void firstOut(Edge& edge, const Node& node) const {      
   363       int src = node.id;
   364       int trg = 0;
   365       edge.id = (trg < src ? src * (src - 1) / 2 + trg : -1);
   366     }
   367 
   368     /// \todo with specialized iterators we can make faster iterating
   369     void nextOut(Edge& edge) const {
   370       int src = source(edge).id;
   371       int trg = target(edge).id;
   372       ++trg;
   373       edge.id = (trg < src ? src * (src - 1) / 2 + trg : -1);
   374     }
   375 
   376     void firstIn(Edge& edge, const Node& node) const {
   377       int src = node.id + 1;
   378       int trg = node.id;
   379       edge.id = (src < _nodeNum ? src * (src - 1) / 2 + trg : -1);
   380     }
   381     
   382     void nextIn(Edge& edge) const {
   383       int src = source(edge).id;
   384       int trg = target(edge).id;
   385       ++src;
   386       edge.id = (src < _nodeNum ? src * (src - 1) / 2 + trg : -1);
   387     }
   388 
   389   };
   390 
   391   typedef UGraphExtender<UGraphBaseExtender<FullUGraphBase> > 
   392   ExtendedFullUGraphBase;
   393 
   394   /// \ingroup graphs
   395   ///
   396   /// \brief An undirected full graph class.
   397   ///
   398   /// This is a simple and fast undirected full graph implementation.
   399   /// It is completely static, so you can neither add nor delete either
   400   /// edges or nodes.
   401   ///
   402   /// The main difference beetween the \e FullGraph and \e FullUGraph class
   403   /// is that this class conforms to the undirected graph concept and
   404   /// it does not contain the loop edges.
   405   ///
   406   /// \sa FullGraph
   407   ///
   408   /// \author Balazs Dezso
   409   class FullUGraph : public ExtendedFullUGraphBase {
   410   public:
   411 
   412     typedef ExtendedFullUGraphBase Parent;
   413 
   414     /// \brief Constructor
   415     FullUGraph(int n) { construct(n); }
   416 
   417     /// \brief Resize the graph
   418     ///
   419     void resize(int n) {
   420       Parent::getNotifier(Edge()).clear();
   421       Parent::getNotifier(UEdge()).clear();
   422       Parent::getNotifier(Node()).clear();
   423       construct(n);
   424       Parent::getNotifier(Node()).build();
   425       Parent::getNotifier(UEdge()).build();
   426       Parent::getNotifier(Edge()).build();
   427     }
   428   };
   429 
   430 
   431   class FullBpUGraphBase {
   432   protected:
   433 
   434     int _aNodeNum;
   435     int _bNodeNum;
   436 
   437     int _edgeNum;
   438 
   439   public:
   440 
   441     class NodeSetError : public LogicError {
   442       virtual const char* exceptionName() const { 
   443 	return "lemon::FullBpUGraph::NodeSetError";
   444       }
   445     };
   446   
   447     class Node {
   448       friend class FullBpUGraphBase;
   449     protected:
   450       int id;
   451 
   452       Node(int _id) : id(_id) {}
   453     public:
   454       Node() {}
   455       Node(Invalid) { id = -1; }
   456       bool operator==(const Node i) const {return id==i.id;}
   457       bool operator!=(const Node i) const {return id!=i.id;}
   458       bool operator<(const Node i) const {return id<i.id;}
   459     };
   460 
   461     class Edge {
   462       friend class FullBpUGraphBase;
   463     protected:
   464       int id;
   465 
   466       Edge(int _id) { id = _id;}
   467     public:
   468       Edge() {}
   469       Edge (Invalid) { id = -1; }
   470       bool operator==(const Edge i) const {return id==i.id;}
   471       bool operator!=(const Edge i) const {return id!=i.id;}
   472       bool operator<(const Edge i) const {return id<i.id;}
   473     };
   474 
   475     void construct(int aNodeNum, int bNodeNum) {
   476       _aNodeNum = aNodeNum;
   477       _bNodeNum = bNodeNum;
   478       _edgeNum = aNodeNum * bNodeNum;
   479     }
   480 
   481     void firstANode(Node& node) const {
   482       node.id = 2 * _aNodeNum - 2;
   483       if (node.id < 0) node.id = -1; 
   484     }
   485     void nextANode(Node& node) const {
   486       node.id -= 2;
   487       if (node.id < 0) node.id = -1; 
   488     }
   489 
   490     void firstBNode(Node& node) const {
   491       node.id = 2 * _bNodeNum - 1;
   492     }
   493     void nextBNode(Node& node) const {
   494       node.id -= 2;
   495     }
   496 
   497     void first(Node& node) const {
   498       if (_aNodeNum > 0) {
   499 	node.id = 2 * _aNodeNum - 2;
   500       } else {
   501 	node.id = 2 * _bNodeNum - 1;
   502       }
   503     }
   504     void next(Node& node) const {
   505       node.id -= 2;
   506       if (node.id == -2) {
   507 	node.id = 2 * _bNodeNum - 1;
   508       }
   509     }
   510   
   511     void first(Edge& edge) const {
   512       edge.id = _edgeNum - 1;
   513     }
   514     void next(Edge& edge) const {
   515       --edge.id;
   516     }
   517 
   518     void firstOut(Edge& edge, const Node& node) const {
   519       LEMON_ASSERT((node.id & 1) == 0, NodeSetError());
   520       edge.id = (node.id >> 1) * _bNodeNum;
   521     }
   522     void nextOut(Edge& edge) const {
   523       ++(edge.id);
   524       if (edge.id % _bNodeNum == 0) edge.id = -1;
   525     }
   526 
   527     void firstIn(Edge& edge, const Node& node) const {
   528       LEMON_ASSERT((node.id & 1) == 1, NodeSetError());
   529       edge.id = (node.id >> 1);
   530     }
   531     void nextIn(Edge& edge) const {
   532       edge.id += _bNodeNum;
   533       if (edge.id >= _edgeNum) edge.id = -1;
   534     }
   535 
   536     static int id(const Node& node) {
   537       return node.id;
   538     }
   539     static Node nodeFromId(int id) {
   540       return Node(id);
   541     }
   542     int maxNodeId() const {
   543       return _aNodeNum > _bNodeNum ? 
   544 	_aNodeNum * 2 - 2 : _bNodeNum * 2 - 1;
   545     }
   546   
   547     static int id(const Edge& edge) {
   548       return edge.id;
   549     }
   550     static Edge edgeFromId(int id) {
   551       return Edge(id);
   552     }
   553     int maxEdgeId() const {
   554       return _edgeNum - 1;
   555     }
   556   
   557     static int aNodeId(const Node& node) {
   558       return node.id >> 1;
   559     }
   560     static Node fromANodeId(int id, Node) {
   561       return Node(id << 1);
   562     }
   563     int maxANodeId() const {
   564       return _aNodeNum;
   565     }
   566 
   567     static int bNodeId(const Node& node) {
   568       return node.id >> 1;
   569     }
   570     static Node fromBNodeId(int id) {
   571       return Node((id << 1) + 1);
   572     }
   573     int maxBNodeId() const {
   574       return _bNodeNum;
   575     }
   576 
   577     Node aNode(const Edge& edge) const {
   578       return Node((edge.id / _bNodeNum) << 1);
   579     }
   580     Node bNode(const Edge& edge) const {
   581       return Node(((edge.id % _bNodeNum) << 1) + 1);
   582     }
   583 
   584     static bool aNode(const Node& node) {
   585       return (node.id & 1) == 0;
   586     }
   587 
   588     static bool bNode(const Node& node) {
   589       return (node.id & 1) == 1;
   590     }
   591 
   592     static Node aNode(int index) {
   593       return Node(index << 1);
   594     }
   595 
   596     static Node bNode(int index) {
   597       return Node((index << 1) + 1);
   598     }
   599 
   600   };
   601 
   602 
   603   typedef BpUGraphExtender< BpUGraphBaseExtender<
   604     FullBpUGraphBase> > ExtendedFullBpUGraphBase;
   605 
   606 
   607   /// \ingroup graphs
   608   ///
   609   /// \brief An undirected full bipartite graph class.
   610   ///
   611   /// This is a simple and fast bipartite undirected full graph implementation.
   612   /// It is completely static, so you can neither add nor delete either
   613   /// edges or nodes.
   614   ///
   615   /// \sa FullGraph
   616   ///
   617   /// \author Balazs Dezso
   618   class FullBpUGraph : 
   619     public ExtendedFullBpUGraphBase {
   620   public:
   621 
   622     typedef ExtendedFullBpUGraphBase Parent;
   623 
   624     FullBpUGraph(int aNodeNum, int bNodeNum) {
   625       Parent::construct(aNodeNum, bNodeNum);
   626     }
   627     /// \brief Resize the graph
   628     ///
   629     void resize(int n, int m) {
   630       Parent::getNotifier(Edge()).clear();
   631       Parent::getNotifier(UEdge()).clear();
   632       Parent::getNotifier(Node()).clear();
   633       construct(n, m);
   634       Parent::getNotifier(Node()).build();
   635       Parent::getNotifier(UEdge()).build();
   636       Parent::getNotifier(Edge()).build();
   637     }
   638   };
   639 
   640 } //namespace lemon
   641 
   642 
   643 #endif //LEMON_FULL_GRAPH_H