lemon/edge_set.h
author deba
Mon, 19 Dec 2005 09:47:10 +0000
changeset 1865 dcefd1d1377f
child 1866 c2de2ed28e59
permissions -rw-r--r--
Doc fix
deba@1842
     1
/* -*- C++ -*-
deba@1842
     2
 * lemon/edge_set.h - Part of LEMON, a generic C++ optimization library
deba@1842
     3
 *
deba@1842
     4
 * Copyright (C) 2005 Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
deba@1842
     5
 * (Egervary Research Group on Combinatorial Optimization, EGRES).
deba@1842
     6
 *
deba@1842
     7
 * Permission to use, modify and distribute this software is granted
deba@1842
     8
 * provided that this copyright notice appears in all copies. For
deba@1842
     9
 * precise terms see the accompanying LICENSE file.
deba@1842
    10
 *
deba@1842
    11
 * This software is provided "AS IS" with no warranty of any kind,
deba@1842
    12
 * express or implied, and with no claim as to its suitability for any
deba@1842
    13
 * purpose.
deba@1842
    14
 *
deba@1842
    15
 */
deba@1842
    16
deba@1842
    17
#ifndef LEMON_EDGE_SET_H
deba@1842
    18
#define LEMON_EDGE_SET_H
deba@1842
    19
deba@1842
    20
/// \ingroup graphs
deba@1842
    21
/// \file
deba@1842
    22
/// \brief EdgeSet classes.
deba@1842
    23
///
deba@1842
    24
/// Graphs which use another graph's node-set as own. 
deba@1842
    25
deba@1842
    26
namespace lemon {
deba@1842
    27
deba@1842
    28
  template <typename _Graph>
deba@1842
    29
  class ListEdgeSetBase {
deba@1842
    30
  public:
deba@1842
    31
deba@1842
    32
    typedef _Graph Graph;
deba@1842
    33
    typedef typename Graph::Node Node;
deba@1842
    34
    typedef typename Graph::NodeIt NodeIt;
deba@1842
    35
deba@1842
    36
  protected:
deba@1842
    37
deba@1842
    38
    struct NodeT {
deba@1842
    39
      int first_out, first_in;
deba@1842
    40
      NodeT() : first_out(-1), first_in(-1) {}
deba@1842
    41
    };
deba@1842
    42
deba@1842
    43
    typedef typename Graph::template NodeMap<NodeT> NodesImplBase;
deba@1842
    44
deba@1842
    45
    NodesImplBase* nodes;
deba@1842
    46
deba@1842
    47
    struct EdgeT {
deba@1842
    48
      Node source, target;
deba@1842
    49
      int next_out, next_in;
deba@1842
    50
      int prev_out, prev_in;
deba@1842
    51
      EdgeT() : prev_out(-1), prev_in(-1) {}
deba@1842
    52
    };
deba@1842
    53
deba@1842
    54
    std::vector<EdgeT> edges;
deba@1842
    55
deba@1842
    56
    int first_edge;
deba@1842
    57
    int first_free_edge;
deba@1842
    58
deba@1842
    59
    const Graph* graph;
deba@1842
    60
deba@1842
    61
    void initalize(const Graph& _graph, NodesImplBase& _nodes) {
deba@1842
    62
      graph = &_graph;
deba@1842
    63
      nodes = &_nodes;
deba@1842
    64
    }
deba@1842
    65
    
deba@1842
    66
  public:
deba@1842
    67
deba@1842
    68
    class Edge {
deba@1842
    69
      friend class ListEdgeSetBase<Graph>;
deba@1842
    70
    protected:
deba@1842
    71
      Edge(int _id) : id(_id) {}
deba@1842
    72
      int id;
deba@1842
    73
    public:
deba@1842
    74
      Edge() {}
deba@1842
    75
      Edge(Invalid) : id(-1) {}
deba@1842
    76
      bool operator==(const Edge& edge) const { return id == edge.id; }
deba@1842
    77
      bool operator!=(const Edge& edge) const { return id != edge.id; }
deba@1842
    78
      bool operator<(const Edge& edge) const { return id < edge.id; }
deba@1842
    79
    };
deba@1842
    80
deba@1842
    81
    ListEdgeSetBase() : first_edge(-1), first_free_edge(-1) {} 
deba@1842
    82
deba@1842
    83
    Edge addEdge(const Node& source, const Node& target) {
deba@1842
    84
      int n;
deba@1842
    85
      if (first_free_edge == -1) {
deba@1842
    86
	n = edges.size();
deba@1842
    87
	edges.push_back(EdgeT());
deba@1842
    88
      } else {
deba@1842
    89
	n = first_free_edge;
deba@1842
    90
	first_free_edge = edges[first_free_edge].next_in;
deba@1842
    91
      }
deba@1842
    92
      edges[n].next_in = (*nodes)[target].first_in;
deba@1842
    93
      (*nodes)[target].first_in = n;
deba@1842
    94
      edges[n].next_out = (*nodes)[source].first_out;
deba@1842
    95
      (*nodes)[source].first_out = n;
deba@1842
    96
      edges[n].source = source;
deba@1842
    97
      edges[n].target = target;
deba@1842
    98
      return Edge(n);
deba@1842
    99
    }
deba@1842
   100
deba@1842
   101
    void erase(const Edge& edge) {
deba@1842
   102
      int n = edge.id;
deba@1842
   103
      if (edges[n].prev_in != -1) {
deba@1842
   104
	edges[edges[n].prev_in].next_in = edges[n].next_in;
deba@1842
   105
      } else {
deba@1842
   106
	(*nodes)[edges[n].target].first_in = edges[n].next_in;
deba@1842
   107
      }
deba@1842
   108
      if (edges[n].next_in != -1) {
deba@1842
   109
	edges[edges[n].next_in].prev_in = edges[n].prev_in;
deba@1842
   110
      }
deba@1842
   111
deba@1842
   112
      if (edges[n].prev_out != -1) {
deba@1842
   113
	edges[edges[n].prev_out].next_out = edges[n].next_out;
deba@1842
   114
      } else {
deba@1842
   115
	(*nodes)[edges[n].source].first_out = edges[n].next_out;
deba@1842
   116
      }
deba@1842
   117
      if (edges[n].next_out != -1) {
deba@1842
   118
	edges[edges[n].next_out].prev_out = edges[n].prev_out;
deba@1842
   119
      }
deba@1842
   120
           
deba@1842
   121
    }
deba@1842
   122
deba@1842
   123
    void clear() {
deba@1842
   124
      edges.clear();
deba@1842
   125
      first_edge = -1;
deba@1842
   126
      first_free_edge = -1;
deba@1842
   127
    }
deba@1842
   128
deba@1842
   129
    void first(Node& node) const {
deba@1842
   130
      graph->first(node);
deba@1842
   131
    }
deba@1842
   132
deba@1842
   133
    void next(Node& node) const {
deba@1842
   134
      graph->next(node);
deba@1842
   135
    }
deba@1842
   136
deba@1842
   137
    void first(Edge& edge) const {
deba@1842
   138
      Node node;
deba@1842
   139
      for (first(node); node != INVALID && (*nodes)[node].first_in == -1; 
deba@1842
   140
	   next(node));
deba@1842
   141
      edge.id = (node == INVALID) ? -1 : (*nodes)[node].first_in;
deba@1842
   142
    }
deba@1842
   143
deba@1842
   144
    void next(Edge& edge) const {
deba@1842
   145
      if (edges[edge.id].next_in != -1) {
deba@1842
   146
	edge.id = edges[edge.id].next_in;
deba@1842
   147
      } else {
deba@1842
   148
	Node node = edges[edge.id].target;
deba@1842
   149
	for (next(node); node != INVALID && (*nodes)[node].first_in == -1; 
deba@1842
   150
	     next(node));
deba@1842
   151
	edge.id = (node == INVALID) ? -1 : (*nodes)[node].first_in;
deba@1842
   152
      }      
deba@1842
   153
    }
deba@1842
   154
deba@1842
   155
    void firstOut(Edge& edge, const Node& node) const {
deba@1842
   156
      edge.id = (*nodes)[node].first_out;    
deba@1842
   157
    }
deba@1842
   158
    
deba@1842
   159
    void nextOut(Edge& edge) const {
deba@1842
   160
      edge.id = edges[edge.id].next_out;        
deba@1842
   161
    }
deba@1842
   162
deba@1842
   163
    void firstIn(Edge& edge, const Node& node) const {
deba@1842
   164
      edge.id = (*nodes)[node].first_in;          
deba@1842
   165
    }
deba@1842
   166
deba@1842
   167
    void nextIn(Edge& edge) const {
deba@1842
   168
      edge.id = edges[edge.id].next_in;    
deba@1842
   169
    }
deba@1842
   170
deba@1842
   171
    int id(const Node& node) const { return graph->id(node); }
deba@1842
   172
    int id(const Edge& edge) const { return edge.id; }
deba@1842
   173
deba@1842
   174
    Node nodeFromId(int id) const { return graph->fromId(id, Node()); }
deba@1842
   175
    Edge edgeFromId(int id) const { return Edge(id); }
deba@1842
   176
deba@1842
   177
    int maxNodeId() const { return graph->maxId(Node()); };
deba@1842
   178
    int maxEdgeId() const { return edges.size() - 1; }
deba@1842
   179
deba@1842
   180
    Node source(const Edge& edge) const { return edges[edge.id].source;}
deba@1842
   181
    Node target(const Edge& edge) const { return edges[edge.id].target;}
deba@1842
   182
deba@1842
   183
    template <typename _Value>
deba@1842
   184
    class NodeMap : public Graph::template NodeMap<_Value> {
deba@1842
   185
    public:
deba@1842
   186
      typedef typename _Graph::template NodeMap<_Value> Parent;
deba@1842
   187
      explicit NodeMap(const ListEdgeSetBase<Graph>& edgeset) 
deba@1842
   188
	: Parent(*edgeset.graph) { }
deba@1842
   189
      NodeMap(const ListEdgeSetBase<Graph>& edgeset, const _Value& value)
deba@1842
   190
	: Parent(*edgeset.graph, value) { }
deba@1842
   191
    };
deba@1842
   192
deba@1842
   193
  };
deba@1842
   194
deba@1842
   195
  /// \ingroup graphs
deba@1842
   196
  ///
deba@1842
   197
  /// \brief Graph using a node set of another graph and an
deba@1842
   198
  /// own edge set.
deba@1842
   199
  ///
deba@1842
   200
  /// This structure can be used to establish another graph over a node set
deba@1842
   201
  /// of an existing one. The node iterator will go through the nodes of the
deba@1842
   202
  /// original graph.
deba@1842
   203
  ///
deba@1842
   204
  /// \param _Graph The type of the graph which shares its node set with 
deba@1842
   205
  /// this class. Its interface must conform to the \ref concept::StaticGraph
deba@1842
   206
  /// "StaticGraph" concept.
deba@1842
   207
  ///
deba@1842
   208
  /// In the edge extension and removing it conforms to the 
deba@1842
   209
  /// \ref concept::ExtendableGraph "ExtendableGraph" concept.
deba@1842
   210
  template <typename _Graph>
deba@1842
   211
  class ListEdgeSet :
deba@1842
   212
    public ErasableEdgeSetExtender<
deba@1842
   213
    ClearableEdgeSetExtender<
deba@1842
   214
    ExtendableEdgeSetExtender<
deba@1842
   215
    MappableEdgeSetExtender<
deba@1842
   216
    IterableGraphExtender<
deba@1842
   217
    AlterableEdgeSetExtender<
deba@1842
   218
    GraphExtender<
deba@1842
   219
    ListEdgeSetBase<_Graph> > > > > > > > {
deba@1842
   220
deba@1842
   221
  public:
deba@1842
   222
deba@1842
   223
    typedef ErasableEdgeSetExtender<
deba@1842
   224
      ClearableEdgeSetExtender<
deba@1842
   225
      ExtendableEdgeSetExtender<
deba@1842
   226
      MappableEdgeSetExtender<
deba@1842
   227
      IterableGraphExtender<
deba@1842
   228
      AlterableEdgeSetExtender<
deba@1842
   229
      GraphExtender<
deba@1842
   230
      ListEdgeSetBase<_Graph> > > > > > > > Parent;
deba@1842
   231
    
deba@1842
   232
    typedef typename Parent::Node Node;
deba@1842
   233
    typedef typename Parent::Edge Edge;
deba@1842
   234
    
deba@1842
   235
    typedef _Graph Graph;
deba@1842
   236
deba@1842
   237
deba@1842
   238
    typedef typename Parent::NodesImplBase NodesImplBase;
deba@1842
   239
deba@1842
   240
    void eraseNode(const Node& node) {
deba@1842
   241
      Edge edge;
deba@1842
   242
      Parent::firstOut(edge, node);
deba@1842
   243
      while (edge != INVALID ) {
deba@1842
   244
	erase(edge);
deba@1842
   245
	Parent::firstOut(edge, node);
deba@1842
   246
      } 
deba@1842
   247
deba@1842
   248
      Parent::firstIn(edge, node);
deba@1842
   249
      while (edge != INVALID ) {
deba@1842
   250
	erase(edge);
deba@1842
   251
	Parent::firstIn(edge, node);
deba@1842
   252
      }
deba@1842
   253
    }
deba@1842
   254
    
deba@1842
   255
    void clearNodes() {
deba@1842
   256
      Parent::clear();
deba@1842
   257
    }
deba@1842
   258
deba@1842
   259
    class NodesImpl : public NodesImplBase {
deba@1842
   260
    public:
deba@1842
   261
      typedef NodesImplBase Parent;
deba@1842
   262
      
deba@1842
   263
      NodesImpl(const Graph& graph, ListEdgeSet& edgeset) 
deba@1842
   264
	: Parent(graph), _edgeset(edgeset) {}
deba@1842
   265
      
deba@1842
   266
    protected:
deba@1842
   267
deba@1842
   268
      virtual void erase(const Node& node) {
deba@1842
   269
	_edgeset.eraseNode(node);
deba@1842
   270
	Parent::erase(node);
deba@1842
   271
      }
deba@1842
   272
      virtual void clear() {
deba@1842
   273
	_edgeset.clearNodes();
deba@1842
   274
	Parent::clear();
deba@1842
   275
      }
deba@1842
   276
deba@1842
   277
    private:
deba@1842
   278
      ListEdgeSet& _edgeset;
deba@1842
   279
    };
deba@1842
   280
deba@1842
   281
    NodesImpl nodes;
deba@1842
   282
    
deba@1842
   283
  public:
deba@1842
   284
deba@1842
   285
    /// \brief Constructor of the adaptor.
deba@1842
   286
    /// 
deba@1842
   287
    /// Constructor of the adaptor.
deba@1842
   288
    ListEdgeSet(const Graph& graph) : nodes(graph, *this) {
deba@1842
   289
      Parent::initalize(graph, nodes);
deba@1842
   290
    }
deba@1842
   291
    
deba@1842
   292
  };
deba@1842
   293
deba@1842
   294
  /// \ingroup graphs
deba@1842
   295
  ///
deba@1842
   296
  /// \brief Graph using a node set of another graph and an
deba@1842
   297
  /// own undir edge set.
deba@1842
   298
  ///
deba@1842
   299
  /// This structure can be used to establish another graph over a node set
deba@1842
   300
  /// of an existing one. The node iterator will go through the nodes of the
deba@1842
   301
  /// original graph.
deba@1842
   302
  ///
deba@1842
   303
  /// \param _Graph The type of the graph which shares its node set with 
deba@1842
   304
  /// this class. Its interface must conform to the \ref concept::StaticGraph
deba@1842
   305
  /// "StaticGraph" concept.
deba@1842
   306
  ///
deba@1842
   307
  /// In the edge extension and removing it conforms to the 
deba@1842
   308
  /// \ref concept::ExtendableGraph "ExtendableGraph" concept.
deba@1842
   309
  template <typename _Graph>
deba@1842
   310
  class ListUndirEdgeSet :
deba@1842
   311
    public ErasableUndirEdgeSetExtender<
deba@1842
   312
    ClearableUndirEdgeSetExtender<
deba@1842
   313
    ExtendableUndirEdgeSetExtender<
deba@1842
   314
    MappableUndirEdgeSetExtender<
deba@1842
   315
    IterableUndirGraphExtender<
deba@1842
   316
    AlterableUndirEdgeSetExtender<
deba@1842
   317
    UndirGraphExtender<
deba@1842
   318
    ListEdgeSetBase<_Graph> > > > > > > > {
deba@1842
   319
deba@1842
   320
  public:
deba@1842
   321
deba@1842
   322
    typedef ErasableUndirEdgeSetExtender<
deba@1842
   323
      ClearableUndirEdgeSetExtender<
deba@1842
   324
      ExtendableUndirEdgeSetExtender<
deba@1842
   325
      MappableUndirEdgeSetExtender<
deba@1842
   326
      IterableUndirGraphExtender<
deba@1842
   327
      AlterableUndirEdgeSetExtender<
deba@1842
   328
      UndirGraphExtender<
deba@1842
   329
      ListEdgeSetBase<_Graph> > > > > > > > Parent;
deba@1842
   330
    
deba@1842
   331
    typedef typename Parent::Node Node;
deba@1842
   332
    typedef typename Parent::Edge Edge;
deba@1842
   333
    
deba@1842
   334
    typedef _Graph Graph;
deba@1842
   335
deba@1842
   336
deba@1842
   337
    typedef typename Parent::NodesImplBase NodesImplBase;
deba@1842
   338
deba@1842
   339
    void eraseNode(const Node& node) {
deba@1842
   340
      Edge edge;
deba@1842
   341
      Parent::firstOut(edge, node);
deba@1842
   342
      while (edge != INVALID ) {
deba@1842
   343
	erase(edge);
deba@1842
   344
	Parent::firstOut(edge, node);
deba@1842
   345
      } 
deba@1842
   346
deba@1842
   347
    }
deba@1842
   348
    
deba@1842
   349
    void clearNodes() {
deba@1842
   350
      Parent::clear();
deba@1842
   351
    }
deba@1842
   352
deba@1842
   353
    class NodesImpl : public NodesImplBase {
deba@1842
   354
    public:
deba@1842
   355
      typedef NodesImplBase Parent;
deba@1842
   356
      
deba@1842
   357
      NodesImpl(const Graph& graph, ListUndirEdgeSet& edgeset) 
deba@1842
   358
	: Parent(graph), _edgeset(edgeset) {}
deba@1842
   359
      
deba@1842
   360
    protected:
deba@1842
   361
deba@1842
   362
      virtual void erase(const Node& node) {
deba@1842
   363
	_edgeset.eraseNode(node);
deba@1842
   364
	Parent::erase(node);
deba@1842
   365
      }
deba@1842
   366
      virtual void clear() {
deba@1842
   367
	_edgeset.clearNodes();
deba@1842
   368
	Parent::clear();
deba@1842
   369
      }
deba@1842
   370
deba@1842
   371
    private:
deba@1842
   372
      ListUndirEdgeSet& _edgeset;
deba@1842
   373
    };
deba@1842
   374
deba@1842
   375
    NodesImpl nodes;
deba@1842
   376
    
deba@1842
   377
  public:
deba@1842
   378
deba@1842
   379
    /// \brief Constructor of the adaptor.
deba@1842
   380
    /// 
deba@1842
   381
    /// Constructor of the adaptor.
deba@1842
   382
    ListUndirEdgeSet(const Graph& graph) : nodes(graph, *this) {
deba@1842
   383
      Parent::initalize(graph, nodes);
deba@1842
   384
    }
deba@1842
   385
    
deba@1842
   386
  };
deba@1842
   387
deba@1842
   388
}
deba@1842
   389
deba@1842
   390
#endif