COIN-OR::LEMON - Graph Library

source: lemon-0.x/lemon/full_graph.h @ 1978:ef2d00e46897

Last change on this file since 1978:ef2d00e46897 was 1956:a055123339d5, checked in by Alpar Juttner, 18 years ago

Unified copyright notices

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