lemon/list_bpugraph.h
author deba
Fri, 30 Jun 2006 12:14:36 +0000
changeset 2115 4cd528a30ec1
parent 2114 lemon/list_graph.h@677ea6c8169a
permissions -rw-r--r--
Splitted graph files
alpar@948
     1
/* -*- C++ -*-
alpar@948
     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@948
     8
 *
alpar@948
     9
 * Permission to use, modify and distribute this software is granted
alpar@948
    10
 * provided that this copyright notice appears in all copies. For
alpar@948
    11
 * precise terms see the accompanying LICENSE file.
alpar@948
    12
 *
alpar@948
    13
 * This software is provided "AS IS" with no warranty of any kind,
alpar@948
    14
 * express or implied, and with no claim as to its suitability for any
alpar@948
    15
 * purpose.
alpar@948
    16
 *
alpar@948
    17
 */
alpar@395
    18
deba@2115
    19
#ifndef LEMON_LIST_BPUGRAPH_H
deba@2115
    20
#define LEMON_LIST_BPUGRAPH_H
alpar@395
    21
alpar@948
    22
///\ingroup graphs
alpar@948
    23
///\file
deba@2115
    24
///\brief ListBpUGraph classes.
alpar@948
    25
deba@2115
    26
#include <lemon/bits/bpugraph_extender.h>
deba@782
    27
deba@1774
    28
#include <lemon/error.h>
deba@1774
    29
deba@1979
    30
#include <vector>
alpar@1011
    31
#include <list>
deba@782
    32
alpar@921
    33
namespace lemon {
alpar@395
    34
deba@1982
    35
  class ListBpUGraphBase {
deba@1982
    36
  public:
deba@1982
    37
deba@1982
    38
    class NodeSetError : public LogicError {
deba@1982
    39
      virtual const char* exceptionName() const { 
deba@1982
    40
	return "lemon::ListBpUGraph::NodeSetError";
deba@1982
    41
      }
deba@1982
    42
    };
deba@1982
    43
deba@1982
    44
  protected:
deba@1982
    45
deba@1982
    46
    struct NodeT {
deba@2098
    47
      int first_edge, prev, next;
deba@1982
    48
    };
deba@1982
    49
deba@2076
    50
    struct UEdgeT {
deba@1982
    51
      int aNode, prev_out, next_out;
deba@1982
    52
      int bNode, prev_in, next_in;
deba@1982
    53
    };
deba@1982
    54
deba@1982
    55
    std::vector<NodeT> aNodes;
deba@1982
    56
    std::vector<NodeT> bNodes;
deba@1982
    57
deba@2076
    58
    std::vector<UEdgeT> edges;
deba@1982
    59
deba@1982
    60
    int first_anode;
deba@1982
    61
    int first_free_anode;
deba@1982
    62
deba@1982
    63
    int first_bnode;
deba@1982
    64
    int first_free_bnode;
deba@1982
    65
deba@1982
    66
    int first_free_edge;
deba@1982
    67
deba@1982
    68
  public:
deba@1982
    69
  
deba@1982
    70
    class Node {
deba@1982
    71
      friend class ListBpUGraphBase;
deba@1982
    72
    protected:
deba@1982
    73
      int id;
deba@1982
    74
deba@2031
    75
      explicit Node(int _id) : id(_id) {}
deba@1982
    76
    public:
deba@1982
    77
      Node() {}
deba@1982
    78
      Node(Invalid) { id = -1; }
deba@1982
    79
      bool operator==(const Node i) const {return id==i.id;}
deba@1982
    80
      bool operator!=(const Node i) const {return id!=i.id;}
deba@1982
    81
      bool operator<(const Node i) const {return id<i.id;}
deba@1982
    82
    };
deba@1982
    83
deba@2076
    84
    class UEdge {
deba@1982
    85
      friend class ListBpUGraphBase;
deba@1982
    86
    protected:
deba@1982
    87
      int id;
deba@1982
    88
deba@2076
    89
      explicit UEdge(int _id) { id = _id;}
deba@1982
    90
    public:
deba@2076
    91
      UEdge() {}
deba@2076
    92
      UEdge (Invalid) { id = -1; }
deba@2076
    93
      bool operator==(const UEdge i) const {return id==i.id;}
deba@2076
    94
      bool operator!=(const UEdge i) const {return id!=i.id;}
deba@2076
    95
      bool operator<(const UEdge i) const {return id<i.id;}
deba@1982
    96
    };
deba@1982
    97
deba@1982
    98
    ListBpUGraphBase()
deba@1982
    99
      : first_anode(-1), first_free_anode(-1),
deba@1982
   100
        first_bnode(-1), first_free_bnode(-1),
deba@1982
   101
        first_free_edge(-1) {}
deba@1982
   102
deba@1982
   103
    void firstANode(Node& node) const {
deba@1982
   104
      node.id = first_anode != -1 ? (first_anode << 1) : -1;
deba@1982
   105
    }
deba@1982
   106
    void nextANode(Node& node) const {
deba@2098
   107
      node.id = aNodes[node.id >> 1].next;
deba@1982
   108
    }
deba@1982
   109
deba@1982
   110
    void firstBNode(Node& node) const {
deba@2098
   111
      node.id = first_bnode != -1 ? (first_bnode << 1) + 1 : -1;
deba@1982
   112
    }
deba@1982
   113
    void nextBNode(Node& node) const {
deba@2098
   114
      node.id = bNodes[node.id >> 1].next;
deba@1982
   115
    }
deba@1982
   116
deba@1982
   117
    void first(Node& node) const {
deba@1982
   118
      if (first_anode != -1) {
deba@1982
   119
        node.id = (first_anode << 1);
deba@1982
   120
      } else if (first_bnode != -1) {
deba@1982
   121
        node.id = (first_bnode << 1) + 1;
deba@1982
   122
      } else {
deba@1982
   123
        node.id = -1;
deba@1982
   124
      }
deba@1982
   125
    }
deba@1982
   126
    void next(Node& node) const {
deba@1982
   127
      if (aNode(node)) {
deba@2098
   128
        node.id = aNodes[node.id >> 1].next;
deba@1982
   129
        if (node.id == -1) {
deba@1982
   130
          if (first_bnode != -1) {
deba@1982
   131
            node.id = (first_bnode << 1) + 1;
deba@1982
   132
          }
deba@1982
   133
        }
deba@1982
   134
      } else {
deba@2098
   135
        node.id = bNodes[node.id >> 1].next;
deba@1982
   136
      }
deba@1982
   137
    }
deba@1982
   138
  
deba@2076
   139
    void first(UEdge& edge) const {
deba@1982
   140
      int aNodeId = first_anode;
deba@1982
   141
      while (aNodeId != -1 && aNodes[aNodeId].first_edge == -1) {
deba@2098
   142
        aNodeId = aNodes[aNodeId].next != -1 ? 
deba@2098
   143
          aNodes[aNodeId].next >> 1 : -1;
deba@1982
   144
      }
deba@1982
   145
      if (aNodeId != -1) {
deba@1982
   146
        edge.id = aNodes[aNodeId].first_edge;
deba@1982
   147
      } else {
deba@1982
   148
        edge.id = -1;
deba@1982
   149
      }
deba@1982
   150
    }
deba@2076
   151
    void next(UEdge& edge) const {
deba@1982
   152
      int aNodeId = edges[edge.id].aNode >> 1;
deba@1982
   153
      edge.id = edges[edge.id].next_out;
deba@1982
   154
      if (edge.id == -1) {
deba@2098
   155
        aNodeId = aNodes[aNodeId].next != -1 ? 
deba@2098
   156
          aNodes[aNodeId].next >> 1 : -1;
deba@1982
   157
        while (aNodeId != -1 && aNodes[aNodeId].first_edge == -1) {
deba@2098
   158
          aNodeId = aNodes[aNodeId].next != -1 ? 
deba@2098
   159
          aNodes[aNodeId].next >> 1 : -1;
deba@1982
   160
        }
deba@1982
   161
        if (aNodeId != -1) {
deba@1982
   162
          edge.id = aNodes[aNodeId].first_edge;
deba@1982
   163
        } else {
deba@1982
   164
          edge.id = -1;
deba@1982
   165
        }
deba@1982
   166
      }
deba@1982
   167
    }
deba@1982
   168
deba@2076
   169
    void firstFromANode(UEdge& edge, const Node& node) const {
deba@1982
   170
      LEMON_ASSERT((node.id & 1) == 0, NodeSetError());
deba@1982
   171
      edge.id = aNodes[node.id >> 1].first_edge;
deba@1982
   172
    }
deba@2076
   173
    void nextFromANode(UEdge& edge) const {
deba@1982
   174
      edge.id = edges[edge.id].next_out;
deba@1982
   175
    }
deba@1982
   176
deba@2076
   177
    void firstFromBNode(UEdge& edge, const Node& node) const {
deba@1982
   178
      LEMON_ASSERT((node.id & 1) == 1, NodeSetError());
deba@1982
   179
      edge.id = bNodes[node.id >> 1].first_edge;
deba@1982
   180
    }
deba@2076
   181
    void nextFromBNode(UEdge& edge) const {
deba@1982
   182
      edge.id = edges[edge.id].next_in;
deba@1982
   183
    }
deba@1982
   184
deba@1982
   185
    static int id(const Node& node) {
deba@1982
   186
      return node.id;
deba@1982
   187
    }
deba@1982
   188
    static Node nodeFromId(int id) {
deba@1982
   189
      return Node(id);
deba@1982
   190
    }
deba@1982
   191
    int maxNodeId() const {
deba@1982
   192
      return aNodes.size() > bNodes.size() ?
deba@1982
   193
	aNodes.size() * 2 - 2 : bNodes.size() * 2 - 1;
deba@1982
   194
    }
deba@1982
   195
  
deba@2076
   196
    static int id(const UEdge& edge) {
deba@1982
   197
      return edge.id;
deba@1982
   198
    }
deba@2076
   199
    static UEdge uEdgeFromId(int id) {
deba@2076
   200
      return UEdge(id);
deba@1982
   201
    }
deba@2076
   202
    int maxUEdgeId() const {
deba@1982
   203
      return edges.size();
deba@1982
   204
    }
deba@1982
   205
  
deba@1982
   206
    static int aNodeId(const Node& node) {
deba@1982
   207
      return node.id >> 1;
deba@1982
   208
    }
deba@1995
   209
    static Node fromANodeId(int id) {
deba@1982
   210
      return Node(id << 1);
deba@1982
   211
    }
deba@1982
   212
    int maxANodeId() const {
deba@1982
   213
      return aNodes.size();
deba@1982
   214
    }
deba@1982
   215
deba@1982
   216
    static int bNodeId(const Node& node) {
deba@1982
   217
      return node.id >> 1;
deba@1982
   218
    }
deba@1982
   219
    static Node fromBNodeId(int id) {
deba@1982
   220
      return Node((id << 1) + 1);
deba@1982
   221
    }
deba@1982
   222
    int maxBNodeId() const {
deba@1982
   223
      return bNodes.size();
deba@1982
   224
    }
deba@1982
   225
deba@2076
   226
    Node aNode(const UEdge& edge) const {
deba@1982
   227
      return Node(edges[edge.id].aNode);
deba@1982
   228
    }
deba@2076
   229
    Node bNode(const UEdge& edge) const {
deba@1982
   230
      return Node(edges[edge.id].bNode);
deba@1982
   231
    }
deba@1982
   232
deba@1982
   233
    static bool aNode(const Node& node) {
deba@1982
   234
      return (node.id & 1) == 0;
deba@1982
   235
    }
deba@1982
   236
deba@1982
   237
    static bool bNode(const Node& node) {
deba@1982
   238
      return (node.id & 1) == 1;
deba@1982
   239
    }
deba@1982
   240
deba@1982
   241
    Node addANode() {
deba@1982
   242
      int aNodeId;
deba@1982
   243
      if (first_free_anode == -1) {
deba@1982
   244
        aNodeId = aNodes.size();
deba@1982
   245
        aNodes.push_back(NodeT());
deba@1982
   246
      } else {
deba@1982
   247
        aNodeId = first_free_anode;
deba@2098
   248
        first_free_anode = aNodes[first_free_anode].next;
deba@1982
   249
      }
deba@2098
   250
      if (first_anode != -1) {
deba@2098
   251
        aNodes[aNodeId].next = first_anode << 1;
deba@2098
   252
        aNodes[first_anode].prev = aNodeId << 1;
deba@2098
   253
      } else {
deba@2098
   254
        aNodes[aNodeId].next = -1;
deba@2098
   255
      }
deba@2098
   256
      aNodes[aNodeId].prev = -1;
deba@1982
   257
      first_anode = aNodeId;
deba@1982
   258
      aNodes[aNodeId].first_edge = -1;
deba@1982
   259
      return Node(aNodeId << 1);
deba@1982
   260
    }
deba@1982
   261
deba@1982
   262
    Node addBNode() {
deba@1982
   263
      int bNodeId;
deba@1984
   264
      if (first_free_bnode == -1) {
deba@1982
   265
        bNodeId = bNodes.size();
deba@1982
   266
        bNodes.push_back(NodeT());
deba@1982
   267
      } else {
deba@1982
   268
        bNodeId = first_free_bnode;
deba@2098
   269
        first_free_bnode = bNodes[first_free_bnode].next;
deba@1982
   270
      }
deba@2098
   271
      if (first_bnode != -1) {
deba@2098
   272
        bNodes[bNodeId].next = (first_bnode << 1) + 1;
deba@2098
   273
        bNodes[first_bnode].prev = (bNodeId << 1) + 1;
deba@2098
   274
      } else {
deba@2098
   275
        bNodes[bNodeId].next = -1;
deba@2098
   276
      }
deba@1982
   277
      first_bnode = bNodeId;
deba@1982
   278
      bNodes[bNodeId].first_edge = -1;
deba@1982
   279
      return Node((bNodeId << 1) + 1);
deba@1982
   280
    }
deba@1982
   281
deba@2076
   282
    UEdge addEdge(const Node& source, const Node& target) {
deba@1982
   283
      LEMON_ASSERT(((source.id ^ target.id) & 1) == 1, NodeSetError());
deba@1982
   284
      int edgeId;
deba@1982
   285
      if (first_free_edge != -1) {
deba@1982
   286
        edgeId = first_free_edge;
deba@1982
   287
        first_free_edge = edges[edgeId].next_out;
deba@1982
   288
      } else {
deba@1982
   289
        edgeId = edges.size();
deba@2076
   290
        edges.push_back(UEdgeT());
deba@1982
   291
      }
deba@1982
   292
      if ((source.id & 1) == 0) {
deba@1982
   293
	edges[edgeId].aNode = source.id;
deba@1982
   294
	edges[edgeId].bNode = target.id;
deba@1982
   295
      } else {
deba@1982
   296
	edges[edgeId].aNode = target.id;
deba@1982
   297
	edges[edgeId].bNode = source.id;
deba@1982
   298
      }
deba@1982
   299
      edges[edgeId].next_out = aNodes[edges[edgeId].aNode >> 1].first_edge;
deba@1982
   300
      edges[edgeId].prev_out = -1;
deba@1982
   301
      if (aNodes[edges[edgeId].aNode >> 1].first_edge != -1) {
deba@1982
   302
        edges[aNodes[edges[edgeId].aNode >> 1].first_edge].prev_out = edgeId;
deba@1982
   303
      }
deba@1982
   304
      aNodes[edges[edgeId].aNode >> 1].first_edge = edgeId;
deba@1982
   305
      edges[edgeId].next_in = bNodes[edges[edgeId].bNode >> 1].first_edge;
deba@1982
   306
      edges[edgeId].prev_in = -1;
deba@1982
   307
      if (bNodes[edges[edgeId].bNode >> 1].first_edge != -1) {
deba@1982
   308
        edges[bNodes[edges[edgeId].bNode >> 1].first_edge].prev_in = edgeId;
deba@1982
   309
      }
deba@1982
   310
      bNodes[edges[edgeId].bNode >> 1].first_edge = edgeId;
deba@2076
   311
      return UEdge(edgeId);
deba@1982
   312
    }
deba@1982
   313
deba@1982
   314
    void erase(const Node& node) {
deba@1982
   315
      if (aNode(node)) {
deba@1982
   316
        int aNodeId = node.id >> 1;
deba@2098
   317
        if (aNodes[aNodeId].prev != -1) {
deba@2098
   318
          aNodes[aNodes[aNodeId].prev >> 1].next = aNodes[aNodeId].next;
deba@2098
   319
        } else {
deba@2098
   320
          first_anode = aNodes[aNodeId].next >> 1;
deba@2098
   321
        }
deba@2098
   322
        if (aNodes[aNodeId].next != -1) {
deba@2098
   323
          aNodes[aNodes[aNodeId].next >> 1].prev = aNodes[aNodeId].prev;
deba@2098
   324
        }
deba@2098
   325
        aNodes[aNodeId].next = first_free_anode;
deba@1982
   326
        first_free_anode = aNodeId;
deba@1982
   327
      } else {
deba@1982
   328
        int bNodeId = node.id >> 1;
deba@2098
   329
        if (bNodes[bNodeId].prev != -1) {
deba@2098
   330
          bNodes[bNodes[bNodeId].prev >> 1].next = bNodes[bNodeId].next;
deba@2098
   331
        } else {
deba@2098
   332
          first_bnode = bNodes[bNodeId].next >> 1;
deba@2098
   333
        }
deba@2098
   334
        if (bNodes[bNodeId].next != -1) {
deba@2098
   335
          bNodes[bNodes[bNodeId].next >> 1].prev = bNodes[bNodeId].prev;
deba@2098
   336
        }
deba@2098
   337
        bNodes[bNodeId].next = first_free_bnode;
deba@1982
   338
        first_free_bnode = bNodeId;
deba@1982
   339
      }
deba@1982
   340
    }
deba@1982
   341
deba@2076
   342
    void erase(const UEdge& edge) {
deba@2098
   343
deba@1982
   344
      if (edges[edge.id].prev_out != -1) {
deba@1982
   345
        edges[edges[edge.id].prev_out].next_out = edges[edge.id].next_out;
deba@1982
   346
      } else {
deba@2098
   347
        aNodes[edges[edge.id].aNode >> 1].first_edge = edges[edge.id].next_out;
deba@1982
   348
      }
deba@1982
   349
      if (edges[edge.id].next_out != -1) {
deba@1982
   350
        edges[edges[edge.id].next_out].prev_out = edges[edge.id].prev_out;
deba@1982
   351
      }
deba@2098
   352
deba@1982
   353
      if (edges[edge.id].prev_in != -1) {
deba@1982
   354
        edges[edges[edge.id].prev_in].next_in = edges[edge.id].next_in;
deba@1982
   355
      } else {
deba@2098
   356
        bNodes[edges[edge.id].bNode >> 1].first_edge = edges[edge.id].next_in;
deba@1982
   357
      }
deba@1982
   358
      if (edges[edge.id].next_in != -1) {
deba@1982
   359
        edges[edges[edge.id].next_in].prev_in = edges[edge.id].prev_in;
deba@1982
   360
      }
deba@2098
   361
deba@1982
   362
      edges[edge.id].next_out = first_free_edge;
deba@1982
   363
      first_free_edge = edge.id;
deba@1982
   364
    }
deba@1982
   365
deba@1982
   366
    void clear() {
deba@1982
   367
      aNodes.clear();
deba@1982
   368
      bNodes.clear();
deba@1982
   369
      edges.clear();
deba@1982
   370
      first_anode = -1;
deba@1982
   371
      first_free_anode = -1;
deba@1982
   372
      first_bnode = -1;
deba@1982
   373
      first_free_bnode = -1;
deba@1982
   374
      first_free_edge = -1;
deba@1982
   375
    }
deba@1982
   376
deba@1982
   377
  };
deba@1982
   378
deba@1982
   379
deba@2076
   380
  typedef BpUGraphExtender< ListBpUGraphBase > ExtendedListBpUGraphBase;
deba@1982
   381
deba@1982
   382
  /// \ingroup graphs
deba@1982
   383
  ///
deba@1982
   384
  /// \brief A smart bipartite undirected graph class.
deba@1982
   385
  ///
deba@1982
   386
  /// This is a bipartite undirected graph implementation.
deba@1991
   387
  /// It is conforms to the \ref concept::ErasableBpUGraph "ErasableBpUGraph" 
deba@1991
   388
  /// concept.
deba@1982
   389
  /// \sa concept::BpUGraph.
deba@1982
   390
  ///
deba@1982
   391
  class ListBpUGraph : public ExtendedListBpUGraphBase {};
deba@1982
   392
alpar@949
   393
  
alpar@948
   394
  /// @}  
alpar@948
   395
} //namespace lemon
klao@946
   396
  
alpar@400
   397
klao@946
   398
#endif