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