lemon/edge_set.h
author Peter Kovacs <kpeter@inf.elte.hu>
Tue, 15 Mar 2011 19:32:21 +0100
changeset 936 ddd3c0d3d9bf
parent 787 c2230649a493
child 1092 dceba191c00d
permissions -rw-r--r--
Implement the scaling Price Refinement heuristic in CostScaling (#417)
instead of Early Termination.

These two heuristics are similar, but the newer one is faster
and not only makes it possible to skip some epsilon phases, but
it can improve the performance of the other phases, as well.
deba@468
     1
/* -*- mode: C++; indent-tabs-mode: nil; -*-
deba@468
     2
 *
deba@468
     3
 * This file is a part of LEMON, a generic C++ optimization library.
deba@468
     4
 *
alpar@877
     5
 * Copyright (C) 2003-2010
deba@468
     6
 * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
deba@468
     7
 * (Egervary Research Group on Combinatorial Optimization, EGRES).
deba@468
     8
 *
deba@468
     9
 * Permission to use, modify and distribute this software is granted
deba@468
    10
 * provided that this copyright notice appears in all copies. For
deba@468
    11
 * precise terms see the accompanying LICENSE file.
deba@468
    12
 *
deba@468
    13
 * This software is provided "AS IS" with no warranty of any kind,
deba@468
    14
 * express or implied, and with no claim as to its suitability for any
deba@468
    15
 * purpose.
deba@468
    16
 *
deba@468
    17
 */
deba@468
    18
deba@468
    19
#ifndef LEMON_EDGE_SET_H
deba@468
    20
#define LEMON_EDGE_SET_H
deba@468
    21
deba@468
    22
#include <lemon/core.h>
deba@468
    23
#include <lemon/bits/edge_set_extender.h>
deba@468
    24
kpeter@660
    25
/// \ingroup graphs
deba@468
    26
/// \file
deba@468
    27
/// \brief ArcSet and EdgeSet classes.
deba@468
    28
///
deba@468
    29
/// Graphs which use another graph's node-set as own.
deba@468
    30
namespace lemon {
deba@468
    31
deba@488
    32
  template <typename GR>
deba@468
    33
  class ListArcSetBase {
deba@468
    34
  public:
deba@468
    35
deba@488
    36
    typedef typename GR::Node Node;
deba@488
    37
    typedef typename GR::NodeIt NodeIt;
deba@468
    38
deba@468
    39
  protected:
deba@468
    40
deba@468
    41
    struct NodeT {
deba@468
    42
      int first_out, first_in;
deba@468
    43
      NodeT() : first_out(-1), first_in(-1) {}
deba@468
    44
    };
deba@468
    45
deba@488
    46
    typedef typename ItemSetTraits<GR, Node>::
deba@468
    47
    template Map<NodeT>::Type NodesImplBase;
deba@468
    48
deba@488
    49
    NodesImplBase* _nodes;
deba@468
    50
deba@468
    51
    struct ArcT {
deba@468
    52
      Node source, target;
deba@468
    53
      int next_out, next_in;
deba@468
    54
      int prev_out, prev_in;
deba@468
    55
      ArcT() : prev_out(-1), prev_in(-1) {}
deba@468
    56
    };
deba@468
    57
deba@468
    58
    std::vector<ArcT> arcs;
deba@468
    59
deba@468
    60
    int first_arc;
deba@468
    61
    int first_free_arc;
deba@468
    62
deba@488
    63
    const GR* _graph;
deba@468
    64
deba@488
    65
    void initalize(const GR& graph, NodesImplBase& nodes) {
deba@488
    66
      _graph = &graph;
deba@488
    67
      _nodes = &nodes;
deba@468
    68
    }
deba@468
    69
deba@468
    70
  public:
deba@468
    71
deba@468
    72
    class Arc {
deba@488
    73
      friend class ListArcSetBase<GR>;
deba@468
    74
    protected:
deba@468
    75
      Arc(int _id) : id(_id) {}
deba@468
    76
      int id;
deba@468
    77
    public:
deba@468
    78
      Arc() {}
deba@468
    79
      Arc(Invalid) : id(-1) {}
deba@468
    80
      bool operator==(const Arc& arc) const { return id == arc.id; }
deba@468
    81
      bool operator!=(const Arc& arc) const { return id != arc.id; }
deba@468
    82
      bool operator<(const Arc& arc) const { return id < arc.id; }
deba@468
    83
    };
deba@468
    84
deba@468
    85
    ListArcSetBase() : first_arc(-1), first_free_arc(-1) {}
deba@468
    86
kpeter@670
    87
    Node addNode() {
kpeter@670
    88
      LEMON_ASSERT(false,
kpeter@670
    89
        "This graph structure does not support node insertion");
kpeter@670
    90
      return INVALID; // avoid warning
kpeter@670
    91
    }
kpeter@670
    92
deba@468
    93
    Arc addArc(const Node& u, const Node& v) {
deba@468
    94
      int n;
deba@468
    95
      if (first_free_arc == -1) {
deba@468
    96
        n = arcs.size();
deba@468
    97
        arcs.push_back(ArcT());
deba@468
    98
      } else {
deba@468
    99
        n = first_free_arc;
deba@468
   100
        first_free_arc = arcs[first_free_arc].next_in;
deba@468
   101
      }
deba@488
   102
      arcs[n].next_in = (*_nodes)[v].first_in;
deba@488
   103
      if ((*_nodes)[v].first_in != -1) {
deba@488
   104
        arcs[(*_nodes)[v].first_in].prev_in = n;
deba@468
   105
      }
deba@488
   106
      (*_nodes)[v].first_in = n;
deba@488
   107
      arcs[n].next_out = (*_nodes)[u].first_out;
deba@488
   108
      if ((*_nodes)[u].first_out != -1) {
deba@488
   109
        arcs[(*_nodes)[u].first_out].prev_out = n;
deba@468
   110
      }
deba@488
   111
      (*_nodes)[u].first_out = n;
deba@468
   112
      arcs[n].source = u;
deba@468
   113
      arcs[n].target = v;
deba@468
   114
      return Arc(n);
deba@468
   115
    }
deba@468
   116
deba@468
   117
    void erase(const Arc& arc) {
deba@468
   118
      int n = arc.id;
deba@468
   119
      if (arcs[n].prev_in != -1) {
deba@468
   120
        arcs[arcs[n].prev_in].next_in = arcs[n].next_in;
deba@468
   121
      } else {
deba@488
   122
        (*_nodes)[arcs[n].target].first_in = arcs[n].next_in;
deba@468
   123
      }
deba@468
   124
      if (arcs[n].next_in != -1) {
deba@468
   125
        arcs[arcs[n].next_in].prev_in = arcs[n].prev_in;
deba@468
   126
      }
deba@468
   127
deba@468
   128
      if (arcs[n].prev_out != -1) {
deba@468
   129
        arcs[arcs[n].prev_out].next_out = arcs[n].next_out;
deba@468
   130
      } else {
deba@488
   131
        (*_nodes)[arcs[n].source].first_out = arcs[n].next_out;
deba@468
   132
      }
deba@468
   133
      if (arcs[n].next_out != -1) {
deba@468
   134
        arcs[arcs[n].next_out].prev_out = arcs[n].prev_out;
deba@468
   135
      }
deba@468
   136
deba@468
   137
    }
deba@468
   138
deba@468
   139
    void clear() {
deba@468
   140
      Node node;
deba@468
   141
      for (first(node); node != INVALID; next(node)) {
deba@488
   142
        (*_nodes)[node].first_in = -1;
deba@488
   143
        (*_nodes)[node].first_out = -1;
deba@468
   144
      }
deba@468
   145
      arcs.clear();
deba@468
   146
      first_arc = -1;
deba@468
   147
      first_free_arc = -1;
deba@468
   148
    }
deba@468
   149
deba@468
   150
    void first(Node& node) const {
deba@488
   151
      _graph->first(node);
deba@468
   152
    }
deba@468
   153
deba@468
   154
    void next(Node& node) const {
deba@488
   155
      _graph->next(node);
deba@468
   156
    }
deba@468
   157
deba@468
   158
    void first(Arc& arc) const {
deba@468
   159
      Node node;
deba@468
   160
      first(node);
deba@488
   161
      while (node != INVALID && (*_nodes)[node].first_in == -1) {
deba@468
   162
        next(node);
deba@468
   163
      }
deba@488
   164
      arc.id = (node == INVALID) ? -1 : (*_nodes)[node].first_in;
deba@468
   165
    }
deba@468
   166
deba@468
   167
    void next(Arc& arc) const {
deba@468
   168
      if (arcs[arc.id].next_in != -1) {
deba@468
   169
        arc.id = arcs[arc.id].next_in;
deba@468
   170
      } else {
deba@468
   171
        Node node = arcs[arc.id].target;
deba@468
   172
        next(node);
deba@488
   173
        while (node != INVALID && (*_nodes)[node].first_in == -1) {
deba@468
   174
          next(node);
deba@468
   175
        }
deba@488
   176
        arc.id = (node == INVALID) ? -1 : (*_nodes)[node].first_in;
deba@468
   177
      }
deba@468
   178
    }
deba@468
   179
deba@468
   180
    void firstOut(Arc& arc, const Node& node) const {
deba@488
   181
      arc.id = (*_nodes)[node].first_out;
deba@468
   182
    }
deba@468
   183
deba@468
   184
    void nextOut(Arc& arc) const {
deba@468
   185
      arc.id = arcs[arc.id].next_out;
deba@468
   186
    }
deba@468
   187
deba@468
   188
    void firstIn(Arc& arc, const Node& node) const {
deba@488
   189
      arc.id = (*_nodes)[node].first_in;
deba@468
   190
    }
deba@468
   191
deba@468
   192
    void nextIn(Arc& arc) const {
deba@468
   193
      arc.id = arcs[arc.id].next_in;
deba@468
   194
    }
deba@468
   195
deba@488
   196
    int id(const Node& node) const { return _graph->id(node); }
deba@468
   197
    int id(const Arc& arc) const { return arc.id; }
deba@468
   198
deba@488
   199
    Node nodeFromId(int ix) const { return _graph->nodeFromId(ix); }
deba@468
   200
    Arc arcFromId(int ix) const { return Arc(ix); }
deba@468
   201
deba@488
   202
    int maxNodeId() const { return _graph->maxNodeId(); };
deba@468
   203
    int maxArcId() const { return arcs.size() - 1; }
deba@468
   204
deba@468
   205
    Node source(const Arc& arc) const { return arcs[arc.id].source;}
deba@468
   206
    Node target(const Arc& arc) const { return arcs[arc.id].target;}
deba@468
   207
deba@488
   208
    typedef typename ItemSetTraits<GR, Node>::ItemNotifier NodeNotifier;
deba@468
   209
deba@468
   210
    NodeNotifier& notifier(Node) const {
deba@488
   211
      return _graph->notifier(Node());
deba@468
   212
    }
deba@468
   213
deba@488
   214
    template <typename V>
deba@488
   215
    class NodeMap : public GR::template NodeMap<V> {
kpeter@617
   216
      typedef typename GR::template NodeMap<V> Parent;
kpeter@617
   217
deba@468
   218
    public:
deba@468
   219
deba@488
   220
      explicit NodeMap(const ListArcSetBase<GR>& arcset)
deba@488
   221
        : Parent(*arcset._graph) {}
deba@468
   222
deba@488
   223
      NodeMap(const ListArcSetBase<GR>& arcset, const V& value)
deba@488
   224
        : Parent(*arcset._graph, value) {}
deba@468
   225
deba@468
   226
      NodeMap& operator=(const NodeMap& cmap) {
deba@468
   227
        return operator=<NodeMap>(cmap);
deba@468
   228
      }
deba@468
   229
deba@468
   230
      template <typename CMap>
deba@468
   231
      NodeMap& operator=(const CMap& cmap) {
deba@468
   232
        Parent::operator=(cmap);
deba@468
   233
        return *this;
deba@468
   234
      }
deba@468
   235
    };
deba@468
   236
deba@468
   237
  };
deba@468
   238
kpeter@660
   239
  /// \ingroup graphs
deba@468
   240
  ///
deba@468
   241
  /// \brief Digraph using a node set of another digraph or graph and
deba@468
   242
  /// an own arc set.
deba@468
   243
  ///
deba@468
   244
  /// This structure can be used to establish another directed graph
deba@468
   245
  /// over a node set of an existing one. This class uses the same
deba@468
   246
  /// Node type as the underlying graph, and each valid node of the
deba@468
   247
  /// original graph is valid in this arc set, therefore the node
deba@468
   248
  /// objects of the original graph can be used directly with this
deba@468
   249
  /// class. The node handling functions (id handling, observing, and
deba@468
   250
  /// iterators) works equivalently as in the original graph.
deba@468
   251
  ///
deba@468
   252
  /// This implementation is based on doubly-linked lists, from each
deba@468
   253
  /// node the outgoing and the incoming arcs make up lists, therefore
deba@468
   254
  /// one arc can be erased in constant time. It also makes possible,
deba@468
   255
  /// that node can be removed from the underlying graph, in this case
deba@468
   256
  /// all arcs incident to the given node is erased from the arc set.
deba@468
   257
  ///
kpeter@787
   258
  /// This class fully conforms to the \ref concepts::Digraph
kpeter@787
   259
  /// "Digraph" concept.
kpeter@787
   260
  /// It provides only linear time counting for nodes and arcs.
kpeter@787
   261
  ///
deba@488
   262
  /// \param GR The type of the graph which shares its node set with
deba@468
   263
  /// this class. Its interface must conform to the
deba@468
   264
  /// \ref concepts::Digraph "Digraph" or \ref concepts::Graph "Graph"
deba@468
   265
  /// concept.
deba@488
   266
  template <typename GR>
deba@488
   267
  class ListArcSet : public ArcSetExtender<ListArcSetBase<GR> > {
kpeter@617
   268
    typedef ArcSetExtender<ListArcSetBase<GR> > Parent;
deba@468
   269
deba@468
   270
  public:
deba@468
   271
deba@468
   272
    typedef typename Parent::Node Node;
deba@468
   273
    typedef typename Parent::Arc Arc;
deba@468
   274
deba@468
   275
    typedef typename Parent::NodesImplBase NodesImplBase;
deba@468
   276
deba@468
   277
    void eraseNode(const Node& node) {
deba@468
   278
      Arc arc;
deba@468
   279
      Parent::firstOut(arc, node);
deba@468
   280
      while (arc != INVALID ) {
deba@468
   281
        erase(arc);
deba@468
   282
        Parent::firstOut(arc, node);
deba@468
   283
      }
deba@468
   284
deba@468
   285
      Parent::firstIn(arc, node);
deba@468
   286
      while (arc != INVALID ) {
deba@468
   287
        erase(arc);
deba@468
   288
        Parent::firstIn(arc, node);
deba@468
   289
      }
deba@468
   290
    }
deba@468
   291
deba@468
   292
    void clearNodes() {
deba@468
   293
      Parent::clear();
deba@468
   294
    }
deba@468
   295
deba@468
   296
    class NodesImpl : public NodesImplBase {
deba@468
   297
      typedef NodesImplBase Parent;
deba@468
   298
kpeter@617
   299
    public:
deba@488
   300
      NodesImpl(const GR& graph, ListArcSet& arcset)
deba@468
   301
        : Parent(graph), _arcset(arcset) {}
deba@468
   302
deba@468
   303
      virtual ~NodesImpl() {}
deba@468
   304
deba@468
   305
    protected:
deba@468
   306
deba@468
   307
      virtual void erase(const Node& node) {
deba@468
   308
        _arcset.eraseNode(node);
deba@468
   309
        Parent::erase(node);
deba@468
   310
      }
deba@468
   311
      virtual void erase(const std::vector<Node>& nodes) {
deba@468
   312
        for (int i = 0; i < int(nodes.size()); ++i) {
deba@468
   313
          _arcset.eraseNode(nodes[i]);
deba@468
   314
        }
deba@468
   315
        Parent::erase(nodes);
deba@468
   316
      }
deba@468
   317
      virtual void clear() {
deba@468
   318
        _arcset.clearNodes();
deba@468
   319
        Parent::clear();
deba@468
   320
      }
deba@468
   321
deba@468
   322
    private:
deba@468
   323
      ListArcSet& _arcset;
deba@468
   324
    };
deba@468
   325
deba@488
   326
    NodesImpl _nodes;
deba@468
   327
deba@468
   328
  public:
deba@468
   329
deba@468
   330
    /// \brief Constructor of the ArcSet.
deba@468
   331
    ///
deba@468
   332
    /// Constructor of the ArcSet.
deba@488
   333
    ListArcSet(const GR& graph) : _nodes(graph, *this) {
deba@488
   334
      Parent::initalize(graph, _nodes);
deba@468
   335
    }
deba@468
   336
deba@468
   337
    /// \brief Add a new arc to the digraph.
deba@468
   338
    ///
deba@468
   339
    /// Add a new arc to the digraph with source node \c s
deba@468
   340
    /// and target node \c t.
kpeter@559
   341
    /// \return The new arc.
deba@468
   342
    Arc addArc(const Node& s, const Node& t) {
deba@468
   343
      return Parent::addArc(s, t);
deba@468
   344
    }
deba@468
   345
deba@468
   346
    /// \brief Erase an arc from the digraph.
deba@468
   347
    ///
deba@468
   348
    /// Erase an arc \c a from the digraph.
deba@468
   349
    void erase(const Arc& a) {
deba@468
   350
      return Parent::erase(a);
deba@468
   351
    }
deba@468
   352
deba@468
   353
  };
deba@468
   354
deba@488
   355
  template <typename GR>
deba@468
   356
  class ListEdgeSetBase {
deba@468
   357
  public:
deba@468
   358
deba@488
   359
    typedef typename GR::Node Node;
deba@488
   360
    typedef typename GR::NodeIt NodeIt;
deba@468
   361
deba@468
   362
  protected:
deba@468
   363
deba@468
   364
    struct NodeT {
deba@468
   365
      int first_out;
deba@468
   366
      NodeT() : first_out(-1) {}
deba@468
   367
    };
deba@468
   368
deba@488
   369
    typedef typename ItemSetTraits<GR, Node>::
deba@468
   370
    template Map<NodeT>::Type NodesImplBase;
deba@468
   371
deba@488
   372
    NodesImplBase* _nodes;
deba@468
   373
deba@468
   374
    struct ArcT {
deba@468
   375
      Node target;
deba@468
   376
      int prev_out, next_out;
deba@468
   377
      ArcT() : prev_out(-1), next_out(-1) {}
deba@468
   378
    };
deba@468
   379
deba@468
   380
    std::vector<ArcT> arcs;
deba@468
   381
deba@468
   382
    int first_arc;
deba@468
   383
    int first_free_arc;
deba@468
   384
deba@488
   385
    const GR* _graph;
deba@468
   386
deba@488
   387
    void initalize(const GR& graph, NodesImplBase& nodes) {
deba@488
   388
      _graph = &graph;
deba@488
   389
      _nodes = &nodes;
deba@468
   390
    }
deba@468
   391
deba@468
   392
  public:
deba@468
   393
deba@468
   394
    class Edge {
deba@468
   395
      friend class ListEdgeSetBase;
deba@468
   396
    protected:
deba@468
   397
deba@468
   398
      int id;
deba@468
   399
      explicit Edge(int _id) { id = _id;}
deba@468
   400
deba@468
   401
    public:
deba@468
   402
      Edge() {}
deba@468
   403
      Edge (Invalid) { id = -1; }
deba@468
   404
      bool operator==(const Edge& arc) const {return id == arc.id;}
deba@468
   405
      bool operator!=(const Edge& arc) const {return id != arc.id;}
deba@468
   406
      bool operator<(const Edge& arc) const {return id < arc.id;}
deba@468
   407
    };
deba@468
   408
deba@468
   409
    class Arc {
deba@468
   410
      friend class ListEdgeSetBase;
deba@468
   411
    protected:
deba@468
   412
      Arc(int _id) : id(_id) {}
deba@468
   413
      int id;
deba@468
   414
    public:
deba@468
   415
      operator Edge() const { return edgeFromId(id / 2); }
deba@468
   416
deba@468
   417
      Arc() {}
deba@468
   418
      Arc(Invalid) : id(-1) {}
deba@468
   419
      bool operator==(const Arc& arc) const { return id == arc.id; }
deba@468
   420
      bool operator!=(const Arc& arc) const { return id != arc.id; }
deba@468
   421
      bool operator<(const Arc& arc) const { return id < arc.id; }
deba@468
   422
    };
deba@468
   423
deba@468
   424
    ListEdgeSetBase() : first_arc(-1), first_free_arc(-1) {}
deba@468
   425
kpeter@670
   426
    Node addNode() {
kpeter@670
   427
      LEMON_ASSERT(false,
kpeter@670
   428
        "This graph structure does not support node insertion");
kpeter@670
   429
      return INVALID; // avoid warning
kpeter@670
   430
    }
kpeter@670
   431
deba@468
   432
    Edge addEdge(const Node& u, const Node& v) {
deba@468
   433
      int n;
deba@468
   434
deba@468
   435
      if (first_free_arc == -1) {
deba@468
   436
        n = arcs.size();
deba@468
   437
        arcs.push_back(ArcT());
deba@468
   438
        arcs.push_back(ArcT());
deba@468
   439
      } else {
deba@468
   440
        n = first_free_arc;
deba@468
   441
        first_free_arc = arcs[n].next_out;
deba@468
   442
      }
deba@468
   443
deba@468
   444
      arcs[n].target = u;
deba@468
   445
      arcs[n | 1].target = v;
deba@468
   446
deba@488
   447
      arcs[n].next_out = (*_nodes)[v].first_out;
deba@488
   448
      if ((*_nodes)[v].first_out != -1) {
deba@488
   449
        arcs[(*_nodes)[v].first_out].prev_out = n;
deba@468
   450
      }
deba@488
   451
      (*_nodes)[v].first_out = n;
deba@468
   452
      arcs[n].prev_out = -1;
deba@468
   453
deba@488
   454
      if ((*_nodes)[u].first_out != -1) {
deba@488
   455
        arcs[(*_nodes)[u].first_out].prev_out = (n | 1);
deba@468
   456
      }
deba@488
   457
      arcs[n | 1].next_out = (*_nodes)[u].first_out;
deba@488
   458
      (*_nodes)[u].first_out = (n | 1);
deba@468
   459
      arcs[n | 1].prev_out = -1;
deba@468
   460
deba@468
   461
      return Edge(n / 2);
deba@468
   462
    }
deba@468
   463
deba@468
   464
    void erase(const Edge& arc) {
deba@468
   465
      int n = arc.id * 2;
deba@468
   466
deba@468
   467
      if (arcs[n].next_out != -1) {
deba@468
   468
        arcs[arcs[n].next_out].prev_out = arcs[n].prev_out;
deba@468
   469
      }
deba@468
   470
deba@468
   471
      if (arcs[n].prev_out != -1) {
deba@468
   472
        arcs[arcs[n].prev_out].next_out = arcs[n].next_out;
deba@468
   473
      } else {
deba@488
   474
        (*_nodes)[arcs[n | 1].target].first_out = arcs[n].next_out;
deba@468
   475
      }
deba@468
   476
deba@468
   477
      if (arcs[n | 1].next_out != -1) {
deba@468
   478
        arcs[arcs[n | 1].next_out].prev_out = arcs[n | 1].prev_out;
deba@468
   479
      }
deba@468
   480
deba@468
   481
      if (arcs[n | 1].prev_out != -1) {
deba@468
   482
        arcs[arcs[n | 1].prev_out].next_out = arcs[n | 1].next_out;
deba@468
   483
      } else {
deba@488
   484
        (*_nodes)[arcs[n].target].first_out = arcs[n | 1].next_out;
deba@468
   485
      }
deba@468
   486
deba@468
   487
      arcs[n].next_out = first_free_arc;
deba@468
   488
      first_free_arc = n;
deba@468
   489
deba@468
   490
    }
deba@468
   491
deba@468
   492
    void clear() {
deba@468
   493
      Node node;
deba@468
   494
      for (first(node); node != INVALID; next(node)) {
deba@488
   495
        (*_nodes)[node].first_out = -1;
deba@468
   496
      }
deba@468
   497
      arcs.clear();
deba@468
   498
      first_arc = -1;
deba@468
   499
      first_free_arc = -1;
deba@468
   500
    }
deba@468
   501
deba@468
   502
    void first(Node& node) const {
deba@488
   503
      _graph->first(node);
deba@468
   504
    }
deba@468
   505
deba@468
   506
    void next(Node& node) const {
deba@488
   507
      _graph->next(node);
deba@468
   508
    }
deba@468
   509
deba@468
   510
    void first(Arc& arc) const {
deba@468
   511
      Node node;
deba@468
   512
      first(node);
deba@488
   513
      while (node != INVALID && (*_nodes)[node].first_out == -1) {
deba@468
   514
        next(node);
deba@468
   515
      }
deba@488
   516
      arc.id = (node == INVALID) ? -1 : (*_nodes)[node].first_out;
deba@468
   517
    }
deba@468
   518
deba@468
   519
    void next(Arc& arc) const {
deba@468
   520
      if (arcs[arc.id].next_out != -1) {
deba@468
   521
        arc.id = arcs[arc.id].next_out;
deba@468
   522
      } else {
deba@468
   523
        Node node = arcs[arc.id ^ 1].target;
deba@468
   524
        next(node);
deba@488
   525
        while(node != INVALID && (*_nodes)[node].first_out == -1) {
deba@468
   526
          next(node);
deba@468
   527
        }
deba@488
   528
        arc.id = (node == INVALID) ? -1 : (*_nodes)[node].first_out;
deba@468
   529
      }
deba@468
   530
    }
deba@468
   531
deba@468
   532
    void first(Edge& edge) const {
deba@468
   533
      Node node;
deba@468
   534
      first(node);
deba@468
   535
      while (node != INVALID) {
deba@488
   536
        edge.id = (*_nodes)[node].first_out;
deba@468
   537
        while ((edge.id & 1) != 1) {
deba@468
   538
          edge.id = arcs[edge.id].next_out;
deba@468
   539
        }
deba@468
   540
        if (edge.id != -1) {
deba@468
   541
          edge.id /= 2;
deba@468
   542
          return;
deba@468
   543
        }
deba@468
   544
        next(node);
deba@468
   545
      }
deba@468
   546
      edge.id = -1;
deba@468
   547
    }
deba@468
   548
deba@468
   549
    void next(Edge& edge) const {
deba@468
   550
      Node node = arcs[edge.id * 2].target;
deba@468
   551
      edge.id = arcs[(edge.id * 2) | 1].next_out;
deba@468
   552
      while ((edge.id & 1) != 1) {
deba@468
   553
        edge.id = arcs[edge.id].next_out;
deba@468
   554
      }
deba@468
   555
      if (edge.id != -1) {
deba@468
   556
        edge.id /= 2;
deba@468
   557
        return;
deba@468
   558
      }
deba@468
   559
      next(node);
deba@468
   560
      while (node != INVALID) {
deba@488
   561
        edge.id = (*_nodes)[node].first_out;
deba@468
   562
        while ((edge.id & 1) != 1) {
deba@468
   563
          edge.id = arcs[edge.id].next_out;
deba@468
   564
        }
deba@468
   565
        if (edge.id != -1) {
deba@468
   566
          edge.id /= 2;
deba@468
   567
          return;
deba@468
   568
        }
deba@468
   569
        next(node);
deba@468
   570
      }
deba@468
   571
      edge.id = -1;
deba@468
   572
    }
deba@468
   573
deba@468
   574
    void firstOut(Arc& arc, const Node& node) const {
deba@488
   575
      arc.id = (*_nodes)[node].first_out;
deba@468
   576
    }
deba@468
   577
deba@468
   578
    void nextOut(Arc& arc) const {
deba@468
   579
      arc.id = arcs[arc.id].next_out;
deba@468
   580
    }
deba@468
   581
deba@468
   582
    void firstIn(Arc& arc, const Node& node) const {
deba@488
   583
      arc.id = (((*_nodes)[node].first_out) ^ 1);
deba@468
   584
      if (arc.id == -2) arc.id = -1;
deba@468
   585
    }
deba@468
   586
deba@468
   587
    void nextIn(Arc& arc) const {
deba@468
   588
      arc.id = ((arcs[arc.id ^ 1].next_out) ^ 1);
deba@468
   589
      if (arc.id == -2) arc.id = -1;
deba@468
   590
    }
deba@468
   591
deba@468
   592
    void firstInc(Edge &arc, bool& dir, const Node& node) const {
deba@488
   593
      int de = (*_nodes)[node].first_out;
deba@468
   594
      if (de != -1 ) {
deba@468
   595
        arc.id = de / 2;
deba@468
   596
        dir = ((de & 1) == 1);
deba@468
   597
      } else {
deba@468
   598
        arc.id = -1;
deba@468
   599
        dir = true;
deba@468
   600
      }
deba@468
   601
    }
deba@468
   602
    void nextInc(Edge &arc, bool& dir) const {
deba@468
   603
      int de = (arcs[(arc.id * 2) | (dir ? 1 : 0)].next_out);
deba@468
   604
      if (de != -1 ) {
deba@468
   605
        arc.id = de / 2;
deba@468
   606
        dir = ((de & 1) == 1);
deba@468
   607
      } else {
deba@468
   608
        arc.id = -1;
deba@468
   609
        dir = true;
deba@468
   610
      }
deba@468
   611
    }
deba@468
   612
deba@468
   613
    static bool direction(Arc arc) {
deba@468
   614
      return (arc.id & 1) == 1;
deba@468
   615
    }
deba@468
   616
deba@468
   617
    static Arc direct(Edge edge, bool dir) {
deba@468
   618
      return Arc(edge.id * 2 + (dir ? 1 : 0));
deba@468
   619
    }
deba@468
   620
deba@488
   621
    int id(const Node& node) const { return _graph->id(node); }
deba@468
   622
    static int id(Arc e) { return e.id; }
deba@468
   623
    static int id(Edge e) { return e.id; }
deba@468
   624
deba@488
   625
    Node nodeFromId(int id) const { return _graph->nodeFromId(id); }
deba@468
   626
    static Arc arcFromId(int id) { return Arc(id);}
deba@468
   627
    static Edge edgeFromId(int id) { return Edge(id);}
deba@468
   628
deba@488
   629
    int maxNodeId() const { return _graph->maxNodeId(); };
deba@468
   630
    int maxEdgeId() const { return arcs.size() / 2 - 1; }
deba@468
   631
    int maxArcId() const { return arcs.size()-1; }
deba@468
   632
deba@468
   633
    Node source(Arc e) const { return arcs[e.id ^ 1].target; }
deba@468
   634
    Node target(Arc e) const { return arcs[e.id].target; }
deba@468
   635
deba@468
   636
    Node u(Edge e) const { return arcs[2 * e.id].target; }
deba@468
   637
    Node v(Edge e) const { return arcs[2 * e.id + 1].target; }
deba@468
   638
deba@488
   639
    typedef typename ItemSetTraits<GR, Node>::ItemNotifier NodeNotifier;
deba@468
   640
deba@468
   641
    NodeNotifier& notifier(Node) const {
deba@488
   642
      return _graph->notifier(Node());
deba@468
   643
    }
deba@468
   644
deba@488
   645
    template <typename V>
deba@488
   646
    class NodeMap : public GR::template NodeMap<V> {
kpeter@617
   647
      typedef typename GR::template NodeMap<V> Parent;
kpeter@617
   648
deba@468
   649
    public:
deba@468
   650
deba@488
   651
      explicit NodeMap(const ListEdgeSetBase<GR>& arcset)
deba@488
   652
        : Parent(*arcset._graph) {}
deba@468
   653
deba@488
   654
      NodeMap(const ListEdgeSetBase<GR>& arcset, const V& value)
deba@488
   655
        : Parent(*arcset._graph, value) {}
deba@468
   656
deba@468
   657
      NodeMap& operator=(const NodeMap& cmap) {
deba@468
   658
        return operator=<NodeMap>(cmap);
deba@468
   659
      }
deba@468
   660
deba@468
   661
      template <typename CMap>
deba@468
   662
      NodeMap& operator=(const CMap& cmap) {
deba@468
   663
        Parent::operator=(cmap);
deba@468
   664
        return *this;
deba@468
   665
      }
deba@468
   666
    };
deba@468
   667
deba@468
   668
  };
deba@468
   669
kpeter@660
   670
  /// \ingroup graphs
deba@468
   671
  ///
deba@468
   672
  /// \brief Graph using a node set of another digraph or graph and an
deba@468
   673
  /// own edge set.
deba@468
   674
  ///
deba@468
   675
  /// This structure can be used to establish another graph over a
deba@468
   676
  /// node set of an existing one. This class uses the same Node type
deba@468
   677
  /// as the underlying graph, and each valid node of the original
deba@468
   678
  /// graph is valid in this arc set, therefore the node objects of
deba@468
   679
  /// the original graph can be used directly with this class. The
deba@468
   680
  /// node handling functions (id handling, observing, and iterators)
deba@468
   681
  /// works equivalently as in the original graph.
deba@468
   682
  ///
deba@468
   683
  /// This implementation is based on doubly-linked lists, from each
deba@468
   684
  /// node the incident edges make up lists, therefore one edge can be
deba@468
   685
  /// erased in constant time. It also makes possible, that node can
deba@468
   686
  /// be removed from the underlying graph, in this case all edges
deba@468
   687
  /// incident to the given node is erased from the arc set.
deba@468
   688
  ///
kpeter@787
   689
  /// This class fully conforms to the \ref concepts::Graph "Graph"
kpeter@787
   690
  /// concept.
kpeter@787
   691
  /// It provides only linear time counting for nodes, edges and arcs.
kpeter@787
   692
  ///
deba@488
   693
  /// \param GR The type of the graph which shares its node set
deba@468
   694
  /// with this class. Its interface must conform to the
deba@468
   695
  /// \ref concepts::Digraph "Digraph" or \ref concepts::Graph "Graph"
deba@468
   696
  /// concept.
deba@488
   697
  template <typename GR>
deba@488
   698
  class ListEdgeSet : public EdgeSetExtender<ListEdgeSetBase<GR> > {
kpeter@617
   699
    typedef EdgeSetExtender<ListEdgeSetBase<GR> > Parent;
deba@468
   700
deba@468
   701
  public:
deba@468
   702
deba@468
   703
    typedef typename Parent::Node Node;
deba@468
   704
    typedef typename Parent::Arc Arc;
deba@468
   705
    typedef typename Parent::Edge Edge;
deba@468
   706
deba@468
   707
    typedef typename Parent::NodesImplBase NodesImplBase;
deba@468
   708
deba@468
   709
    void eraseNode(const Node& node) {
deba@468
   710
      Arc arc;
deba@468
   711
      Parent::firstOut(arc, node);
deba@468
   712
      while (arc != INVALID ) {
deba@468
   713
        erase(arc);
deba@468
   714
        Parent::firstOut(arc, node);
deba@468
   715
      }
deba@468
   716
deba@468
   717
    }
deba@468
   718
deba@468
   719
    void clearNodes() {
deba@468
   720
      Parent::clear();
deba@468
   721
    }
deba@468
   722
deba@468
   723
    class NodesImpl : public NodesImplBase {
deba@468
   724
      typedef NodesImplBase Parent;
deba@468
   725
kpeter@617
   726
    public:
deba@488
   727
      NodesImpl(const GR& graph, ListEdgeSet& arcset)
deba@468
   728
        : Parent(graph), _arcset(arcset) {}
deba@468
   729
deba@468
   730
      virtual ~NodesImpl() {}
deba@468
   731
deba@468
   732
    protected:
deba@468
   733
deba@468
   734
      virtual void erase(const Node& node) {
deba@468
   735
        _arcset.eraseNode(node);
deba@468
   736
        Parent::erase(node);
deba@468
   737
      }
deba@468
   738
      virtual void erase(const std::vector<Node>& nodes) {
deba@468
   739
        for (int i = 0; i < int(nodes.size()); ++i) {
deba@468
   740
          _arcset.eraseNode(nodes[i]);
deba@468
   741
        }
deba@468
   742
        Parent::erase(nodes);
deba@468
   743
      }
deba@468
   744
      virtual void clear() {
deba@468
   745
        _arcset.clearNodes();
deba@468
   746
        Parent::clear();
deba@468
   747
      }
deba@468
   748
deba@468
   749
    private:
deba@468
   750
      ListEdgeSet& _arcset;
deba@468
   751
    };
deba@468
   752
deba@488
   753
    NodesImpl _nodes;
deba@468
   754
deba@468
   755
  public:
deba@468
   756
deba@468
   757
    /// \brief Constructor of the EdgeSet.
deba@468
   758
    ///
deba@468
   759
    /// Constructor of the EdgeSet.
deba@488
   760
    ListEdgeSet(const GR& graph) : _nodes(graph, *this) {
deba@488
   761
      Parent::initalize(graph, _nodes);
deba@468
   762
    }
deba@468
   763
deba@468
   764
    /// \brief Add a new edge to the graph.
deba@468
   765
    ///
deba@468
   766
    /// Add a new edge to the graph with node \c u
deba@468
   767
    /// and node \c v endpoints.
kpeter@559
   768
    /// \return The new edge.
deba@468
   769
    Edge addEdge(const Node& u, const Node& v) {
deba@468
   770
      return Parent::addEdge(u, v);
deba@468
   771
    }
deba@468
   772
deba@468
   773
    /// \brief Erase an edge from the graph.
deba@468
   774
    ///
deba@468
   775
    /// Erase the edge \c e from the graph.
deba@468
   776
    void erase(const Edge& e) {
deba@468
   777
      return Parent::erase(e);
deba@468
   778
    }
deba@468
   779
deba@468
   780
  };
deba@468
   781
deba@488
   782
  template <typename GR>
deba@468
   783
  class SmartArcSetBase {
deba@468
   784
  public:
deba@468
   785
kpeter@617
   786
    typedef typename GR::Node Node;
kpeter@617
   787
    typedef typename GR::NodeIt NodeIt;
deba@468
   788
deba@468
   789
  protected:
deba@468
   790
deba@468
   791
    struct NodeT {
deba@468
   792
      int first_out, first_in;
deba@468
   793
      NodeT() : first_out(-1), first_in(-1) {}
deba@468
   794
    };
deba@468
   795
deba@488
   796
    typedef typename ItemSetTraits<GR, Node>::
deba@468
   797
    template Map<NodeT>::Type NodesImplBase;
deba@468
   798
deba@488
   799
    NodesImplBase* _nodes;
deba@468
   800
deba@468
   801
    struct ArcT {
deba@468
   802
      Node source, target;
deba@468
   803
      int next_out, next_in;
deba@468
   804
      ArcT() {}
deba@468
   805
    };
deba@468
   806
deba@468
   807
    std::vector<ArcT> arcs;
deba@468
   808
deba@488
   809
    const GR* _graph;
deba@468
   810
deba@488
   811
    void initalize(const GR& graph, NodesImplBase& nodes) {
deba@488
   812
      _graph = &graph;
deba@488
   813
      _nodes = &nodes;
deba@468
   814
    }
deba@468
   815
deba@468
   816
  public:
deba@468
   817
deba@468
   818
    class Arc {
deba@488
   819
      friend class SmartArcSetBase<GR>;
deba@468
   820
    protected:
deba@468
   821
      Arc(int _id) : id(_id) {}
deba@468
   822
      int id;
deba@468
   823
    public:
deba@468
   824
      Arc() {}
deba@468
   825
      Arc(Invalid) : id(-1) {}
deba@468
   826
      bool operator==(const Arc& arc) const { return id == arc.id; }
deba@468
   827
      bool operator!=(const Arc& arc) const { return id != arc.id; }
deba@468
   828
      bool operator<(const Arc& arc) const { return id < arc.id; }
deba@468
   829
    };
deba@468
   830
deba@468
   831
    SmartArcSetBase() {}
deba@468
   832
kpeter@670
   833
    Node addNode() {
kpeter@670
   834
      LEMON_ASSERT(false,
kpeter@670
   835
        "This graph structure does not support node insertion");
kpeter@670
   836
      return INVALID; // avoid warning
kpeter@670
   837
    }
kpeter@670
   838
deba@468
   839
    Arc addArc(const Node& u, const Node& v) {
deba@468
   840
      int n = arcs.size();
deba@468
   841
      arcs.push_back(ArcT());
deba@488
   842
      arcs[n].next_in = (*_nodes)[v].first_in;
deba@488
   843
      (*_nodes)[v].first_in = n;
deba@488
   844
      arcs[n].next_out = (*_nodes)[u].first_out;
deba@488
   845
      (*_nodes)[u].first_out = n;
deba@468
   846
      arcs[n].source = u;
deba@468
   847
      arcs[n].target = v;
deba@468
   848
      return Arc(n);
deba@468
   849
    }
deba@468
   850
deba@468
   851
    void clear() {
deba@468
   852
      Node node;
deba@468
   853
      for (first(node); node != INVALID; next(node)) {
deba@488
   854
        (*_nodes)[node].first_in = -1;
deba@488
   855
        (*_nodes)[node].first_out = -1;
deba@468
   856
      }
deba@468
   857
      arcs.clear();
deba@468
   858
    }
deba@468
   859
deba@468
   860
    void first(Node& node) const {
deba@488
   861
      _graph->first(node);
deba@468
   862
    }
deba@468
   863
deba@468
   864
    void next(Node& node) const {
deba@488
   865
      _graph->next(node);
deba@468
   866
    }
deba@468
   867
deba@468
   868
    void first(Arc& arc) const {
deba@468
   869
      arc.id = arcs.size() - 1;
deba@468
   870
    }
deba@468
   871
kpeter@778
   872
    static void next(Arc& arc) {
deba@468
   873
      --arc.id;
deba@468
   874
    }
deba@468
   875
deba@468
   876
    void firstOut(Arc& arc, const Node& node) const {
deba@488
   877
      arc.id = (*_nodes)[node].first_out;
deba@468
   878
    }
deba@468
   879
deba@468
   880
    void nextOut(Arc& arc) const {
deba@468
   881
      arc.id = arcs[arc.id].next_out;
deba@468
   882
    }
deba@468
   883
deba@468
   884
    void firstIn(Arc& arc, const Node& node) const {
deba@488
   885
      arc.id = (*_nodes)[node].first_in;
deba@468
   886
    }
deba@468
   887
deba@468
   888
    void nextIn(Arc& arc) const {
deba@468
   889
      arc.id = arcs[arc.id].next_in;
deba@468
   890
    }
deba@468
   891
deba@488
   892
    int id(const Node& node) const { return _graph->id(node); }
deba@468
   893
    int id(const Arc& arc) const { return arc.id; }
deba@468
   894
deba@488
   895
    Node nodeFromId(int ix) const { return _graph->nodeFromId(ix); }
deba@468
   896
    Arc arcFromId(int ix) const { return Arc(ix); }
deba@468
   897
deba@488
   898
    int maxNodeId() const { return _graph->maxNodeId(); };
deba@468
   899
    int maxArcId() const { return arcs.size() - 1; }
deba@468
   900
deba@468
   901
    Node source(const Arc& arc) const { return arcs[arc.id].source;}
deba@468
   902
    Node target(const Arc& arc) const { return arcs[arc.id].target;}
deba@468
   903
deba@488
   904
    typedef typename ItemSetTraits<GR, Node>::ItemNotifier NodeNotifier;
deba@468
   905
deba@468
   906
    NodeNotifier& notifier(Node) const {
deba@488
   907
      return _graph->notifier(Node());
deba@468
   908
    }
deba@468
   909
deba@488
   910
    template <typename V>
deba@488
   911
    class NodeMap : public GR::template NodeMap<V> {
kpeter@617
   912
      typedef typename GR::template NodeMap<V> Parent;
kpeter@617
   913
deba@468
   914
    public:
deba@468
   915
deba@488
   916
      explicit NodeMap(const SmartArcSetBase<GR>& arcset)
deba@488
   917
        : Parent(*arcset._graph) { }
deba@468
   918
deba@488
   919
      NodeMap(const SmartArcSetBase<GR>& arcset, const V& value)
deba@488
   920
        : Parent(*arcset._graph, value) { }
deba@468
   921
deba@468
   922
      NodeMap& operator=(const NodeMap& cmap) {
deba@468
   923
        return operator=<NodeMap>(cmap);
deba@468
   924
      }
deba@468
   925
deba@468
   926
      template <typename CMap>
deba@468
   927
      NodeMap& operator=(const CMap& cmap) {
deba@468
   928
        Parent::operator=(cmap);
deba@468
   929
        return *this;
deba@468
   930
      }
deba@468
   931
    };
deba@468
   932
deba@468
   933
  };
deba@468
   934
deba@468
   935
kpeter@660
   936
  /// \ingroup graphs
deba@468
   937
  ///
deba@468
   938
  /// \brief Digraph using a node set of another digraph or graph and
deba@468
   939
  /// an own arc set.
deba@468
   940
  ///
deba@468
   941
  /// This structure can be used to establish another directed graph
deba@468
   942
  /// over a node set of an existing one. This class uses the same
deba@468
   943
  /// Node type as the underlying graph, and each valid node of the
deba@468
   944
  /// original graph is valid in this arc set, therefore the node
deba@468
   945
  /// objects of the original graph can be used directly with this
deba@468
   946
  /// class. The node handling functions (id handling, observing, and
deba@468
   947
  /// iterators) works equivalently as in the original graph.
deba@468
   948
  ///
deba@488
   949
  /// \param GR The type of the graph which shares its node set with
deba@468
   950
  /// this class. Its interface must conform to the
deba@468
   951
  /// \ref concepts::Digraph "Digraph" or \ref concepts::Graph "Graph"
deba@468
   952
  /// concept.
deba@468
   953
  ///
deba@468
   954
  /// This implementation is slightly faster than the \c ListArcSet,
deba@468
   955
  /// because it uses continuous storage for arcs and it uses just
deba@468
   956
  /// single-linked lists for enumerate outgoing and incoming
deba@468
   957
  /// arcs. Therefore the arcs cannot be erased from the arc sets.
deba@468
   958
  ///
kpeter@787
   959
  /// This class fully conforms to the \ref concepts::Digraph "Digraph"
kpeter@787
   960
  /// concept.
kpeter@787
   961
  /// It provides only linear time counting for nodes and arcs.
kpeter@787
   962
  ///
deba@468
   963
  /// \warning If a node is erased from the underlying graph and this
deba@468
   964
  /// node is the source or target of one arc in the arc set, then
deba@468
   965
  /// the arc set is invalidated, and it cannot be used anymore. The
deba@468
   966
  /// validity can be checked with the \c valid() member function.
deba@488
   967
  template <typename GR>
deba@488
   968
  class SmartArcSet : public ArcSetExtender<SmartArcSetBase<GR> > {
kpeter@617
   969
    typedef ArcSetExtender<SmartArcSetBase<GR> > Parent;
deba@468
   970
deba@468
   971
  public:
deba@468
   972
deba@468
   973
    typedef typename Parent::Node Node;
deba@468
   974
    typedef typename Parent::Arc Arc;
deba@468
   975
deba@468
   976
  protected:
deba@468
   977
deba@468
   978
    typedef typename Parent::NodesImplBase NodesImplBase;
deba@468
   979
deba@468
   980
    void eraseNode(const Node& node) {
deba@468
   981
      if (typename Parent::InArcIt(*this, node) == INVALID &&
deba@468
   982
          typename Parent::OutArcIt(*this, node) == INVALID) {
deba@468
   983
        return;
deba@468
   984
      }
deba@468
   985
      throw typename NodesImplBase::Notifier::ImmediateDetach();
deba@468
   986
    }
deba@468
   987
deba@468
   988
    void clearNodes() {
deba@468
   989
      Parent::clear();
deba@468
   990
    }
deba@468
   991
deba@468
   992
    class NodesImpl : public NodesImplBase {
deba@468
   993
      typedef NodesImplBase Parent;
deba@468
   994
kpeter@617
   995
    public:
deba@488
   996
      NodesImpl(const GR& graph, SmartArcSet& arcset)
deba@468
   997
        : Parent(graph), _arcset(arcset) {}
deba@468
   998
deba@468
   999
      virtual ~NodesImpl() {}
deba@468
  1000
deba@468
  1001
      bool attached() const {
deba@468
  1002
        return Parent::attached();
deba@468
  1003
      }
deba@468
  1004
deba@468
  1005
    protected:
deba@468
  1006
deba@468
  1007
      virtual void erase(const Node& node) {
deba@468
  1008
        try {
deba@468
  1009
          _arcset.eraseNode(node);
deba@468
  1010
          Parent::erase(node);
deba@468
  1011
        } catch (const typename NodesImplBase::Notifier::ImmediateDetach&) {
deba@468
  1012
          Parent::clear();
deba@468
  1013
          throw;
deba@468
  1014
        }
deba@468
  1015
      }
deba@468
  1016
      virtual void erase(const std::vector<Node>& nodes) {
deba@468
  1017
        try {
deba@468
  1018
          for (int i = 0; i < int(nodes.size()); ++i) {
deba@468
  1019
            _arcset.eraseNode(nodes[i]);
deba@468
  1020
          }
deba@468
  1021
          Parent::erase(nodes);
deba@468
  1022
        } catch (const typename NodesImplBase::Notifier::ImmediateDetach&) {
deba@468
  1023
          Parent::clear();
deba@468
  1024
          throw;
deba@468
  1025
        }
deba@468
  1026
      }
deba@468
  1027
      virtual void clear() {
deba@468
  1028
        _arcset.clearNodes();
deba@468
  1029
        Parent::clear();
deba@468
  1030
      }
deba@468
  1031
deba@468
  1032
    private:
deba@468
  1033
      SmartArcSet& _arcset;
deba@468
  1034
    };
deba@468
  1035
deba@488
  1036
    NodesImpl _nodes;
deba@468
  1037
deba@468
  1038
  public:
deba@468
  1039
deba@468
  1040
    /// \brief Constructor of the ArcSet.
deba@468
  1041
    ///
deba@468
  1042
    /// Constructor of the ArcSet.
deba@488
  1043
    SmartArcSet(const GR& graph) : _nodes(graph, *this) {
deba@488
  1044
      Parent::initalize(graph, _nodes);
deba@468
  1045
    }
deba@468
  1046
deba@468
  1047
    /// \brief Add a new arc to the digraph.
deba@468
  1048
    ///
deba@468
  1049
    /// Add a new arc to the digraph with source node \c s
deba@468
  1050
    /// and target node \c t.
kpeter@559
  1051
    /// \return The new arc.
deba@468
  1052
    Arc addArc(const Node& s, const Node& t) {
deba@468
  1053
      return Parent::addArc(s, t);
deba@468
  1054
    }
deba@468
  1055
deba@468
  1056
    /// \brief Validity check
deba@468
  1057
    ///
deba@468
  1058
    /// This functions gives back false if the ArcSet is
deba@468
  1059
    /// invalidated. It occurs when a node in the underlying graph is
deba@468
  1060
    /// erased and it is not isolated in the ArcSet.
deba@468
  1061
    bool valid() const {
deba@488
  1062
      return _nodes.attached();
deba@468
  1063
    }
deba@468
  1064
deba@468
  1065
  };
deba@468
  1066
deba@468
  1067
deba@488
  1068
  template <typename GR>
deba@468
  1069
  class SmartEdgeSetBase {
deba@468
  1070
  public:
deba@468
  1071
deba@488
  1072
    typedef typename GR::Node Node;
deba@488
  1073
    typedef typename GR::NodeIt NodeIt;
deba@468
  1074
deba@468
  1075
  protected:
deba@468
  1076
deba@468
  1077
    struct NodeT {
deba@468
  1078
      int first_out;
deba@468
  1079
      NodeT() : first_out(-1) {}
deba@468
  1080
    };
deba@468
  1081
deba@488
  1082
    typedef typename ItemSetTraits<GR, Node>::
deba@468
  1083
    template Map<NodeT>::Type NodesImplBase;
deba@468
  1084
deba@488
  1085
    NodesImplBase* _nodes;
deba@468
  1086
deba@468
  1087
    struct ArcT {
deba@468
  1088
      Node target;
deba@468
  1089
      int next_out;
deba@468
  1090
      ArcT() {}
deba@468
  1091
    };
deba@468
  1092
deba@468
  1093
    std::vector<ArcT> arcs;
deba@468
  1094
deba@488
  1095
    const GR* _graph;
deba@468
  1096
deba@488
  1097
    void initalize(const GR& graph, NodesImplBase& nodes) {
deba@488
  1098
      _graph = &graph;
deba@488
  1099
      _nodes = &nodes;
deba@468
  1100
    }
deba@468
  1101
deba@468
  1102
  public:
deba@468
  1103
deba@468
  1104
    class Edge {
deba@468
  1105
      friend class SmartEdgeSetBase;
deba@468
  1106
    protected:
deba@468
  1107
deba@468
  1108
      int id;
deba@468
  1109
      explicit Edge(int _id) { id = _id;}
deba@468
  1110
deba@468
  1111
    public:
deba@468
  1112
      Edge() {}
deba@468
  1113
      Edge (Invalid) { id = -1; }
deba@468
  1114
      bool operator==(const Edge& arc) const {return id == arc.id;}
deba@468
  1115
      bool operator!=(const Edge& arc) const {return id != arc.id;}
deba@468
  1116
      bool operator<(const Edge& arc) const {return id < arc.id;}
deba@468
  1117
    };
deba@468
  1118
deba@468
  1119
    class Arc {
deba@468
  1120
      friend class SmartEdgeSetBase;
deba@468
  1121
    protected:
deba@468
  1122
      Arc(int _id) : id(_id) {}
deba@468
  1123
      int id;
deba@468
  1124
    public:
deba@468
  1125
      operator Edge() const { return edgeFromId(id / 2); }
deba@468
  1126
deba@468
  1127
      Arc() {}
deba@468
  1128
      Arc(Invalid) : id(-1) {}
deba@468
  1129
      bool operator==(const Arc& arc) const { return id == arc.id; }
deba@468
  1130
      bool operator!=(const Arc& arc) const { return id != arc.id; }
deba@468
  1131
      bool operator<(const Arc& arc) const { return id < arc.id; }
deba@468
  1132
    };
deba@468
  1133
deba@468
  1134
    SmartEdgeSetBase() {}
deba@468
  1135
kpeter@670
  1136
    Node addNode() {
kpeter@670
  1137
      LEMON_ASSERT(false,
kpeter@670
  1138
        "This graph structure does not support node insertion");
kpeter@670
  1139
      return INVALID; // avoid warning
kpeter@670
  1140
    }
kpeter@670
  1141
deba@468
  1142
    Edge addEdge(const Node& u, const Node& v) {
deba@468
  1143
      int n = arcs.size();
deba@468
  1144
      arcs.push_back(ArcT());
deba@468
  1145
      arcs.push_back(ArcT());
deba@468
  1146
deba@468
  1147
      arcs[n].target = u;
deba@468
  1148
      arcs[n | 1].target = v;
deba@468
  1149
deba@488
  1150
      arcs[n].next_out = (*_nodes)[v].first_out;
deba@488
  1151
      (*_nodes)[v].first_out = n;
deba@468
  1152
deba@488
  1153
      arcs[n | 1].next_out = (*_nodes)[u].first_out;
deba@488
  1154
      (*_nodes)[u].first_out = (n | 1);
deba@468
  1155
deba@468
  1156
      return Edge(n / 2);
deba@468
  1157
    }
deba@468
  1158
deba@468
  1159
    void clear() {
deba@468
  1160
      Node node;
deba@468
  1161
      for (first(node); node != INVALID; next(node)) {
deba@488
  1162
        (*_nodes)[node].first_out = -1;
deba@468
  1163
      }
deba@468
  1164
      arcs.clear();
deba@468
  1165
    }
deba@468
  1166
deba@468
  1167
    void first(Node& node) const {
deba@488
  1168
      _graph->first(node);
deba@468
  1169
    }
deba@468
  1170
deba@468
  1171
    void next(Node& node) const {
deba@488
  1172
      _graph->next(node);
deba@468
  1173
    }
deba@468
  1174
deba@468
  1175
    void first(Arc& arc) const {
deba@468
  1176
      arc.id = arcs.size() - 1;
deba@468
  1177
    }
deba@468
  1178
kpeter@778
  1179
    static void next(Arc& arc) {
deba@468
  1180
      --arc.id;
deba@468
  1181
    }
deba@468
  1182
deba@468
  1183
    void first(Edge& arc) const {
deba@468
  1184
      arc.id = arcs.size() / 2 - 1;
deba@468
  1185
    }
deba@468
  1186
kpeter@778
  1187
    static void next(Edge& arc) {
deba@468
  1188
      --arc.id;
deba@468
  1189
    }
deba@468
  1190
deba@468
  1191
    void firstOut(Arc& arc, const Node& node) const {
deba@488
  1192
      arc.id = (*_nodes)[node].first_out;
deba@468
  1193
    }
deba@468
  1194
deba@468
  1195
    void nextOut(Arc& arc) const {
deba@468
  1196
      arc.id = arcs[arc.id].next_out;
deba@468
  1197
    }
deba@468
  1198
deba@468
  1199
    void firstIn(Arc& arc, const Node& node) const {
deba@488
  1200
      arc.id = (((*_nodes)[node].first_out) ^ 1);
deba@468
  1201
      if (arc.id == -2) arc.id = -1;
deba@468
  1202
    }
deba@468
  1203
deba@468
  1204
    void nextIn(Arc& arc) const {
deba@468
  1205
      arc.id = ((arcs[arc.id ^ 1].next_out) ^ 1);
deba@468
  1206
      if (arc.id == -2) arc.id = -1;
deba@468
  1207
    }
deba@468
  1208
deba@468
  1209
    void firstInc(Edge &arc, bool& dir, const Node& node) const {
deba@488
  1210
      int de = (*_nodes)[node].first_out;
deba@468
  1211
      if (de != -1 ) {
deba@468
  1212
        arc.id = de / 2;
deba@468
  1213
        dir = ((de & 1) == 1);
deba@468
  1214
      } else {
deba@468
  1215
        arc.id = -1;
deba@468
  1216
        dir = true;
deba@468
  1217
      }
deba@468
  1218
    }
deba@468
  1219
    void nextInc(Edge &arc, bool& dir) const {
deba@468
  1220
      int de = (arcs[(arc.id * 2) | (dir ? 1 : 0)].next_out);
deba@468
  1221
      if (de != -1 ) {
deba@468
  1222
        arc.id = de / 2;
deba@468
  1223
        dir = ((de & 1) == 1);
deba@468
  1224
      } else {
deba@468
  1225
        arc.id = -1;
deba@468
  1226
        dir = true;
deba@468
  1227
      }
deba@468
  1228
    }
deba@468
  1229
deba@468
  1230
    static bool direction(Arc arc) {
deba@468
  1231
      return (arc.id & 1) == 1;
deba@468
  1232
    }
deba@468
  1233
deba@468
  1234
    static Arc direct(Edge edge, bool dir) {
deba@468
  1235
      return Arc(edge.id * 2 + (dir ? 1 : 0));
deba@468
  1236
    }
deba@468
  1237
deba@488
  1238
    int id(Node node) const { return _graph->id(node); }
deba@468
  1239
    static int id(Arc arc) { return arc.id; }
deba@468
  1240
    static int id(Edge arc) { return arc.id; }
deba@468
  1241
deba@488
  1242
    Node nodeFromId(int id) const { return _graph->nodeFromId(id); }
deba@468
  1243
    static Arc arcFromId(int id) { return Arc(id); }
deba@468
  1244
    static Edge edgeFromId(int id) { return Edge(id);}
deba@468
  1245
deba@488
  1246
    int maxNodeId() const { return _graph->maxNodeId(); };
deba@468
  1247
    int maxArcId() const { return arcs.size() - 1; }
deba@468
  1248
    int maxEdgeId() const { return arcs.size() / 2 - 1; }
deba@468
  1249
deba@468
  1250
    Node source(Arc e) const { return arcs[e.id ^ 1].target; }
deba@468
  1251
    Node target(Arc e) const { return arcs[e.id].target; }
deba@468
  1252
deba@468
  1253
    Node u(Edge e) const { return arcs[2 * e.id].target; }
deba@468
  1254
    Node v(Edge e) const { return arcs[2 * e.id + 1].target; }
deba@468
  1255
deba@488
  1256
    typedef typename ItemSetTraits<GR, Node>::ItemNotifier NodeNotifier;
deba@468
  1257
deba@468
  1258
    NodeNotifier& notifier(Node) const {
deba@488
  1259
      return _graph->notifier(Node());
deba@468
  1260
    }
deba@468
  1261
deba@488
  1262
    template <typename V>
deba@488
  1263
    class NodeMap : public GR::template NodeMap<V> {
kpeter@617
  1264
      typedef typename GR::template NodeMap<V> Parent;
kpeter@617
  1265
deba@468
  1266
    public:
deba@468
  1267
deba@488
  1268
      explicit NodeMap(const SmartEdgeSetBase<GR>& arcset)
deba@488
  1269
        : Parent(*arcset._graph) { }
deba@468
  1270
deba@488
  1271
      NodeMap(const SmartEdgeSetBase<GR>& arcset, const V& value)
deba@488
  1272
        : Parent(*arcset._graph, value) { }
deba@468
  1273
deba@468
  1274
      NodeMap& operator=(const NodeMap& cmap) {
deba@468
  1275
        return operator=<NodeMap>(cmap);
deba@468
  1276
      }
deba@468
  1277
deba@468
  1278
      template <typename CMap>
deba@468
  1279
      NodeMap& operator=(const CMap& cmap) {
deba@468
  1280
        Parent::operator=(cmap);
deba@468
  1281
        return *this;
deba@468
  1282
      }
deba@468
  1283
    };
deba@468
  1284
deba@468
  1285
  };
deba@468
  1286
kpeter@660
  1287
  /// \ingroup graphs
deba@468
  1288
  ///
deba@468
  1289
  /// \brief Graph using a node set of another digraph or graph and an
deba@468
  1290
  /// own edge set.
deba@468
  1291
  ///
deba@468
  1292
  /// This structure can be used to establish another graph over a
deba@468
  1293
  /// node set of an existing one. This class uses the same Node type
deba@468
  1294
  /// as the underlying graph, and each valid node of the original
deba@468
  1295
  /// graph is valid in this arc set, therefore the node objects of
deba@468
  1296
  /// the original graph can be used directly with this class. The
deba@468
  1297
  /// node handling functions (id handling, observing, and iterators)
deba@468
  1298
  /// works equivalently as in the original graph.
deba@468
  1299
  ///
deba@488
  1300
  /// \param GR The type of the graph which shares its node set
deba@468
  1301
  /// with this class. Its interface must conform to the
deba@468
  1302
  /// \ref concepts::Digraph "Digraph" or \ref concepts::Graph "Graph"
deba@468
  1303
  ///  concept.
deba@468
  1304
  ///
deba@468
  1305
  /// This implementation is slightly faster than the \c ListEdgeSet,
deba@468
  1306
  /// because it uses continuous storage for edges and it uses just
deba@468
  1307
  /// single-linked lists for enumerate incident edges. Therefore the
deba@468
  1308
  /// edges cannot be erased from the edge sets.
deba@468
  1309
  ///
kpeter@787
  1310
  /// This class fully conforms to the \ref concepts::Graph "Graph"
kpeter@787
  1311
  /// concept.
kpeter@787
  1312
  /// It provides only linear time counting for nodes, edges and arcs.
kpeter@787
  1313
  ///
deba@468
  1314
  /// \warning If a node is erased from the underlying graph and this
deba@468
  1315
  /// node is incident to one edge in the edge set, then the edge set
deba@468
  1316
  /// is invalidated, and it cannot be used anymore. The validity can
deba@468
  1317
  /// be checked with the \c valid() member function.
deba@488
  1318
  template <typename GR>
deba@488
  1319
  class SmartEdgeSet : public EdgeSetExtender<SmartEdgeSetBase<GR> > {
kpeter@617
  1320
    typedef EdgeSetExtender<SmartEdgeSetBase<GR> > Parent;
deba@468
  1321
deba@468
  1322
  public:
deba@468
  1323
deba@468
  1324
    typedef typename Parent::Node Node;
deba@468
  1325
    typedef typename Parent::Arc Arc;
deba@468
  1326
    typedef typename Parent::Edge Edge;
deba@468
  1327
deba@468
  1328
  protected:
deba@468
  1329
deba@468
  1330
    typedef typename Parent::NodesImplBase NodesImplBase;
deba@468
  1331
deba@468
  1332
    void eraseNode(const Node& node) {
deba@468
  1333
      if (typename Parent::IncEdgeIt(*this, node) == INVALID) {
deba@468
  1334
        return;
deba@468
  1335
      }
deba@468
  1336
      throw typename NodesImplBase::Notifier::ImmediateDetach();
deba@468
  1337
    }
deba@468
  1338
deba@468
  1339
    void clearNodes() {
deba@468
  1340
      Parent::clear();
deba@468
  1341
    }
deba@468
  1342
deba@468
  1343
    class NodesImpl : public NodesImplBase {
deba@468
  1344
      typedef NodesImplBase Parent;
deba@468
  1345
kpeter@617
  1346
    public:
deba@488
  1347
      NodesImpl(const GR& graph, SmartEdgeSet& arcset)
deba@468
  1348
        : Parent(graph), _arcset(arcset) {}
deba@468
  1349
deba@468
  1350
      virtual ~NodesImpl() {}
deba@468
  1351
deba@468
  1352
      bool attached() const {
deba@468
  1353
        return Parent::attached();
deba@468
  1354
      }
deba@468
  1355
deba@468
  1356
    protected:
deba@468
  1357
deba@468
  1358
      virtual void erase(const Node& node) {
deba@468
  1359
        try {
deba@468
  1360
          _arcset.eraseNode(node);
deba@468
  1361
          Parent::erase(node);
deba@468
  1362
        } catch (const typename NodesImplBase::Notifier::ImmediateDetach&) {
deba@468
  1363
          Parent::clear();
deba@468
  1364
          throw;
deba@468
  1365
        }
deba@468
  1366
      }
deba@468
  1367
      virtual void erase(const std::vector<Node>& nodes) {
deba@468
  1368
        try {
deba@468
  1369
          for (int i = 0; i < int(nodes.size()); ++i) {
deba@468
  1370
            _arcset.eraseNode(nodes[i]);
deba@468
  1371
          }
deba@468
  1372
          Parent::erase(nodes);
deba@468
  1373
        } catch (const typename NodesImplBase::Notifier::ImmediateDetach&) {
deba@468
  1374
          Parent::clear();
deba@468
  1375
          throw;
deba@468
  1376
        }
deba@468
  1377
      }
deba@468
  1378
      virtual void clear() {
deba@468
  1379
        _arcset.clearNodes();
deba@468
  1380
        Parent::clear();
deba@468
  1381
      }
deba@468
  1382
deba@468
  1383
    private:
deba@468
  1384
      SmartEdgeSet& _arcset;
deba@468
  1385
    };
deba@468
  1386
deba@488
  1387
    NodesImpl _nodes;
deba@468
  1388
deba@468
  1389
  public:
deba@468
  1390
deba@468
  1391
    /// \brief Constructor of the EdgeSet.
deba@468
  1392
    ///
deba@468
  1393
    /// Constructor of the EdgeSet.
deba@488
  1394
    SmartEdgeSet(const GR& graph) : _nodes(graph, *this) {
deba@488
  1395
      Parent::initalize(graph, _nodes);
deba@468
  1396
    }
deba@468
  1397
deba@468
  1398
    /// \brief Add a new edge to the graph.
deba@468
  1399
    ///
deba@468
  1400
    /// Add a new edge to the graph with node \c u
deba@468
  1401
    /// and node \c v endpoints.
kpeter@559
  1402
    /// \return The new edge.
deba@468
  1403
    Edge addEdge(const Node& u, const Node& v) {
deba@468
  1404
      return Parent::addEdge(u, v);
deba@468
  1405
    }
deba@468
  1406
deba@468
  1407
    /// \brief Validity check
deba@468
  1408
    ///
deba@468
  1409
    /// This functions gives back false if the EdgeSet is
deba@468
  1410
    /// invalidated. It occurs when a node in the underlying graph is
deba@468
  1411
    /// erased and it is not isolated in the EdgeSet.
deba@468
  1412
    bool valid() const {
deba@488
  1413
      return _nodes.attached();
deba@468
  1414
    }
deba@468
  1415
deba@468
  1416
  };
deba@468
  1417
deba@468
  1418
}
deba@468
  1419
deba@468
  1420
#endif