lemon/smart_graph.h
author Peter Kovacs <kpeter@inf.elte.hu>
Tue, 15 Mar 2011 19:32:21 +0100
changeset 936 ddd3c0d3d9bf
parent 787 c2230649a493
child 1019 4c89e925cfe2
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.
alpar@209
     1
/* -*- mode: C++; indent-tabs-mode: nil; -*-
deba@109
     2
 *
alpar@209
     3
 * This file is a part of LEMON, a generic C++ optimization library.
deba@109
     4
 *
alpar@877
     5
 * Copyright (C) 2003-2010
deba@109
     6
 * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
deba@109
     7
 * (Egervary Research Group on Combinatorial Optimization, EGRES).
deba@109
     8
 *
deba@109
     9
 * Permission to use, modify and distribute this software is granted
deba@109
    10
 * provided that this copyright notice appears in all copies. For
deba@109
    11
 * precise terms see the accompanying LICENSE file.
deba@109
    12
 *
deba@109
    13
 * This software is provided "AS IS" with no warranty of any kind,
deba@109
    14
 * express or implied, and with no claim as to its suitability for any
deba@109
    15
 * purpose.
deba@109
    16
 *
deba@109
    17
 */
deba@109
    18
deba@109
    19
#ifndef LEMON_SMART_GRAPH_H
deba@109
    20
#define LEMON_SMART_GRAPH_H
deba@109
    21
deba@109
    22
///\ingroup graphs
deba@109
    23
///\file
deba@109
    24
///\brief SmartDigraph and SmartGraph classes.
deba@109
    25
deba@109
    26
#include <vector>
deba@109
    27
deba@220
    28
#include <lemon/core.h>
deba@109
    29
#include <lemon/error.h>
deba@109
    30
#include <lemon/bits/graph_extender.h>
deba@109
    31
deba@109
    32
namespace lemon {
deba@109
    33
deba@109
    34
  class SmartDigraph;
deba@109
    35
deba@109
    36
  class SmartDigraphBase {
deba@109
    37
  protected:
deba@109
    38
alpar@209
    39
    struct NodeT
deba@109
    40
    {
alpar@209
    41
      int first_in, first_out;
deba@109
    42
      NodeT() {}
deba@109
    43
    };
alpar@209
    44
    struct ArcT
deba@109
    45
    {
alpar@209
    46
      int target, source, next_in, next_out;
alpar@209
    47
      ArcT() {}
deba@109
    48
    };
deba@109
    49
deba@109
    50
    std::vector<NodeT> nodes;
deba@109
    51
    std::vector<ArcT> arcs;
alpar@209
    52
deba@109
    53
  public:
deba@109
    54
kpeter@617
    55
    typedef SmartDigraphBase Digraph;
deba@109
    56
deba@109
    57
    class Node;
deba@109
    58
    class Arc;
deba@109
    59
deba@109
    60
  public:
deba@109
    61
deba@109
    62
    SmartDigraphBase() : nodes(), arcs() { }
alpar@209
    63
    SmartDigraphBase(const SmartDigraphBase &_g)
deba@109
    64
      : nodes(_g.nodes), arcs(_g.arcs) { }
alpar@209
    65
deba@109
    66
    typedef True NodeNumTag;
kpeter@360
    67
    typedef True ArcNumTag;
deba@109
    68
deba@109
    69
    int nodeNum() const { return nodes.size(); }
deba@109
    70
    int arcNum() const { return arcs.size(); }
deba@109
    71
deba@109
    72
    int maxNodeId() const { return nodes.size()-1; }
deba@109
    73
    int maxArcId() const { return arcs.size()-1; }
deba@109
    74
deba@109
    75
    Node addNode() {
alpar@209
    76
      int n = nodes.size();
deba@109
    77
      nodes.push_back(NodeT());
deba@109
    78
      nodes[n].first_in = -1;
deba@109
    79
      nodes[n].first_out = -1;
deba@109
    80
      return Node(n);
deba@109
    81
    }
alpar@209
    82
deba@109
    83
    Arc addArc(Node u, Node v) {
alpar@209
    84
      int n = arcs.size();
deba@109
    85
      arcs.push_back(ArcT());
alpar@209
    86
      arcs[n].source = u._id;
deba@109
    87
      arcs[n].target = v._id;
deba@109
    88
      arcs[n].next_out = nodes[u._id].first_out;
deba@109
    89
      arcs[n].next_in = nodes[v._id].first_in;
deba@109
    90
      nodes[u._id].first_out = nodes[v._id].first_in = n;
deba@109
    91
deba@109
    92
      return Arc(n);
deba@109
    93
    }
deba@109
    94
deba@109
    95
    void clear() {
deba@109
    96
      arcs.clear();
deba@109
    97
      nodes.clear();
deba@109
    98
    }
deba@109
    99
deba@109
   100
    Node source(Arc a) const { return Node(arcs[a._id].source); }
deba@109
   101
    Node target(Arc a) const { return Node(arcs[a._id].target); }
deba@109
   102
deba@109
   103
    static int id(Node v) { return v._id; }
deba@109
   104
    static int id(Arc a) { return a._id; }
deba@109
   105
deba@109
   106
    static Node nodeFromId(int id) { return Node(id);}
deba@109
   107
    static Arc arcFromId(int id) { return Arc(id);}
deba@109
   108
alpar@209
   109
    bool valid(Node n) const {
alpar@209
   110
      return n._id >= 0 && n._id < static_cast<int>(nodes.size());
deba@149
   111
    }
alpar@209
   112
    bool valid(Arc a) const {
alpar@209
   113
      return a._id >= 0 && a._id < static_cast<int>(arcs.size());
deba@149
   114
    }
deba@149
   115
deba@109
   116
    class Node {
deba@109
   117
      friend class SmartDigraphBase;
deba@109
   118
      friend class SmartDigraph;
deba@109
   119
deba@109
   120
    protected:
deba@109
   121
      int _id;
deba@109
   122
      explicit Node(int id) : _id(id) {}
deba@109
   123
    public:
deba@109
   124
      Node() {}
deba@109
   125
      Node (Invalid) : _id(-1) {}
deba@109
   126
      bool operator==(const Node i) const {return _id == i._id;}
deba@109
   127
      bool operator!=(const Node i) const {return _id != i._id;}
deba@109
   128
      bool operator<(const Node i) const {return _id < i._id;}
deba@109
   129
    };
alpar@209
   130
deba@109
   131
deba@109
   132
    class Arc {
deba@109
   133
      friend class SmartDigraphBase;
deba@109
   134
      friend class SmartDigraph;
deba@109
   135
deba@109
   136
    protected:
deba@109
   137
      int _id;
deba@109
   138
      explicit Arc(int id) : _id(id) {}
deba@109
   139
    public:
deba@109
   140
      Arc() { }
deba@109
   141
      Arc (Invalid) : _id(-1) {}
deba@109
   142
      bool operator==(const Arc i) const {return _id == i._id;}
deba@109
   143
      bool operator!=(const Arc i) const {return _id != i._id;}
deba@109
   144
      bool operator<(const Arc i) const {return _id < i._id;}
deba@109
   145
    };
deba@109
   146
deba@109
   147
    void first(Node& node) const {
deba@109
   148
      node._id = nodes.size() - 1;
deba@109
   149
    }
deba@109
   150
deba@109
   151
    static void next(Node& node) {
deba@109
   152
      --node._id;
deba@109
   153
    }
deba@109
   154
deba@109
   155
    void first(Arc& arc) const {
deba@109
   156
      arc._id = arcs.size() - 1;
deba@109
   157
    }
deba@109
   158
deba@109
   159
    static void next(Arc& arc) {
deba@109
   160
      --arc._id;
deba@109
   161
    }
deba@109
   162
deba@109
   163
    void firstOut(Arc& arc, const Node& node) const {
deba@109
   164
      arc._id = nodes[node._id].first_out;
deba@109
   165
    }
deba@109
   166
deba@109
   167
    void nextOut(Arc& arc) const {
deba@109
   168
      arc._id = arcs[arc._id].next_out;
deba@109
   169
    }
deba@109
   170
deba@109
   171
    void firstIn(Arc& arc, const Node& node) const {
deba@109
   172
      arc._id = nodes[node._id].first_in;
deba@109
   173
    }
alpar@209
   174
deba@109
   175
    void nextIn(Arc& arc) const {
deba@109
   176
      arc._id = arcs[arc._id].next_in;
deba@109
   177
    }
deba@109
   178
deba@109
   179
  };
deba@109
   180
deba@109
   181
  typedef DigraphExtender<SmartDigraphBase> ExtendedSmartDigraphBase;
deba@109
   182
deba@109
   183
  ///\ingroup graphs
deba@109
   184
  ///
deba@109
   185
  ///\brief A smart directed graph class.
deba@109
   186
  ///
kpeter@735
   187
  ///\ref SmartDigraph is a simple and fast digraph implementation.
kpeter@735
   188
  ///It is also quite memory efficient but at the price
alpar@877
   189
  ///that it does not support node and arc deletion
kpeter@735
   190
  ///(except for the Snapshot feature).
deba@109
   191
  ///
kpeter@735
   192
  ///This type fully conforms to the \ref concepts::Digraph "Digraph concept"
kpeter@735
   193
  ///and it also provides some additional functionalities.
kpeter@735
   194
  ///Most of its member functions and nested classes are documented
kpeter@735
   195
  ///only in the concept class.
kpeter@735
   196
  ///
kpeter@787
   197
  ///This class provides constant time counting for nodes and arcs.
kpeter@787
   198
  ///
kpeter@735
   199
  ///\sa concepts::Digraph
kpeter@735
   200
  ///\sa SmartGraph
deba@109
   201
  class SmartDigraph : public ExtendedSmartDigraphBase {
deba@109
   202
    typedef ExtendedSmartDigraphBase Parent;
deba@109
   203
deba@109
   204
  private:
kpeter@735
   205
    /// Digraphs are \e not copy constructible. Use DigraphCopy instead.
deba@109
   206
    SmartDigraph(const SmartDigraph &) : ExtendedSmartDigraphBase() {};
kpeter@735
   207
    /// \brief Assignment of a digraph to another one is \e not allowed.
kpeter@735
   208
    /// Use DigraphCopy instead.
deba@109
   209
    void operator=(const SmartDigraph &) {}
deba@109
   210
deba@109
   211
  public:
alpar@209
   212
deba@109
   213
    /// Constructor
alpar@209
   214
deba@109
   215
    /// Constructor.
deba@109
   216
    ///
deba@109
   217
    SmartDigraph() {};
alpar@209
   218
deba@109
   219
    ///Add a new node to the digraph.
alpar@209
   220
kpeter@735
   221
    ///This function adds a new node to the digraph.
kpeter@735
   222
    ///\return The new node.
deba@109
   223
    Node addNode() { return Parent::addNode(); }
alpar@209
   224
deba@109
   225
    ///Add a new arc to the digraph.
alpar@209
   226
kpeter@735
   227
    ///This function adds a new arc to the digraph with source node \c s
deba@109
   228
    ///and target node \c t.
kpeter@559
   229
    ///\return The new arc.
kpeter@735
   230
    Arc addArc(Node s, Node t) {
alpar@209
   231
      return Parent::addArc(s, t);
deba@109
   232
    }
deba@109
   233
deba@149
   234
    /// \brief Node validity check
deba@149
   235
    ///
kpeter@735
   236
    /// This function gives back \c true if the given node is valid,
kpeter@735
   237
    /// i.e. it is a real node of the digraph.
deba@149
   238
    ///
deba@149
   239
    /// \warning A removed node (using Snapshot) could become valid again
kpeter@735
   240
    /// if new nodes are added to the digraph.
deba@149
   241
    bool valid(Node n) const { return Parent::valid(n); }
deba@149
   242
deba@149
   243
    /// \brief Arc validity check
deba@149
   244
    ///
kpeter@735
   245
    /// This function gives back \c true if the given arc is valid,
kpeter@735
   246
    /// i.e. it is a real arc of the digraph.
deba@149
   247
    ///
deba@149
   248
    /// \warning A removed arc (using Snapshot) could become valid again
kpeter@735
   249
    /// if new arcs are added to the graph.
deba@149
   250
    bool valid(Arc a) const { return Parent::valid(a); }
deba@149
   251
deba@109
   252
    ///Split a node.
alpar@209
   253
kpeter@735
   254
    ///This function splits the given node. First, a new node is added
kpeter@735
   255
    ///to the digraph, then the source of each outgoing arc of node \c n
kpeter@735
   256
    ///is moved to this new node.
kpeter@735
   257
    ///If the second parameter \c connect is \c true (this is the default
kpeter@735
   258
    ///value), then a new arc from node \c n to the newly created node
kpeter@735
   259
    ///is also added.
deba@109
   260
    ///\return The newly created node.
deba@109
   261
    ///
kpeter@735
   262
    ///\note All iterators remain valid.
kpeter@735
   263
    ///
deba@109
   264
    ///\warning This functionality cannot be used together with the Snapshot
deba@109
   265
    ///feature.
deba@109
   266
    Node split(Node n, bool connect = true)
deba@109
   267
    {
deba@109
   268
      Node b = addNode();
deba@109
   269
      nodes[b._id].first_out=nodes[n._id].first_out;
deba@109
   270
      nodes[n._id].first_out=-1;
kpeter@370
   271
      for(int i=nodes[b._id].first_out; i!=-1; i=arcs[i].next_out) {
kpeter@370
   272
        arcs[i].source=b._id;
kpeter@370
   273
      }
deba@109
   274
      if(connect) addArc(n,b);
deba@109
   275
      return b;
deba@109
   276
    }
deba@109
   277
kpeter@735
   278
    ///Clear the digraph.
kpeter@735
   279
kpeter@735
   280
    ///This function erases all nodes and arcs from the digraph.
kpeter@735
   281
    ///
kpeter@735
   282
    void clear() {
kpeter@735
   283
      Parent::clear();
kpeter@735
   284
    }
kpeter@735
   285
kpeter@735
   286
    /// Reserve memory for nodes.
kpeter@735
   287
kpeter@735
   288
    /// Using this function, it is possible to avoid superfluous memory
kpeter@735
   289
    /// allocation: if you know that the digraph you want to build will
kpeter@735
   290
    /// be large (e.g. it will contain millions of nodes and/or arcs),
kpeter@735
   291
    /// then it is worth reserving space for this amount before starting
kpeter@735
   292
    /// to build the digraph.
kpeter@735
   293
    /// \sa reserveArc()
kpeter@735
   294
    void reserveNode(int n) { nodes.reserve(n); };
kpeter@735
   295
kpeter@735
   296
    /// Reserve memory for arcs.
kpeter@735
   297
kpeter@735
   298
    /// Using this function, it is possible to avoid superfluous memory
kpeter@735
   299
    /// allocation: if you know that the digraph you want to build will
kpeter@735
   300
    /// be large (e.g. it will contain millions of nodes and/or arcs),
kpeter@735
   301
    /// then it is worth reserving space for this amount before starting
kpeter@735
   302
    /// to build the digraph.
kpeter@735
   303
    /// \sa reserveNode()
kpeter@735
   304
    void reserveArc(int m) { arcs.reserve(m); };
kpeter@735
   305
deba@109
   306
  public:
alpar@209
   307
deba@109
   308
    class Snapshot;
deba@109
   309
deba@109
   310
  protected:
deba@109
   311
deba@109
   312
    void restoreSnapshot(const Snapshot &s)
deba@109
   313
    {
deba@109
   314
      while(s.arc_num<arcs.size()) {
deba@109
   315
        Arc arc = arcFromId(arcs.size()-1);
alpar@209
   316
        Parent::notifier(Arc()).erase(arc);
alpar@209
   317
        nodes[arcs.back().source].first_out=arcs.back().next_out;
alpar@209
   318
        nodes[arcs.back().target].first_in=arcs.back().next_in;
alpar@209
   319
        arcs.pop_back();
deba@109
   320
      }
deba@109
   321
      while(s.node_num<nodes.size()) {
deba@109
   322
        Node node = nodeFromId(nodes.size()-1);
alpar@209
   323
        Parent::notifier(Node()).erase(node);
alpar@209
   324
        nodes.pop_back();
deba@109
   325
      }
alpar@209
   326
    }
deba@109
   327
deba@109
   328
  public:
deba@109
   329
kpeter@735
   330
    ///Class to make a snapshot of the digraph and to restore it later.
deba@109
   331
kpeter@735
   332
    ///Class to make a snapshot of the digraph and to restore it later.
deba@109
   333
    ///
deba@109
   334
    ///The newly added nodes and arcs can be removed using the
kpeter@735
   335
    ///restore() function. This is the only way for deleting nodes and/or
kpeter@735
   336
    ///arcs from a SmartDigraph structure.
deba@109
   337
    ///
alpar@877
   338
    ///\note After a state is restored, you cannot restore a later state,
kpeter@735
   339
    ///i.e. you cannot add the removed nodes and arcs again using
kpeter@735
   340
    ///another Snapshot instance.
kpeter@735
   341
    ///
kpeter@735
   342
    ///\warning Node splitting cannot be restored.
kpeter@735
   343
    ///\warning The validity of the snapshot is not stored due to
kpeter@735
   344
    ///performance reasons. If you do not use the snapshot correctly,
kpeter@735
   345
    ///it can cause broken program, invalid or not restored state of
kpeter@735
   346
    ///the digraph or no change.
alpar@209
   347
    class Snapshot
deba@109
   348
    {
deba@109
   349
      SmartDigraph *_graph;
deba@109
   350
    protected:
deba@109
   351
      friend class SmartDigraph;
deba@109
   352
      unsigned int node_num;
deba@109
   353
      unsigned int arc_num;
deba@109
   354
    public:
deba@109
   355
      ///Default constructor.
alpar@209
   356
deba@109
   357
      ///Default constructor.
kpeter@735
   358
      ///You have to call save() to actually make a snapshot.
deba@109
   359
      Snapshot() : _graph(0) {}
deba@109
   360
      ///Constructor that immediately makes a snapshot
alpar@209
   361
kpeter@735
   362
      ///This constructor immediately makes a snapshot of the given digraph.
kpeter@735
   363
      ///
kpeter@735
   364
      Snapshot(SmartDigraph &gr) : _graph(&gr) {
alpar@209
   365
        node_num=_graph->nodes.size();
alpar@209
   366
        arc_num=_graph->arcs.size();
deba@109
   367
      }
deba@109
   368
deba@109
   369
      ///Make a snapshot.
deba@109
   370
kpeter@735
   371
      ///This function makes a snapshot of the given digraph.
kpeter@735
   372
      ///It can be called more than once. In case of a repeated
deba@109
   373
      ///call, the previous snapshot gets lost.
kpeter@735
   374
      void save(SmartDigraph &gr) {
kpeter@735
   375
        _graph=&gr;
alpar@209
   376
        node_num=_graph->nodes.size();
alpar@209
   377
        arc_num=_graph->arcs.size();
deba@109
   378
      }
deba@109
   379
deba@109
   380
      ///Undo the changes until a snapshot.
alpar@209
   381
kpeter@735
   382
      ///This function undos the changes until the last snapshot
kpeter@735
   383
      ///created by save() or Snapshot(SmartDigraph&).
deba@109
   384
      void restore()
deba@109
   385
      {
alpar@209
   386
        _graph->restoreSnapshot(*this);
deba@109
   387
      }
deba@109
   388
    };
deba@109
   389
  };
deba@109
   390
deba@109
   391
deba@109
   392
  class SmartGraphBase {
deba@109
   393
deba@109
   394
  protected:
deba@109
   395
deba@109
   396
    struct NodeT {
deba@109
   397
      int first_out;
deba@109
   398
    };
alpar@209
   399
deba@109
   400
    struct ArcT {
deba@109
   401
      int target;
deba@109
   402
      int next_out;
deba@109
   403
    };
deba@109
   404
deba@109
   405
    std::vector<NodeT> nodes;
deba@109
   406
    std::vector<ArcT> arcs;
deba@109
   407
deba@109
   408
    int first_free_arc;
alpar@209
   409
deba@109
   410
  public:
alpar@209
   411
kpeter@617
   412
    typedef SmartGraphBase Graph;
deba@109
   413
deba@109
   414
    class Node;
deba@109
   415
    class Arc;
deba@109
   416
    class Edge;
alpar@209
   417
deba@109
   418
    class Node {
deba@109
   419
      friend class SmartGraphBase;
deba@109
   420
    protected:
deba@109
   421
deba@109
   422
      int _id;
deba@109
   423
      explicit Node(int id) { _id = id;}
deba@109
   424
deba@109
   425
    public:
deba@109
   426
      Node() {}
deba@109
   427
      Node (Invalid) { _id = -1; }
deba@109
   428
      bool operator==(const Node& node) const {return _id == node._id;}
deba@109
   429
      bool operator!=(const Node& node) const {return _id != node._id;}
deba@109
   430
      bool operator<(const Node& node) const {return _id < node._id;}
deba@109
   431
    };
deba@109
   432
deba@109
   433
    class Edge {
deba@109
   434
      friend class SmartGraphBase;
deba@109
   435
    protected:
deba@109
   436
deba@109
   437
      int _id;
deba@109
   438
      explicit Edge(int id) { _id = id;}
deba@109
   439
deba@109
   440
    public:
deba@109
   441
      Edge() {}
deba@109
   442
      Edge (Invalid) { _id = -1; }
deba@109
   443
      bool operator==(const Edge& arc) const {return _id == arc._id;}
deba@109
   444
      bool operator!=(const Edge& arc) const {return _id != arc._id;}
deba@109
   445
      bool operator<(const Edge& arc) const {return _id < arc._id;}
deba@109
   446
    };
deba@109
   447
deba@109
   448
    class Arc {
deba@109
   449
      friend class SmartGraphBase;
deba@109
   450
    protected:
deba@109
   451
deba@109
   452
      int _id;
deba@109
   453
      explicit Arc(int id) { _id = id;}
deba@109
   454
deba@109
   455
    public:
kpeter@329
   456
      operator Edge() const {
kpeter@329
   457
        return _id != -1 ? edgeFromId(_id / 2) : INVALID;
deba@238
   458
      }
deba@109
   459
deba@109
   460
      Arc() {}
deba@109
   461
      Arc (Invalid) { _id = -1; }
deba@109
   462
      bool operator==(const Arc& arc) const {return _id == arc._id;}
deba@109
   463
      bool operator!=(const Arc& arc) const {return _id != arc._id;}
deba@109
   464
      bool operator<(const Arc& arc) const {return _id < arc._id;}
deba@109
   465
    };
deba@109
   466
deba@109
   467
deba@109
   468
deba@109
   469
    SmartGraphBase()
deba@109
   470
      : nodes(), arcs() {}
deba@109
   471
kpeter@368
   472
    typedef True NodeNumTag;
kpeter@368
   473
    typedef True EdgeNumTag;
kpeter@368
   474
    typedef True ArcNumTag;
kpeter@368
   475
kpeter@368
   476
    int nodeNum() const { return nodes.size(); }
kpeter@368
   477
    int edgeNum() const { return arcs.size() / 2; }
kpeter@368
   478
    int arcNum() const { return arcs.size(); }
alpar@209
   479
alpar@209
   480
    int maxNodeId() const { return nodes.size()-1; }
deba@109
   481
    int maxEdgeId() const { return arcs.size() / 2 - 1; }
deba@109
   482
    int maxArcId() const { return arcs.size()-1; }
deba@109
   483
deba@109
   484
    Node source(Arc e) const { return Node(arcs[e._id ^ 1].target); }
deba@109
   485
    Node target(Arc e) const { return Node(arcs[e._id].target); }
deba@109
   486
deba@125
   487
    Node u(Edge e) const { return Node(arcs[2 * e._id].target); }
deba@125
   488
    Node v(Edge e) const { return Node(arcs[2 * e._id + 1].target); }
deba@109
   489
deba@109
   490
    static bool direction(Arc e) {
deba@109
   491
      return (e._id & 1) == 1;
deba@109
   492
    }
deba@109
   493
deba@109
   494
    static Arc direct(Edge e, bool d) {
deba@109
   495
      return Arc(e._id * 2 + (d ? 1 : 0));
deba@109
   496
    }
deba@109
   497
alpar@209
   498
    void first(Node& node) const {
deba@109
   499
      node._id = nodes.size() - 1;
deba@109
   500
    }
deba@109
   501
kpeter@778
   502
    static void next(Node& node) {
deba@109
   503
      --node._id;
deba@109
   504
    }
deba@109
   505
alpar@209
   506
    void first(Arc& arc) const {
deba@109
   507
      arc._id = arcs.size() - 1;
deba@109
   508
    }
deba@109
   509
kpeter@778
   510
    static void next(Arc& arc) {
deba@109
   511
      --arc._id;
deba@109
   512
    }
deba@109
   513
alpar@209
   514
    void first(Edge& arc) const {
deba@109
   515
      arc._id = arcs.size() / 2 - 1;
deba@109
   516
    }
deba@109
   517
kpeter@778
   518
    static void next(Edge& arc) {
deba@109
   519
      --arc._id;
deba@109
   520
    }
deba@109
   521
deba@109
   522
    void firstOut(Arc &arc, const Node& v) const {
deba@109
   523
      arc._id = nodes[v._id].first_out;
deba@109
   524
    }
deba@109
   525
    void nextOut(Arc &arc) const {
deba@109
   526
      arc._id = arcs[arc._id].next_out;
deba@109
   527
    }
deba@109
   528
deba@109
   529
    void firstIn(Arc &arc, const Node& v) const {
deba@109
   530
      arc._id = ((nodes[v._id].first_out) ^ 1);
deba@109
   531
      if (arc._id == -2) arc._id = -1;
deba@109
   532
    }
deba@109
   533
    void nextIn(Arc &arc) const {
deba@109
   534
      arc._id = ((arcs[arc._id ^ 1].next_out) ^ 1);
deba@109
   535
      if (arc._id == -2) arc._id = -1;
deba@109
   536
    }
deba@109
   537
deba@109
   538
    void firstInc(Edge &arc, bool& d, const Node& v) const {
deba@109
   539
      int de = nodes[v._id].first_out;
deba@109
   540
      if (de != -1) {
deba@109
   541
        arc._id = de / 2;
deba@109
   542
        d = ((de & 1) == 1);
deba@109
   543
      } else {
deba@109
   544
        arc._id = -1;
deba@109
   545
        d = true;
deba@109
   546
      }
deba@109
   547
    }
deba@109
   548
    void nextInc(Edge &arc, bool& d) const {
deba@109
   549
      int de = (arcs[(arc._id * 2) | (d ? 1 : 0)].next_out);
deba@109
   550
      if (de != -1) {
deba@109
   551
        arc._id = de / 2;
deba@109
   552
        d = ((de & 1) == 1);
deba@109
   553
      } else {
deba@109
   554
        arc._id = -1;
alpar@209
   555
        d = true;
deba@109
   556
      }
deba@109
   557
    }
alpar@209
   558
deba@109
   559
    static int id(Node v) { return v._id; }
deba@109
   560
    static int id(Arc e) { return e._id; }
deba@109
   561
    static int id(Edge e) { return e._id; }
deba@109
   562
deba@109
   563
    static Node nodeFromId(int id) { return Node(id);}
deba@109
   564
    static Arc arcFromId(int id) { return Arc(id);}
deba@109
   565
    static Edge edgeFromId(int id) { return Edge(id);}
deba@109
   566
alpar@209
   567
    bool valid(Node n) const {
alpar@209
   568
      return n._id >= 0 && n._id < static_cast<int>(nodes.size());
deba@149
   569
    }
alpar@209
   570
    bool valid(Arc a) const {
deba@149
   571
      return a._id >= 0 && a._id < static_cast<int>(arcs.size());
deba@149
   572
    }
alpar@209
   573
    bool valid(Edge e) const {
alpar@209
   574
      return e._id >= 0 && 2 * e._id < static_cast<int>(arcs.size());
deba@149
   575
    }
deba@149
   576
alpar@209
   577
    Node addNode() {
deba@109
   578
      int n = nodes.size();
deba@109
   579
      nodes.push_back(NodeT());
deba@109
   580
      nodes[n].first_out = -1;
alpar@209
   581
deba@109
   582
      return Node(n);
deba@109
   583
    }
alpar@209
   584
deba@138
   585
    Edge addEdge(Node u, Node v) {
deba@109
   586
      int n = arcs.size();
deba@109
   587
      arcs.push_back(ArcT());
deba@109
   588
      arcs.push_back(ArcT());
alpar@209
   589
deba@109
   590
      arcs[n].target = u._id;
deba@109
   591
      arcs[n | 1].target = v._id;
deba@109
   592
deba@109
   593
      arcs[n].next_out = nodes[v._id].first_out;
deba@109
   594
      nodes[v._id].first_out = n;
deba@109
   595
alpar@209
   596
      arcs[n | 1].next_out = nodes[u._id].first_out;
deba@109
   597
      nodes[u._id].first_out = (n | 1);
deba@109
   598
deba@109
   599
      return Edge(n / 2);
deba@109
   600
    }
alpar@209
   601
deba@109
   602
    void clear() {
deba@109
   603
      arcs.clear();
deba@109
   604
      nodes.clear();
deba@109
   605
    }
deba@109
   606
deba@109
   607
  };
deba@109
   608
deba@109
   609
  typedef GraphExtender<SmartGraphBase> ExtendedSmartGraphBase;
deba@109
   610
deba@109
   611
  /// \ingroup graphs
deba@109
   612
  ///
deba@109
   613
  /// \brief A smart undirected graph class.
deba@109
   614
  ///
kpeter@735
   615
  /// \ref SmartGraph is a simple and fast graph implementation.
kpeter@735
   616
  /// It is also quite memory efficient but at the price
alpar@877
   617
  /// that it does not support node and edge deletion
kpeter@735
   618
  /// (except for the Snapshot feature).
deba@109
   619
  ///
kpeter@735
   620
  /// This type fully conforms to the \ref concepts::Graph "Graph concept"
kpeter@735
   621
  /// and it also provides some additional functionalities.
kpeter@735
   622
  /// Most of its member functions and nested classes are documented
kpeter@735
   623
  /// only in the concept class.
kpeter@735
   624
  ///
kpeter@787
   625
  /// This class provides constant time counting for nodes, edges and arcs.
kpeter@787
   626
  ///
kpeter@735
   627
  /// \sa concepts::Graph
kpeter@735
   628
  /// \sa SmartDigraph
deba@109
   629
  class SmartGraph : public ExtendedSmartGraphBase {
kpeter@617
   630
    typedef ExtendedSmartGraphBase Parent;
kpeter@617
   631
deba@109
   632
  private:
kpeter@735
   633
    /// Graphs are \e not copy constructible. Use GraphCopy instead.
deba@109
   634
    SmartGraph(const SmartGraph &) : ExtendedSmartGraphBase() {};
kpeter@735
   635
    /// \brief Assignment of a graph to another one is \e not allowed.
kpeter@735
   636
    /// Use GraphCopy instead.
deba@109
   637
    void operator=(const SmartGraph &) {}
deba@109
   638
deba@109
   639
  public:
deba@109
   640
deba@109
   641
    /// Constructor
alpar@209
   642
deba@109
   643
    /// Constructor.
deba@109
   644
    ///
deba@109
   645
    SmartGraph() {}
deba@109
   646
kpeter@735
   647
    /// \brief Add a new node to the graph.
kpeter@735
   648
    ///
kpeter@735
   649
    /// This function adds a new node to the graph.
kpeter@559
   650
    /// \return The new node.
deba@109
   651
    Node addNode() { return Parent::addNode(); }
alpar@209
   652
kpeter@735
   653
    /// \brief Add a new edge to the graph.
kpeter@735
   654
    ///
kpeter@735
   655
    /// This function adds a new edge to the graph between nodes
kpeter@735
   656
    /// \c u and \c v with inherent orientation from node \c u to
kpeter@735
   657
    /// node \c v.
kpeter@735
   658
    /// \return The new edge.
kpeter@735
   659
    Edge addEdge(Node u, Node v) {
kpeter@735
   660
      return Parent::addEdge(u, v);
deba@109
   661
    }
deba@109
   662
deba@149
   663
    /// \brief Node validity check
deba@149
   664
    ///
kpeter@735
   665
    /// This function gives back \c true if the given node is valid,
kpeter@735
   666
    /// i.e. it is a real node of the graph.
deba@149
   667
    ///
deba@149
   668
    /// \warning A removed node (using Snapshot) could become valid again
kpeter@735
   669
    /// if new nodes are added to the graph.
deba@149
   670
    bool valid(Node n) const { return Parent::valid(n); }
deba@149
   671
kpeter@735
   672
    /// \brief Edge validity check
kpeter@735
   673
    ///
kpeter@735
   674
    /// This function gives back \c true if the given edge is valid,
kpeter@735
   675
    /// i.e. it is a real edge of the graph.
kpeter@735
   676
    ///
kpeter@735
   677
    /// \warning A removed edge (using Snapshot) could become valid again
kpeter@735
   678
    /// if new edges are added to the graph.
kpeter@735
   679
    bool valid(Edge e) const { return Parent::valid(e); }
kpeter@735
   680
deba@149
   681
    /// \brief Arc validity check
deba@149
   682
    ///
kpeter@735
   683
    /// This function gives back \c true if the given arc is valid,
kpeter@735
   684
    /// i.e. it is a real arc of the graph.
deba@149
   685
    ///
deba@149
   686
    /// \warning A removed arc (using Snapshot) could become valid again
kpeter@735
   687
    /// if new edges are added to the graph.
deba@149
   688
    bool valid(Arc a) const { return Parent::valid(a); }
deba@149
   689
deba@109
   690
    ///Clear the graph.
alpar@209
   691
kpeter@735
   692
    ///This function erases all nodes and arcs from the graph.
deba@109
   693
    ///
deba@109
   694
    void clear() {
deba@109
   695
      Parent::clear();
deba@109
   696
    }
deba@109
   697
kpeter@736
   698
    /// Reserve memory for nodes.
kpeter@736
   699
kpeter@736
   700
    /// Using this function, it is possible to avoid superfluous memory
kpeter@736
   701
    /// allocation: if you know that the graph you want to build will
kpeter@736
   702
    /// be large (e.g. it will contain millions of nodes and/or edges),
kpeter@736
   703
    /// then it is worth reserving space for this amount before starting
kpeter@736
   704
    /// to build the graph.
kpeter@736
   705
    /// \sa reserveEdge()
kpeter@736
   706
    void reserveNode(int n) { nodes.reserve(n); };
kpeter@736
   707
kpeter@736
   708
    /// Reserve memory for edges.
kpeter@736
   709
kpeter@736
   710
    /// Using this function, it is possible to avoid superfluous memory
kpeter@736
   711
    /// allocation: if you know that the graph you want to build will
kpeter@736
   712
    /// be large (e.g. it will contain millions of nodes and/or edges),
kpeter@736
   713
    /// then it is worth reserving space for this amount before starting
kpeter@736
   714
    /// to build the graph.
kpeter@736
   715
    /// \sa reserveNode()
kpeter@736
   716
    void reserveEdge(int m) { arcs.reserve(2 * m); };
kpeter@736
   717
deba@109
   718
  public:
alpar@209
   719
deba@109
   720
    class Snapshot;
deba@109
   721
deba@109
   722
  protected:
deba@109
   723
deba@109
   724
    void saveSnapshot(Snapshot &s)
deba@109
   725
    {
deba@109
   726
      s._graph = this;
deba@109
   727
      s.node_num = nodes.size();
deba@109
   728
      s.arc_num = arcs.size();
deba@109
   729
    }
deba@109
   730
deba@109
   731
    void restoreSnapshot(const Snapshot &s)
deba@109
   732
    {
deba@109
   733
      while(s.arc_num<arcs.size()) {
deba@109
   734
        int n=arcs.size()-1;
deba@109
   735
        Edge arc=edgeFromId(n/2);
alpar@209
   736
        Parent::notifier(Edge()).erase(arc);
deba@109
   737
        std::vector<Arc> dir;
deba@109
   738
        dir.push_back(arcFromId(n));
deba@109
   739
        dir.push_back(arcFromId(n-1));
alpar@209
   740
        Parent::notifier(Arc()).erase(dir);
kpeter@373
   741
        nodes[arcs[n-1].target].first_out=arcs[n].next_out;
kpeter@373
   742
        nodes[arcs[n].target].first_out=arcs[n-1].next_out;
alpar@209
   743
        arcs.pop_back();
alpar@209
   744
        arcs.pop_back();
deba@109
   745
      }
deba@109
   746
      while(s.node_num<nodes.size()) {
deba@109
   747
        int n=nodes.size()-1;
deba@109
   748
        Node node = nodeFromId(n);
alpar@209
   749
        Parent::notifier(Node()).erase(node);
alpar@209
   750
        nodes.pop_back();
deba@109
   751
      }
alpar@209
   752
    }
deba@109
   753
deba@109
   754
  public:
deba@109
   755
kpeter@735
   756
    ///Class to make a snapshot of the graph and to restore it later.
deba@109
   757
kpeter@735
   758
    ///Class to make a snapshot of the graph and to restore it later.
deba@109
   759
    ///
kpeter@735
   760
    ///The newly added nodes and edges can be removed using the
kpeter@735
   761
    ///restore() function. This is the only way for deleting nodes and/or
kpeter@735
   762
    ///edges from a SmartGraph structure.
deba@109
   763
    ///
alpar@877
   764
    ///\note After a state is restored, you cannot restore a later state,
kpeter@735
   765
    ///i.e. you cannot add the removed nodes and edges again using
kpeter@735
   766
    ///another Snapshot instance.
deba@109
   767
    ///
kpeter@735
   768
    ///\warning The validity of the snapshot is not stored due to
kpeter@735
   769
    ///performance reasons. If you do not use the snapshot correctly,
kpeter@735
   770
    ///it can cause broken program, invalid or not restored state of
kpeter@735
   771
    ///the graph or no change.
alpar@209
   772
    class Snapshot
deba@109
   773
    {
deba@109
   774
      SmartGraph *_graph;
deba@109
   775
    protected:
deba@109
   776
      friend class SmartGraph;
deba@109
   777
      unsigned int node_num;
deba@109
   778
      unsigned int arc_num;
deba@109
   779
    public:
deba@109
   780
      ///Default constructor.
alpar@209
   781
deba@109
   782
      ///Default constructor.
kpeter@735
   783
      ///You have to call save() to actually make a snapshot.
deba@109
   784
      Snapshot() : _graph(0) {}
deba@109
   785
      ///Constructor that immediately makes a snapshot
alpar@209
   786
kpeter@735
   787
      /// This constructor immediately makes a snapshot of the given graph.
kpeter@735
   788
      ///
kpeter@735
   789
      Snapshot(SmartGraph &gr) {
kpeter@735
   790
        gr.saveSnapshot(*this);
deba@109
   791
      }
deba@109
   792
deba@109
   793
      ///Make a snapshot.
deba@109
   794
kpeter@735
   795
      ///This function makes a snapshot of the given graph.
kpeter@735
   796
      ///It can be called more than once. In case of a repeated
deba@109
   797
      ///call, the previous snapshot gets lost.
kpeter@735
   798
      void save(SmartGraph &gr)
deba@109
   799
      {
kpeter@735
   800
        gr.saveSnapshot(*this);
deba@109
   801
      }
deba@109
   802
kpeter@735
   803
      ///Undo the changes until the last snapshot.
alpar@209
   804
kpeter@735
   805
      ///This function undos the changes until the last snapshot
kpeter@735
   806
      ///created by save() or Snapshot(SmartGraph&).
deba@109
   807
      void restore()
deba@109
   808
      {
deba@109
   809
        _graph->restoreSnapshot(*this);
deba@109
   810
      }
deba@109
   811
    };
deba@109
   812
  };
alpar@209
   813
deba@109
   814
} //namespace lemon
deba@109
   815
deba@109
   816
deba@109
   817
#endif //LEMON_SMART_GRAPH_H