lemon/full_graph.h
author hegyi
Mon, 21 Nov 2005 18:03:20 +0000
changeset 1823 cb082cdf3667
parent 1791 62e7d237e1fb
child 1828 fd3771591a5c
permissions -rw-r--r--
NewMapWin has become Dialog instead of Window. Therefore it is created dynamically, when there is need for it, instead of keeping one instance in memory. This solution is slower, but more correct than before.
     1 /* -*- C++ -*-
     2  * lemon/full_graph.h - Part of LEMON, a generic C++ optimization library
     3  *
     4  * Copyright (C) 2005 Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
     5  * (Egervary Research Group on Combinatorial Optimization, EGRES).
     6  *
     7  * Permission to use, modify and distribute this software is granted
     8  * provided that this copyright notice appears in all copies. For
     9  * precise terms see the accompanying LICENSE file.
    10  *
    11  * This software is provided "AS IS" with no warranty of any kind,
    12  * express or implied, and with no claim as to its suitability for any
    13  * purpose.
    14  *
    15  */
    16 
    17 #ifndef LEMON_FULL_GRAPH_H
    18 #define LEMON_FULL_GRAPH_H
    19 
    20 #include <cmath>
    21 
    22 
    23 #include <lemon/bits/iterable_graph_extender.h>
    24 #include <lemon/bits/alteration_notifier.h>
    25 #include <lemon/bits/static_map.h>
    26 #include <lemon/bits/graph_extender.h>
    27 
    28 #include <lemon/invalid.h>
    29 #include <lemon/utility.h>
    30 
    31 
    32 ///\ingroup graphs
    33 ///\file
    34 ///\brief FullGraph and UndirFullGraph 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 StaticMappableGraphExtender<
   193     IterableGraphExtender<
   194     AlterableGraphExtender<
   195     GraphExtender<FullGraphBase> > > > ExtendedFullGraphBase;
   196 
   197   /// \ingroup graphs
   198   ///
   199   /// \brief A full graph class.
   200   ///
   201   /// This is a simple and fast directed full graph implementation.
   202   /// It is completely static, so you can neither add nor delete either
   203   /// edges or nodes.
   204   /// Thus it conforms to
   205   /// the \ref concept::StaticGraph "StaticGraph" concept
   206   /// \sa concept::StaticGraph.
   207   ///
   208   /// \author Alpar Juttner
   209   class FullGraph : public ExtendedFullGraphBase {
   210   public:
   211 
   212     FullGraph(int n) { construct(n); }
   213   };
   214 
   215 
   216   class UndirFullGraphBase {
   217     int _nodeNum;
   218     int _edgeNum;
   219   public:
   220 
   221     typedef UndirFullGraphBase Graph;
   222 
   223     class Node;
   224     class Edge;
   225 
   226   public:
   227 
   228     UndirFullGraphBase() {}
   229 
   230 
   231     ///Creates a full graph with \c n nodes.
   232     void construct(int n) { _nodeNum = n; _edgeNum = n * (n - 1) / 2; }
   233     ///
   234     //    FullGraphBase(const FullGraphBase &_g)
   235     //      : _nodeNum(_g.nodeNum()), _edgeNum(_nodeNum*_nodeNum) { }
   236     
   237     typedef True NodeNumTag;
   238     typedef True EdgeNumTag;
   239 
   240     ///Number of nodes.
   241     int nodeNum() const { return _nodeNum; }
   242     ///Number of edges.
   243     int edgeNum() const { return _edgeNum; }
   244 
   245     /// Maximum node ID.
   246     
   247     /// Maximum node ID.
   248     ///\sa id(Node)
   249     int maxNodeId() const { return _nodeNum-1; }
   250     /// Maximum edge ID.
   251     
   252     /// Maximum edge ID.
   253     ///\sa id(Edge)
   254     int maxEdgeId() const { return _edgeNum-1; }
   255 
   256     Node source(Edge e) const { 
   257       /// \todo we may do it faster
   258       return Node(((int)sqrt((double)(1 + 8 * e.id)) + 1) / 2);
   259     }
   260 
   261     Node target(Edge e) const { 
   262       int source = ((int)sqrt((double)(1 + 8 * e.id)) + 1) / 2;;
   263       return Node(e.id - (source) * (source - 1) / 2);
   264     }
   265 
   266 
   267     /// Node ID.
   268     
   269     /// The ID of a valid Node is a nonnegative integer not greater than
   270     /// \ref maxNodeId(). The range of the ID's is not surely continuous
   271     /// and the greatest node ID can be actually less then \ref maxNodeId().
   272     ///
   273     /// The ID of the \ref INVALID node is -1.
   274     ///\return The ID of the node \c v. 
   275 
   276     static int id(Node v) { return v.id; }
   277     /// Edge ID.
   278     
   279     /// The ID of a valid Edge is a nonnegative integer not greater than
   280     /// \ref maxEdgeId(). The range of the ID's is not surely continuous
   281     /// and the greatest edge ID can be actually less then \ref maxEdgeId().
   282     ///
   283     /// The ID of the \ref INVALID edge is -1.
   284     ///\return The ID of the edge \c e. 
   285     static int id(Edge e) { return e.id; }
   286 
   287     /// Finds an edge between two nodes.
   288     
   289     /// Finds an edge from node \c u to node \c v.
   290     ///
   291     /// If \c prev is \ref INVALID (this is the default value), then
   292     /// It finds the first edge from \c u to \c v. Otherwise it looks for
   293     /// the next edge from \c u to \c v after \c prev.
   294     /// \return The found edge or INVALID if there is no such an edge.
   295     Edge findEdge(Node u, Node v, Edge prev = INVALID) const {
   296       if (prev.id != -1 || u.id <= v.id) return -1;
   297       return Edge(u.id * (u.id - 1) / 2 + v.id);
   298     }
   299 
   300     typedef True FindEdgeTag;
   301     
   302       
   303     class Node {
   304       friend class UndirFullGraphBase;
   305 
   306     protected:
   307       int id;
   308       Node(int _id) { id = _id;}
   309     public:
   310       Node() {}
   311       Node (Invalid) { id = -1; }
   312       bool operator==(const Node node) const {return id == node.id;}
   313       bool operator!=(const Node node) const {return id != node.id;}
   314       bool operator<(const Node node) const {return id < node.id;}
   315     };
   316     
   317 
   318 
   319     class Edge {
   320       friend class UndirFullGraphBase;
   321       
   322     protected:
   323       int id;  // _nodeNum * target + source;
   324 
   325       Edge(int _id) : id(_id) {}
   326 
   327     public:
   328       Edge() { }
   329       Edge (Invalid) { id = -1; }
   330       bool operator==(const Edge edge) const {return id == edge.id;}
   331       bool operator!=(const Edge edge) const {return id != edge.id;}
   332       bool operator<(const Edge edge) const {return id < edge.id;}
   333     };
   334 
   335     void first(Node& node) const {
   336       node.id = _nodeNum - 1;
   337     }
   338 
   339     static void next(Node& node) {
   340       --node.id;
   341     }
   342 
   343     void first(Edge& edge) const {
   344       edge.id = _edgeNum - 1;
   345     }
   346 
   347     static void next(Edge& edge) {
   348       --edge.id;
   349     }
   350 
   351     void firstOut(Edge& edge, const Node& node) const {      
   352       int src = node.id;
   353       int trg = 0;
   354       edge.id = (trg < src ? src * (src - 1) / 2 + trg : -1);
   355     }
   356 
   357     /// \todo with specialized iterators we can make faster iterating
   358     void nextOut(Edge& edge) const {
   359       int src = source(edge).id;
   360       int trg = target(edge).id;
   361       ++trg;
   362       edge.id = (trg < src ? src * (src - 1) / 2 + trg : -1);
   363     }
   364 
   365     void firstIn(Edge& edge, const Node& node) const {
   366       int src = node.id + 1;
   367       int trg = node.id;
   368       edge.id = (src < _nodeNum ? src * (src - 1) / 2 + trg : -1);
   369     }
   370     
   371     void nextIn(Edge& edge) const {
   372       int src = source(edge).id;
   373       int trg = target(edge).id;
   374       ++src;
   375       edge.id = (src < _nodeNum ? src * (src - 1) / 2 + trg : -1);
   376     }
   377 
   378   };
   379 
   380   typedef StaticMappableUndirGraphExtender<
   381     IterableUndirGraphExtender<
   382     AlterableUndirGraphExtender<
   383     UndirGraphExtender<UndirFullGraphBase> > > > ExtendedUndirFullGraphBase;
   384 
   385   /// \ingroup graphs
   386   ///
   387   /// \brief An undirected full graph class.
   388   ///
   389   /// This is a simple and fast undirected full graph implementation.
   390   /// It is completely static, so you can neither add nor delete either
   391   /// edges or nodes.
   392   ///
   393   /// The main difference beetween the \e FullGraph and \e UndirFullGraph class
   394   /// is that this class conforms to the undirected graph concept and
   395   /// it does not contain the loop edges.
   396   ///
   397   /// \sa FullGraph
   398   ///
   399   /// \author Balazs Dezso
   400   class UndirFullGraph : public ExtendedUndirFullGraphBase {
   401   public:
   402     UndirFullGraph(int n) { construct(n); }
   403   };
   404 
   405 
   406   class FullUndirBipartiteGraphBase {
   407   protected:
   408 
   409     int _upperNodeNum;
   410     int _lowerNodeNum;
   411 
   412     int _edgeNum;
   413 
   414   public:
   415 
   416     class NodeSetError : public LogicError {
   417       virtual const char* exceptionName() const { 
   418 	return "lemon::FullUndirBipartiteGraph::NodeSetError";
   419       }
   420     };
   421   
   422     class Node {
   423       friend class FullUndirBipartiteGraphBase;
   424     protected:
   425       int id;
   426 
   427       Node(int _id) : id(_id) {}
   428     public:
   429       Node() {}
   430       Node(Invalid) { id = -1; }
   431       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;}
   434     };
   435 
   436     class Edge {
   437       friend class FullUndirBipartiteGraphBase;
   438     protected:
   439       int id;
   440 
   441       Edge(int _id) { id = _id;}
   442     public:
   443       Edge() {}
   444       Edge (Invalid) { id = -1; }
   445       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;}
   448     };
   449 
   450     void construct(int upperNodeNum, int lowerNodeNum) {
   451       _upperNodeNum = upperNodeNum;
   452       _lowerNodeNum = lowerNodeNum;
   453       _edgeNum = upperNodeNum * lowerNodeNum;
   454     }
   455 
   456     void firstUpper(Node& node) const {
   457       node.id = 2 * _upperNodeNum - 2;
   458       if (node.id < 0) node.id = -1; 
   459     }
   460     void nextUpper(Node& node) const {
   461       node.id -= 2;
   462       if (node.id < 0) node.id = -1; 
   463     }
   464 
   465     void firstLower(Node& node) const {
   466       node.id = 2 * _lowerNodeNum - 1;
   467     }
   468     void nextLower(Node& node) const {
   469       node.id -= 2;
   470     }
   471 
   472     void first(Node& node) const {
   473       if (_upperNodeNum > 0) {
   474 	node.id = 2 * _upperNodeNum - 2;
   475       } else {
   476 	node.id = 2 * _lowerNodeNum - 1;
   477       }
   478     }
   479     void next(Node& node) const {
   480       node.id -= 2;
   481       if (node.id == -2) {
   482 	node.id = 2 * _lowerNodeNum - 1;
   483       }
   484     }
   485   
   486     void first(Edge& edge) const {
   487       edge.id = _edgeNum - 1;
   488     }
   489     void next(Edge& edge) const {
   490       --edge.id;
   491     }
   492 
   493     void firstDown(Edge& edge, const Node& node) const {
   494       LEMON_ASSERT((node.id & 1) == 0, NodeSetError());
   495       edge.id = (node.id >> 1) * _lowerNodeNum;
   496     }
   497     void nextDown(Edge& edge) const {
   498       ++(edge.id);
   499       if (edge.id % _lowerNodeNum == 0) edge.id = -1;
   500     }
   501 
   502     void firstUp(Edge& edge, const Node& node) const {
   503       LEMON_ASSERT((node.id & 1) == 1, NodeSetError());
   504       edge.id = (node.id >> 1);
   505     }
   506     void nextUp(Edge& edge) const {
   507       edge.id += _lowerNodeNum;
   508       if (edge.id >= _edgeNum) edge.id = -1;
   509     }
   510 
   511     static int id(const Node& node) {
   512       return node.id;
   513     }
   514     static Node nodeFromId(int id) {
   515       return Node(id);
   516     }
   517     int maxNodeId() const {
   518       return _upperNodeNum > _lowerNodeNum ? 
   519 	_upperNodeNum * 2 - 2 : _lowerNodeNum * 2 - 1;
   520     }
   521   
   522     static int id(const Edge& edge) {
   523       return edge.id;
   524     }
   525     static Edge edgeFromId(int id) {
   526       return Edge(id);
   527     }
   528     int maxEdgeId() const {
   529       return _edgeNum - 1;
   530     }
   531   
   532     static int upperId(const Node& node) {
   533       return node.id >> 1;
   534     }
   535     static Node fromUpperId(int id, Node) {
   536       return Node(id << 1);
   537     }
   538     int maxUpperId() const {
   539       return _upperNodeNum;
   540     }
   541 
   542     static int lowerId(const Node& node) {
   543       return node.id >> 1;
   544     }
   545     static Node fromLowerId(int id) {
   546       return Node((id << 1) + 1);
   547     }
   548     int maxLowerId() const {
   549       return _lowerNodeNum;
   550     }
   551 
   552     Node upperNode(const Edge& edge) const {
   553       return Node((edge.id / _lowerNodeNum) << 1);
   554     }
   555     Node lowerNode(const Edge& edge) const {
   556       return Node(((edge.id % _lowerNodeNum) << 1) + 1);
   557     }
   558 
   559     static bool upper(const Node& node) {
   560       return (node.id & 1) == 0;
   561     }
   562 
   563     static bool lower(const Node& node) {
   564       return (node.id & 1) == 1;
   565     }
   566 
   567     static Node upperNode(int index) {
   568       return Node(index << 1);
   569     }
   570 
   571     static Node lowerNode(int index) {
   572       return Node((index << 1) + 1);
   573     }
   574 
   575   };
   576 
   577 
   578   typedef MappableUndirBipartiteGraphExtender<
   579     IterableUndirBipartiteGraphExtender<
   580     AlterableUndirBipartiteGraphExtender<
   581     UndirBipartiteGraphExtender <
   582     FullUndirBipartiteGraphBase> > > >
   583   ExtendedFullUndirBipartiteGraphBase;
   584 
   585 
   586   class FullUndirBipartiteGraph : 
   587     public ExtendedFullUndirBipartiteGraphBase {
   588   public:
   589     typedef ExtendedFullUndirBipartiteGraphBase Parent;
   590     FullUndirBipartiteGraph(int upperNodeNum, int lowerNodeNum) {
   591       Parent::construct(upperNodeNum, lowerNodeNum);
   592     }
   593   };
   594 
   595 } //namespace lemon
   596 
   597 
   598 #endif //LEMON_FULL_GRAPH_H