lemon/full_graph.h
author deba
Tue, 21 Nov 2006 18:22:08 +0000
changeset 2306 42cce226b87b
parent 2256 b22dfb6c5ff3
child 2384 805c5a2a36dd
permissions -rw-r--r--
BfsVisitor
Bipartite partitions based on visitors

topology_demo.cc => scaleToA4 works without extra parameters
alpar@906
     1
/* -*- C++ -*-
alpar@906
     2
 *
alpar@1956
     3
 * This file is a part of LEMON, a generic C++ optimization library
alpar@1956
     4
 *
alpar@1956
     5
 * Copyright (C) 2003-2006
alpar@1956
     6
 * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
alpar@1359
     7
 * (Egervary Research Group on Combinatorial Optimization, EGRES).
alpar@906
     8
 *
alpar@906
     9
 * Permission to use, modify and distribute this software is granted
alpar@906
    10
 * provided that this copyright notice appears in all copies. For
alpar@906
    11
 * precise terms see the accompanying LICENSE file.
alpar@906
    12
 *
alpar@906
    13
 * This software is provided "AS IS" with no warranty of any kind,
alpar@906
    14
 * express or implied, and with no claim as to its suitability for any
alpar@906
    15
 * purpose.
alpar@906
    16
 *
alpar@906
    17
 */
alpar@591
    18
alpar@921
    19
#ifndef LEMON_FULL_GRAPH_H
alpar@921
    20
#define LEMON_FULL_GRAPH_H
alpar@591
    21
deba@983
    22
#include <cmath>
deba@983
    23
deba@2116
    24
#include <lemon/bits/base_extender.h>
deba@1791
    25
#include <lemon/bits/graph_extender.h>
deba@1566
    26
deba@1993
    27
#include <lemon/bits/invalid.h>
deba@1993
    28
#include <lemon/bits/utility.h>
klao@977
    29
klao@977
    30
alpar@591
    31
///\ingroup graphs
alpar@591
    32
///\file
deba@2116
    33
///\brief FullGraph and FullUGraph classes.
alpar@591
    34
alpar@591
    35
alpar@921
    36
namespace lemon {
alpar@591
    37
klao@946
    38
  class FullGraphBase {
deba@1566
    39
    int _nodeNum;
deba@1566
    40
    int _edgeNum;
alpar@591
    41
  public:
deba@782
    42
klao@946
    43
    typedef FullGraphBase Graph;
alpar@591
    44
alpar@591
    45
    class Node;
alpar@591
    46
    class Edge;
deba@782
    47
deba@2223
    48
  protected:
alpar@591
    49
klao@946
    50
    FullGraphBase() {}
klao@946
    51
deba@2223
    52
    void construct(int n) { _nodeNum = n; _edgeNum = n * n; }
klao@946
    53
deba@2223
    54
  public:
alpar@591
    55
    
klao@977
    56
    typedef True NodeNumTag;
klao@977
    57
    typedef True EdgeNumTag;
klao@977
    58
deba@1986
    59
    Node operator()(int index) const { return Node(index); }
deba@1986
    60
    int index(const Node& node) const { return node.id; }
deba@1986
    61
deba@2223
    62
    Edge edge(const Node& u, const Node& v) const { 
deba@2223
    63
      return Edge(*this, u.id, v.id); 
deba@2223
    64
    }
deba@2223
    65
deba@1566
    66
    int nodeNum() const { return _nodeNum; }
deba@1566
    67
    int edgeNum() const { return _edgeNum; }
alpar@591
    68
deba@1791
    69
    int maxNodeId() const { return _nodeNum-1; }
deba@1791
    70
    int maxEdgeId() const { return _edgeNum-1; }
alpar@591
    71
deba@1566
    72
    Node source(Edge e) const { return e.id % _nodeNum; }
deba@1566
    73
    Node target(Edge e) const { return e.id / _nodeNum; }
alpar@591
    74
alpar@591
    75
klao@946
    76
    static int id(Node v) { return v.id; }
klao@946
    77
    static int id(Edge e) { return e.id; }
alpar@591
    78
deba@1791
    79
    static Node nodeFromId(int id) { return Node(id);}
deba@1106
    80
    
deba@1791
    81
    static Edge edgeFromId(int id) { return Edge(id);}
deba@1106
    82
deba@1566
    83
    typedef True FindEdgeTag;
deba@1566
    84
deba@1566
    85
    Edge findEdge(Node u,Node v, Edge prev = INVALID) const {
klao@946
    86
      return prev.id == -1 ? Edge(*this, u.id, v.id) : INVALID;
alpar@774
    87
    }
alpar@774
    88
    
alpar@774
    89
      
alpar@591
    90
    class Node {
klao@946
    91
      friend class FullGraphBase;
alpar@591
    92
alpar@591
    93
    protected:
klao@946
    94
      int id;
alpar@1643
    95
      Node(int _id) : id(_id) {}
alpar@591
    96
    public:
alpar@591
    97
      Node() {}
alpar@1643
    98
      Node (Invalid) : id(-1) {}
klao@946
    99
      bool operator==(const Node node) const {return id == node.id;}
klao@946
   100
      bool operator!=(const Node node) const {return id != node.id;}
klao@946
   101
      bool operator<(const Node node) const {return id < node.id;}
alpar@591
   102
    };
alpar@591
   103
    
klao@946
   104
klao@946
   105
klao@946
   106
    class Edge {
klao@946
   107
      friend class FullGraphBase;
klao@946
   108
      
klao@946
   109
    protected:
deba@1566
   110
      int id;  // _nodeNum * target + source;
klao@946
   111
klao@946
   112
      Edge(int _id) : id(_id) {}
klao@946
   113
alpar@986
   114
      Edge(const FullGraphBase& _graph, int source, int target) 
deba@1566
   115
	: id(_graph._nodeNum * target+source) {}
alpar@591
   116
    public:
klao@946
   117
      Edge() { }
klao@946
   118
      Edge (Invalid) { id = -1; }
klao@946
   119
      bool operator==(const Edge edge) const {return id == edge.id;}
klao@946
   120
      bool operator!=(const Edge edge) const {return id != edge.id;}
klao@946
   121
      bool operator<(const Edge edge) const {return id < edge.id;}
alpar@591
   122
    };
alpar@591
   123
klao@946
   124
    void first(Node& node) const {
deba@1566
   125
      node.id = _nodeNum-1;
klao@946
   126
    }
alpar@591
   127
klao@946
   128
    static void next(Node& node) {
klao@946
   129
      --node.id;
klao@946
   130
    }
klao@946
   131
klao@946
   132
    void first(Edge& edge) const {
deba@1566
   133
      edge.id = _edgeNum-1;
klao@946
   134
    }
klao@946
   135
klao@946
   136
    static void next(Edge& edge) {
klao@946
   137
      --edge.id;
klao@946
   138
    }
klao@946
   139
klao@946
   140
    void firstOut(Edge& edge, const Node& node) const {
deba@1566
   141
      edge.id = _edgeNum + node.id - _nodeNum;
klao@946
   142
    }
klao@946
   143
klao@946
   144
    void nextOut(Edge& edge) const {
deba@1566
   145
      edge.id -= _nodeNum;
klao@946
   146
      if (edge.id < 0) edge.id = -1;
klao@946
   147
    }
klao@946
   148
klao@946
   149
    void firstIn(Edge& edge, const Node& node) const {
deba@1566
   150
      edge.id = node.id * _nodeNum;
klao@946
   151
    }
alpar@591
   152
    
klao@946
   153
    void nextIn(Edge& edge) const {
klao@946
   154
      ++edge.id;
deba@1566
   155
      if (edge.id % _nodeNum == 0) edge.id = -1;
klao@946
   156
    }
alpar@591
   157
alpar@591
   158
  };
alpar@591
   159
deba@1979
   160
  typedef GraphExtender<FullGraphBase> ExtendedFullGraphBase;
klao@946
   161
deba@1566
   162
  /// \ingroup graphs
alpar@951
   163
  ///
deba@1566
   164
  /// \brief A full graph class.
deba@1566
   165
  ///
deba@1566
   166
  /// This is a simple and fast directed full graph implementation.
deba@1566
   167
  /// It is completely static, so you can neither add nor delete either
deba@1566
   168
  /// edges or nodes.
deba@1566
   169
  /// Thus it conforms to
alpar@2260
   170
  /// the \ref concepts::Graph "Graph" concept and
alpar@2256
   171
  ///it also has an
alpar@2256
   172
  ///important extra feature that
alpar@2260
   173
  ///its maps are real \ref concepts::ReferenceMap "reference map"s.
alpar@2260
   174
  /// \sa concepts::Graph.
deba@1566
   175
  ///
deba@1986
   176
  /// \sa FullUGraph
deba@1986
   177
  ///
deba@1566
   178
  /// \author Alpar Juttner
deba@1669
   179
  class FullGraph : public ExtendedFullGraphBase {
klao@946
   180
  public:
klao@946
   181
deba@1979
   182
    typedef ExtendedFullGraphBase Parent;
deba@1979
   183
deba@1979
   184
    /// \brief Constructor
deba@1987
   185
    FullGraph() { construct(0); }
deba@1987
   186
deba@1987
   187
    /// \brief Constructor
deba@1979
   188
    ///
klao@946
   189
    FullGraph(int n) { construct(n); }
deba@1979
   190
deba@1979
   191
    /// \brief Resize the graph
deba@1979
   192
    ///
deba@1986
   193
    /// Resize the graph. The function will fully destroy and build the graph.
deba@1986
   194
    /// This cause that the maps of the graph will reallocated
deba@1986
   195
    /// automatically and the previous values will be lost.
deba@1979
   196
    void resize(int n) {
deba@1979
   197
      Parent::getNotifier(Edge()).clear();
deba@1979
   198
      Parent::getNotifier(Node()).clear();
deba@1979
   199
      construct(n);
deba@1979
   200
      Parent::getNotifier(Node()).build();
deba@1979
   201
      Parent::getNotifier(Edge()).build();
deba@1979
   202
    }
deba@2223
   203
deba@2223
   204
    /// \brief Returns the node with the given index.
deba@2223
   205
    ///
deba@2223
   206
    /// Returns the node with the given index. Because it is a
deba@2223
   207
    /// static size graph the node's of the graph can be indiced
deba@2223
   208
    /// by the range from 0 to \e nodeNum()-1 and the index of
deba@2223
   209
    /// the node can accessed by the \e index() member.
deba@2223
   210
    Node operator()(int index) const { return Parent::operator()(index); }
deba@2223
   211
deba@2223
   212
    /// \brief Returns the index of the node.
deba@2223
   213
    ///
deba@2223
   214
    /// Returns the index of the node. Because it is a
deba@2223
   215
    /// static size graph the node's of the graph can be indiced
deba@2223
   216
    /// by the range from 0 to \e nodeNum()-1 and the index of
deba@2223
   217
    /// the node can accessed by the \e index() member.
deba@2223
   218
    int index(const Node& node) const { return Parent::index(node); }
deba@2223
   219
deba@2223
   220
    /// \brief Returns the edge connects the given nodes.
deba@2223
   221
    ///
deba@2223
   222
    /// Returns the edge connects the given nodes.
deba@2223
   223
    Edge edge(const Node& u, const Node& v) const { 
deba@2223
   224
      return Parent::edge(u, v); 
deba@2223
   225
    }
deba@2223
   226
deba@2223
   227
    /// \brief Number of nodes.
deba@2223
   228
    int nodeNum() const { return Parent::nodeNum(); }
deba@2223
   229
    /// \brief Number of edges.
deba@2223
   230
    int edgeNum() const { return Parent::edgeNum(); }
klao@946
   231
  };
klao@946
   232
deba@2116
   233
deba@2116
   234
  class FullUGraphBase {
deba@2116
   235
    int _nodeNum;
deba@2116
   236
    int _edgeNum;
deba@2116
   237
  public:
deba@2116
   238
deba@2116
   239
    typedef FullUGraphBase Graph;
deba@2116
   240
deba@2116
   241
    class Node;
deba@2116
   242
    class Edge;
deba@2116
   243
deba@2223
   244
  protected:
deba@2116
   245
deba@2116
   246
    FullUGraphBase() {}
deba@2116
   247
deba@2116
   248
    void construct(int n) { _nodeNum = n; _edgeNum = n * (n - 1) / 2; }
deba@2116
   249
deba@2223
   250
  public:
deba@2223
   251
deba@2223
   252
deba@2116
   253
    Node operator()(int index) const { return Node(index); }
deba@2223
   254
    int index(const Node& node) const { return node.id; }
deba@2116
   255
deba@2223
   256
    Edge edge(const Node& u, const Node& v) const { 
deba@2223
   257
      return Edge(u.id * (u.id - 1) / 2 + v.id);
deba@2223
   258
    }
deba@2116
   259
deba@2116
   260
    typedef True NodeNumTag;
deba@2116
   261
    typedef True EdgeNumTag;
deba@2116
   262
deba@2116
   263
    int nodeNum() const { return _nodeNum; }
deba@2116
   264
    int edgeNum() const { return _edgeNum; }
deba@2116
   265
deba@2116
   266
    int maxNodeId() const { return _nodeNum-1; }
deba@2116
   267
    int maxEdgeId() const { return _edgeNum-1; }
deba@2116
   268
deba@2116
   269
    static Node nodeFromId(int id) { return Node(id);}
deba@2116
   270
    static Edge edgeFromId(int id) { return Edge(id);}
deba@2116
   271
deba@2116
   272
    Node source(Edge e) const { 
deba@2116
   273
      /// \todo we may do it faster
deba@2116
   274
      return Node(((int)sqrt((double)(1 + 8 * e.id)) + 1) / 2);
deba@2116
   275
    }
deba@2116
   276
deba@2116
   277
    Node target(Edge e) const { 
deba@2116
   278
      int source = ((int)sqrt((double)(1 + 8 * e.id)) + 1) / 2;;
deba@2116
   279
      return Node(e.id - (source) * (source - 1) / 2);
deba@2116
   280
    }
deba@2116
   281
deba@2116
   282
    static int id(Node v) { return v.id; }
deba@2116
   283
    static int id(Edge e) { return e.id; }
deba@2116
   284
deba@2116
   285
    Edge findEdge(Node u, Node v, Edge prev = INVALID) const {
deba@2116
   286
      if (prev.id != -1 || u.id <= v.id) return Edge(-1);
deba@2116
   287
      return Edge(u.id * (u.id - 1) / 2 + v.id);
deba@2116
   288
    }
deba@2116
   289
deba@2116
   290
    typedef True FindEdgeTag;
deba@2116
   291
    
deba@2116
   292
      
deba@2116
   293
    class Node {
deba@2116
   294
      friend class FullUGraphBase;
deba@2116
   295
deba@2116
   296
    protected:
deba@2116
   297
      int id;
deba@2116
   298
      Node(int _id) { id = _id;}
deba@2116
   299
    public:
deba@2116
   300
      Node() {}
deba@2116
   301
      Node (Invalid) { id = -1; }
deba@2116
   302
      bool operator==(const Node node) const {return id == node.id;}
deba@2116
   303
      bool operator!=(const Node node) const {return id != node.id;}
deba@2116
   304
      bool operator<(const Node node) const {return id < node.id;}
deba@2116
   305
    };
deba@2116
   306
    
deba@2116
   307
deba@2116
   308
deba@2116
   309
    class Edge {
deba@2116
   310
      friend class FullUGraphBase;
deba@2116
   311
      
deba@2116
   312
    protected:
deba@2116
   313
      int id;  // _nodeNum * target + source;
deba@2116
   314
deba@2116
   315
      Edge(int _id) : id(_id) {}
deba@2116
   316
deba@2116
   317
    public:
deba@2116
   318
      Edge() { }
deba@2116
   319
      Edge (Invalid) { id = -1; }
deba@2116
   320
      bool operator==(const Edge edge) const {return id == edge.id;}
deba@2116
   321
      bool operator!=(const Edge edge) const {return id != edge.id;}
deba@2116
   322
      bool operator<(const Edge edge) const {return id < edge.id;}
deba@2116
   323
    };
deba@2116
   324
deba@2116
   325
    void first(Node& node) const {
deba@2116
   326
      node.id = _nodeNum - 1;
deba@2116
   327
    }
deba@2116
   328
deba@2116
   329
    static void next(Node& node) {
deba@2116
   330
      --node.id;
deba@2116
   331
    }
deba@2116
   332
deba@2116
   333
    void first(Edge& edge) const {
deba@2116
   334
      edge.id = _edgeNum - 1;
deba@2116
   335
    }
deba@2116
   336
deba@2116
   337
    static void next(Edge& edge) {
deba@2116
   338
      --edge.id;
deba@2116
   339
    }
deba@2116
   340
deba@2116
   341
    void firstOut(Edge& edge, const Node& node) const {      
deba@2116
   342
      int src = node.id;
deba@2116
   343
      int trg = 0;
deba@2116
   344
      edge.id = (trg < src ? src * (src - 1) / 2 + trg : -1);
deba@2116
   345
    }
deba@2116
   346
deba@2116
   347
    /// \todo with specialized iterators we can make faster iterating
deba@2116
   348
    void nextOut(Edge& edge) const {
deba@2116
   349
      int src = source(edge).id;
deba@2116
   350
      int trg = target(edge).id;
deba@2116
   351
      ++trg;
deba@2116
   352
      edge.id = (trg < src ? src * (src - 1) / 2 + trg : -1);
deba@2116
   353
    }
deba@2116
   354
deba@2116
   355
    void firstIn(Edge& edge, const Node& node) const {
deba@2116
   356
      int src = node.id + 1;
deba@2116
   357
      int trg = node.id;
deba@2116
   358
      edge.id = (src < _nodeNum ? src * (src - 1) / 2 + trg : -1);
deba@2116
   359
    }
deba@2116
   360
    
deba@2116
   361
    void nextIn(Edge& edge) const {
deba@2116
   362
      int src = source(edge).id;
deba@2116
   363
      int trg = target(edge).id;
deba@2116
   364
      ++src;
deba@2116
   365
      edge.id = (src < _nodeNum ? src * (src - 1) / 2 + trg : -1);
deba@2116
   366
    }
deba@2116
   367
deba@2116
   368
  };
deba@2116
   369
deba@2116
   370
  typedef UGraphExtender<UndirGraphExtender<FullUGraphBase> > 
deba@2116
   371
  ExtendedFullUGraphBase;
deba@2116
   372
deba@2116
   373
  /// \ingroup graphs
deba@2116
   374
  ///
deba@2116
   375
  /// \brief An undirected full graph class.
deba@2116
   376
  ///
deba@2116
   377
  /// This is a simple and fast undirected full graph implementation.
deba@2116
   378
  /// It is completely static, so you can neither add nor delete either
deba@2116
   379
  /// edges or nodes.
deba@2116
   380
  ///
deba@2116
   381
  /// The main difference beetween the \e FullGraph and \e FullUGraph class
deba@2116
   382
  /// is that this class conforms to the undirected graph concept and
deba@2116
   383
  /// it does not contain the loop edges.
deba@2116
   384
  ///
alpar@2256
   385
  ///It also has an
alpar@2256
   386
  ///important extra feature that
alpar@2260
   387
  ///its maps are real \ref concepts::ReferenceMap "reference map"s.
alpar@2256
   388
  ///
deba@2116
   389
  /// \sa FullGraph
deba@2116
   390
  ///
deba@2116
   391
  /// \author Balazs Dezso
deba@2116
   392
  class FullUGraph : public ExtendedFullUGraphBase {
deba@2116
   393
  public:
deba@2116
   394
deba@2116
   395
    typedef ExtendedFullUGraphBase Parent;
deba@2116
   396
deba@2116
   397
    /// \brief Constructor
deba@2116
   398
    FullUGraph() { construct(0); }
deba@2116
   399
deba@2116
   400
    /// \brief Constructor
deba@2116
   401
    FullUGraph(int n) { construct(n); }
deba@2116
   402
deba@2116
   403
    /// \brief Resize the graph
deba@2116
   404
    ///
deba@2116
   405
    /// Resize the graph. The function will fully destroy and build the graph.
deba@2116
   406
    /// This cause that the maps of the graph will reallocated
deba@2116
   407
    /// automatically and the previous values will be lost.
deba@2116
   408
    void resize(int n) {
deba@2116
   409
      Parent::getNotifier(Edge()).clear();
deba@2116
   410
      Parent::getNotifier(UEdge()).clear();
deba@2116
   411
      Parent::getNotifier(Node()).clear();
deba@2116
   412
      construct(n);
deba@2116
   413
      Parent::getNotifier(Node()).build();
deba@2116
   414
      Parent::getNotifier(UEdge()).build();
deba@2116
   415
      Parent::getNotifier(Edge()).build();
deba@2116
   416
    }
deba@2223
   417
deba@2223
   418
    /// \brief Returns the node with the given index.
deba@2223
   419
    ///
deba@2223
   420
    /// Returns the node with the given index. Because it is a
deba@2223
   421
    /// static size graph the node's of the graph can be indiced
deba@2223
   422
    /// by the range from 0 to \e nodeNum()-1 and the index of
deba@2223
   423
    /// the node can accessed by the \e index() member.
deba@2223
   424
    Node operator()(int index) const { return Parent::operator()(index); }
deba@2223
   425
deba@2223
   426
    /// \brief Returns the index of the node.
deba@2223
   427
    ///
deba@2223
   428
    /// Returns the index of the node. Because it is a
deba@2223
   429
    /// static size graph the node's of the graph can be indiced
deba@2223
   430
    /// by the range from 0 to \e nodeNum()-1 and the index of
deba@2223
   431
    /// the node can accessed by the \e index() member.
deba@2223
   432
    int index(const Node& node) const { return Parent::index(node); }
deba@2223
   433
deba@2223
   434
    /// \brief Number of nodes.
deba@2223
   435
    int nodeNum() const { return Parent::nodeNum(); }
deba@2223
   436
    /// \brief Number of edges.
deba@2223
   437
    int edgeNum() const { return Parent::edgeNum(); }
deba@2223
   438
    /// \brief Number of undirected edges.
deba@2223
   439
    int uEdgeNum() const { return Parent::uEdgeNum(); }
deba@2223
   440
deba@2223
   441
    /// \brief Returns the edge connects the given nodes.
deba@2223
   442
    ///
deba@2223
   443
    /// Returns the edge connects the given nodes.
deba@2223
   444
    Edge edge(const Node& u, const Node& v) const { 
deba@2223
   445
      if (Parent::index(u) > Parent::index(v)) {
deba@2223
   446
        return Parent::direct(Parent::edge(u, v), true);
deba@2223
   447
      } else if (Parent::index(u) == Parent::index(v)) {
deba@2223
   448
        return INVALID;
deba@2223
   449
      } else {
deba@2223
   450
        return Parent::direct(Parent::edge(v, u), false); 
deba@2223
   451
      }
deba@2223
   452
    }
deba@2223
   453
deba@2223
   454
    /// \brief Returns the undirected edge connects the given nodes.
deba@2223
   455
    ///
deba@2223
   456
    /// Returns the undirected edge connects the given nodes.
deba@2223
   457
    UEdge uEdge(const Node& u, const Node& v) const {
deba@2223
   458
      if (Parent::index(u) > Parent::index(v)) {
deba@2223
   459
        return Parent::edge(u, v);
deba@2223
   460
      } else if (Parent::index(u) == Parent::index(v)) {
deba@2223
   461
        return INVALID;
deba@2223
   462
      } else {
deba@2223
   463
        return Parent::edge(v, u);
deba@2223
   464
      }
deba@2223
   465
    }
deba@2116
   466
  };
deba@2116
   467
deba@2116
   468
deba@2116
   469
  class FullBpUGraphBase {
deba@2116
   470
  protected:
deba@2116
   471
deba@2116
   472
    int _aNodeNum;
deba@2116
   473
    int _bNodeNum;
deba@2116
   474
deba@2116
   475
    int _edgeNum;
deba@2116
   476
deba@2223
   477
  protected:
deba@2223
   478
deba@2223
   479
    FullBpUGraphBase() {}
deba@2223
   480
deba@2223
   481
    void construct(int aNodeNum, int bNodeNum) {
deba@2223
   482
      _aNodeNum = aNodeNum;
deba@2223
   483
      _bNodeNum = bNodeNum;
deba@2223
   484
      _edgeNum = aNodeNum * bNodeNum;
deba@2223
   485
    }
deba@2223
   486
deba@2116
   487
  public:
deba@2116
   488
deba@2116
   489
    class NodeSetError : public LogicError {
deba@2162
   490
    public:
alpar@2151
   491
      virtual const char* what() const throw() { 
deba@2116
   492
	return "lemon::FullBpUGraph::NodeSetError";
deba@2116
   493
      }
deba@2116
   494
    };
deba@2116
   495
  
deba@2116
   496
    class Node {
deba@2116
   497
      friend class FullBpUGraphBase;
deba@2116
   498
    protected:
deba@2116
   499
      int id;
deba@2116
   500
deba@2116
   501
      Node(int _id) : id(_id) {}
deba@2116
   502
    public:
deba@2116
   503
      Node() {}
deba@2116
   504
      Node(Invalid) { id = -1; }
deba@2116
   505
      bool operator==(const Node i) const {return id==i.id;}
deba@2116
   506
      bool operator!=(const Node i) const {return id!=i.id;}
deba@2116
   507
      bool operator<(const Node i) const {return id<i.id;}
deba@2116
   508
    };
deba@2116
   509
deba@2116
   510
    class UEdge {
deba@2116
   511
      friend class FullBpUGraphBase;
deba@2116
   512
    protected:
deba@2116
   513
      int id;
deba@2116
   514
deba@2116
   515
      UEdge(int _id) { id = _id;}
deba@2116
   516
    public:
deba@2116
   517
      UEdge() {}
deba@2116
   518
      UEdge (Invalid) { id = -1; }
deba@2116
   519
      bool operator==(const UEdge i) const {return id==i.id;}
deba@2116
   520
      bool operator!=(const UEdge i) const {return id!=i.id;}
deba@2116
   521
      bool operator<(const UEdge i) const {return id<i.id;}
deba@2116
   522
    };
deba@2116
   523
deba@2223
   524
    Node aNode(int index) const { return Node(index << 1); }
deba@2223
   525
    Node bNode(int index) const { return Node((index << 1) + 1); }
deba@2223
   526
deba@2223
   527
    int aNodeIndex(const Node& node) const { return node.id >> 1; }
deba@2223
   528
    int bNodeIndex(const Node& node) const { return node.id >> 1; }
deba@2223
   529
deba@2223
   530
    UEdge uEdge(const Node& u, const Node& v) const { 
deba@2223
   531
      if (((u.id ^ v.id) & 1) != 1) {
deba@2223
   532
        return UEdge(-1);
deba@2223
   533
      } else if ((u.id & 1) == 0) {
deba@2223
   534
        return UEdge((u.id >> 1) * _bNodeNum + (v.id >> 1));
deba@2223
   535
      } else {
deba@2223
   536
        return UEdge((v.id >> 1) * _bNodeNum + (u.id >> 1));
deba@2223
   537
      }
deba@2116
   538
    }
deba@2116
   539
deba@2116
   540
    void firstANode(Node& node) const {
deba@2116
   541
      node.id = 2 * _aNodeNum - 2;
deba@2116
   542
      if (node.id < 0) node.id = -1; 
deba@2116
   543
    }
deba@2116
   544
    void nextANode(Node& node) const {
deba@2116
   545
      node.id -= 2;
deba@2116
   546
      if (node.id < 0) node.id = -1; 
deba@2116
   547
    }
deba@2116
   548
deba@2116
   549
    void firstBNode(Node& node) const {
deba@2116
   550
      node.id = 2 * _bNodeNum - 1;
deba@2116
   551
    }
deba@2116
   552
    void nextBNode(Node& node) const {
deba@2116
   553
      node.id -= 2;
deba@2116
   554
    }
deba@2116
   555
deba@2116
   556
    void first(Node& node) const {
deba@2116
   557
      if (_aNodeNum > 0) {
deba@2116
   558
	node.id = 2 * _aNodeNum - 2;
deba@2116
   559
      } else {
deba@2116
   560
	node.id = 2 * _bNodeNum - 1;
deba@2116
   561
      }
deba@2116
   562
    }
deba@2116
   563
    void next(Node& node) const {
deba@2116
   564
      node.id -= 2;
deba@2116
   565
      if (node.id == -2) {
deba@2116
   566
	node.id = 2 * _bNodeNum - 1;
deba@2116
   567
      }
deba@2116
   568
    }
deba@2116
   569
  
deba@2116
   570
    void first(UEdge& edge) const {
deba@2116
   571
      edge.id = _edgeNum - 1;
deba@2116
   572
    }
deba@2116
   573
    void next(UEdge& edge) const {
deba@2116
   574
      --edge.id;
deba@2116
   575
    }
deba@2116
   576
deba@2116
   577
    void firstFromANode(UEdge& edge, const Node& node) const {
deba@2116
   578
      LEMON_ASSERT((node.id & 1) == 0, NodeSetError());
deba@2116
   579
      edge.id = (node.id >> 1) * _bNodeNum;
deba@2116
   580
    }
deba@2116
   581
    void nextFromANode(UEdge& edge) const {
deba@2116
   582
      ++(edge.id);
deba@2116
   583
      if (edge.id % _bNodeNum == 0) edge.id = -1;
deba@2116
   584
    }
deba@2116
   585
deba@2116
   586
    void firstFromBNode(UEdge& edge, const Node& node) const {
deba@2116
   587
      LEMON_ASSERT((node.id & 1) == 1, NodeSetError());
deba@2116
   588
      edge.id = (node.id >> 1);
deba@2116
   589
    }
deba@2116
   590
    void nextFromBNode(UEdge& edge) const {
deba@2116
   591
      edge.id += _bNodeNum;
deba@2116
   592
      if (edge.id >= _edgeNum) edge.id = -1;
deba@2116
   593
    }
deba@2116
   594
deba@2116
   595
    static int id(const Node& node) {
deba@2116
   596
      return node.id;
deba@2116
   597
    }
deba@2116
   598
    static Node nodeFromId(int id) {
deba@2116
   599
      return Node(id);
deba@2116
   600
    }
deba@2116
   601
    int maxNodeId() const {
deba@2116
   602
      return _aNodeNum > _bNodeNum ? 
deba@2116
   603
	_aNodeNum * 2 - 2 : _bNodeNum * 2 - 1;
deba@2116
   604
    }
deba@2116
   605
  
deba@2116
   606
    static int id(const UEdge& edge) {
deba@2116
   607
      return edge.id;
deba@2116
   608
    }
deba@2116
   609
    static UEdge uEdgeFromId(int id) {
deba@2116
   610
      return UEdge(id);
deba@2116
   611
    }
deba@2116
   612
    int maxUEdgeId() const {
deba@2116
   613
      return _edgeNum - 1;
deba@2116
   614
    }
deba@2116
   615
  
deba@2116
   616
    static int aNodeId(const Node& node) {
deba@2116
   617
      return node.id >> 1;
deba@2116
   618
    }
deba@2231
   619
    static Node nodeFromANodeId(int id) {
deba@2116
   620
      return Node(id << 1);
deba@2116
   621
    }
deba@2116
   622
    int maxANodeId() const {
deba@2116
   623
      return _aNodeNum;
deba@2116
   624
    }
deba@2116
   625
deba@2116
   626
    static int bNodeId(const Node& node) {
deba@2116
   627
      return node.id >> 1;
deba@2116
   628
    }
deba@2231
   629
    static Node nodeFromBNodeId(int id) {
deba@2116
   630
      return Node((id << 1) + 1);
deba@2116
   631
    }
deba@2116
   632
    int maxBNodeId() const {
deba@2116
   633
      return _bNodeNum;
deba@2116
   634
    }
deba@2116
   635
deba@2116
   636
    Node aNode(const UEdge& edge) const {
deba@2116
   637
      return Node((edge.id / _bNodeNum) << 1);
deba@2116
   638
    }
deba@2116
   639
    Node bNode(const UEdge& edge) const {
deba@2116
   640
      return Node(((edge.id % _bNodeNum) << 1) + 1);
deba@2116
   641
    }
deba@2116
   642
deba@2116
   643
    static bool aNode(const Node& node) {
deba@2116
   644
      return (node.id & 1) == 0;
deba@2116
   645
    }
deba@2116
   646
deba@2116
   647
    static bool bNode(const Node& node) {
deba@2116
   648
      return (node.id & 1) == 1;
deba@2116
   649
    }
deba@2116
   650
deba@2116
   651
deba@2116
   652
    typedef True NodeNumTag;
deba@2116
   653
    int nodeNum() const { return _aNodeNum + _bNodeNum; }
deba@2116
   654
    int aNodeNum() const { return _aNodeNum; }
deba@2116
   655
    int bNodeNum() const { return _bNodeNum; }
deba@2116
   656
deba@2116
   657
    typedef True EdgeNumTag;
deba@2116
   658
    int uEdgeNum() const { return _edgeNum; }
deba@2116
   659
deba@2223
   660
deba@2223
   661
    typedef True FindEdgeTag;
deba@2223
   662
    UEdge findUEdge(Node u, Node v, UEdge prev = INVALID) const {
deba@2223
   663
      if (prev.id != -1 || ((u.id ^ v.id) & 1) != 1) {
deba@2223
   664
        return UEdge(-1);
deba@2223
   665
      } else if ((u.id & 1) == 0) {
deba@2223
   666
        return UEdge((u.id >> 1) * _bNodeNum + (v.id >> 1));
deba@2223
   667
      } else {
deba@2223
   668
        return UEdge((v.id >> 1) * _bNodeNum + (u.id >> 1));
deba@2223
   669
      }
deba@2223
   670
    }
deba@2223
   671
deba@2116
   672
  };
deba@2116
   673
deba@2116
   674
deba@2231
   675
  typedef BpUGraphExtender<BidirBpUGraphExtender<FullBpUGraphBase> > 
deba@2231
   676
  ExtendedFullBpUGraphBase;
deba@2116
   677
deba@2116
   678
deba@2116
   679
  /// \ingroup graphs
deba@2116
   680
  ///
deba@2116
   681
  /// \brief An undirected full bipartite graph class.
deba@2116
   682
  ///
deba@2116
   683
  /// This is a simple and fast bipartite undirected full graph implementation.
deba@2116
   684
  /// It is completely static, so you can neither add nor delete either
deba@2116
   685
  /// edges or nodes.
deba@2116
   686
  ///
deba@2116
   687
  /// \author Balazs Dezso
deba@2116
   688
  class FullBpUGraph : 
deba@2116
   689
    public ExtendedFullBpUGraphBase {
deba@2116
   690
  public:
deba@2116
   691
deba@2116
   692
    typedef ExtendedFullBpUGraphBase Parent;
deba@2116
   693
deba@2116
   694
    FullBpUGraph() {
deba@2116
   695
      Parent::construct(0, 0);
deba@2116
   696
    }
deba@2116
   697
deba@2116
   698
    FullBpUGraph(int aNodeNum, int bNodeNum) {
deba@2116
   699
      Parent::construct(aNodeNum, bNodeNum);
deba@2116
   700
    }
deba@2116
   701
deba@2116
   702
    /// \brief Resize the graph
deba@2116
   703
    ///
deba@2223
   704
    /// Resize the graph
deba@2116
   705
    void resize(int n, int m) {
deba@2116
   706
      Parent::getNotifier(Edge()).clear();
deba@2116
   707
      Parent::getNotifier(UEdge()).clear();
deba@2116
   708
      Parent::getNotifier(Node()).clear();
deba@2116
   709
      Parent::getNotifier(ANode()).clear();
deba@2116
   710
      Parent::getNotifier(BNode()).clear();
deba@2116
   711
      construct(n, m);
deba@2116
   712
      Parent::getNotifier(ANode()).build();
deba@2116
   713
      Parent::getNotifier(BNode()).build();
deba@2116
   714
      Parent::getNotifier(Node()).build();
deba@2116
   715
      Parent::getNotifier(UEdge()).build();
deba@2116
   716
      Parent::getNotifier(Edge()).build();
deba@2116
   717
    }
deba@2223
   718
deba@2223
   719
    /// \brief Number of nodes.
deba@2223
   720
    int nodeNum() const { return Parent::nodeNum(); }
deba@2223
   721
    /// \brief Number of A-nodes.
deba@2223
   722
    int aNodeNum() const { return Parent::aNodeNum(); }
deba@2223
   723
    /// \brief Number of B-nodes.
deba@2223
   724
    int bNodeNum() const { return Parent::bNodeNum(); }
deba@2223
   725
    /// \brief Number of edges.
deba@2223
   726
    int edgeNum() const { return Parent::edgeNum(); }
deba@2223
   727
    /// \brief Number of undirected edges.
deba@2223
   728
    int uEdgeNum() const { return Parent::uEdgeNum(); }
deba@2223
   729
deba@2223
   730
deba@2223
   731
    using Parent::aNode;
deba@2223
   732
    using Parent::bNode;
deba@2223
   733
deba@2223
   734
    /// \brief Returns the A-node with the given index.
deba@2223
   735
    ///
deba@2223
   736
    /// Returns the A-node with the given index. Because it is a
deba@2223
   737
    /// static size graph the node's of the graph can be indiced
deba@2223
   738
    /// by the range from 0 to \e aNodeNum()-1 and the index of
deba@2223
   739
    /// the node can accessed by the \e aNodeIndex() member.
deba@2223
   740
    Node aNode(int index) const { return Parent::aNode(index); }
deba@2223
   741
deba@2223
   742
    /// \brief Returns the B-node with the given index.
deba@2223
   743
    ///
deba@2223
   744
    /// Returns the B-node with the given index. Because it is a
deba@2223
   745
    /// static size graph the node's of the graph can be indiced
deba@2223
   746
    /// by the range from 0 to \e bNodeNum()-1 and the index of
deba@2223
   747
    /// the node can accessed by the \e bNodeIndex() member.
deba@2223
   748
    Node bNode(int index) const { return Parent::bNode(index); }
deba@2223
   749
deba@2223
   750
    /// \brief Returns the index of the A-node.
deba@2223
   751
    ///
deba@2223
   752
    /// Returns the index of the A-node. Because it is a
deba@2223
   753
    /// static size graph the node's of the graph can be indiced
deba@2223
   754
    /// by the range from 0 to \e aNodeNum()-1 and the index of
deba@2223
   755
    /// the node can accessed by the \e aNodeIndex() member.
deba@2223
   756
    int aNodeIndex(const Node& node) const { return Parent::aNodeIndex(node); }
deba@2223
   757
deba@2223
   758
    /// \brief Returns the index of the B-node.
deba@2223
   759
    ///
deba@2223
   760
    /// Returns the index of the B-node. Because it is a
deba@2223
   761
    /// static size graph the node's of the graph can be indiced
deba@2223
   762
    /// by the range from 0 to \e bNodeNum()-1 and the index of
deba@2223
   763
    /// the node can accessed by the \e bNodeIndex() member.
deba@2223
   764
    int bNodeIndex(const Node& node) const { return Parent::bNodeIndex(node); }
deba@2223
   765
deba@2223
   766
    /// \brief Returns the edge connects the given nodes.
deba@2223
   767
    ///
deba@2223
   768
    /// Returns the edge connects the given nodes.
deba@2223
   769
    Edge edge(const Node& u, const Node& v) const {
deba@2223
   770
      UEdge uedge = Parent::uEdge(u, v);
deba@2223
   771
      if (uedge != INVALID) {
deba@2223
   772
        return Parent::direct(uedge, Parent::aNode(u));
deba@2223
   773
      } else {
deba@2223
   774
        return INVALID;
deba@2223
   775
      }
deba@2223
   776
    }
deba@2223
   777
deba@2223
   778
    /// \brief Returns the undirected edge connects the given nodes.
deba@2223
   779
    ///
deba@2223
   780
    /// Returns the undirected edge connects the given nodes.
deba@2223
   781
    UEdge uEdge(const Node& u, const Node& v) const {
deba@2223
   782
      return Parent::uEdge(u, v);
deba@2223
   783
    }
deba@2116
   784
  };
deba@2116
   785
alpar@921
   786
} //namespace lemon
alpar@591
   787
alpar@591
   788
alpar@921
   789
#endif //LEMON_FULL_GRAPH_H