lemon/smart_graph.h
author Balazs Dezso <deba@inf.elte.hu>
Thu, 24 Jun 2010 09:27:53 +0200
changeset 894 bb70ad62c95f
parent 582 7a28e215f715
child 735 853fcddcf282
child 778 a143f19f465b
permissions -rw-r--r--
Fix critical bug in preflow (#372)

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