lemon/bits/edge_set_extender.h
author Peter Kovacs <kpeter@inf.elte.hu>
Tue, 15 Mar 2011 19:32:21 +0100
changeset 936 ddd3c0d3d9bf
parent 877 141f9c0db4a3
parent 882 ece1f8a3052d
child 966 c8fce9beb46a
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@877
     1
/* -*- mode: C++; indent-tabs-mode: nil; -*-
deba@468
     2
 *
alpar@877
     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_BITS_EDGE_SET_EXTENDER_H
deba@468
    20
#define LEMON_BITS_EDGE_SET_EXTENDER_H
deba@468
    21
deba@519
    22
#include <lemon/core.h>
deba@468
    23
#include <lemon/error.h>
deba@468
    24
#include <lemon/bits/default_map.h>
deba@519
    25
#include <lemon/bits/map_extender.h>
deba@468
    26
kpeter@559
    27
//\ingroup digraphbits
kpeter@559
    28
//\file
kpeter@559
    29
//\brief Extenders for the arc set types
deba@468
    30
namespace lemon {
deba@468
    31
kpeter@559
    32
  // \ingroup digraphbits
kpeter@559
    33
  //
kpeter@559
    34
  // \brief Extender for the ArcSets
deba@468
    35
  template <typename Base>
deba@468
    36
  class ArcSetExtender : public Base {
kpeter@617
    37
    typedef Base Parent;
kpeter@617
    38
deba@468
    39
  public:
deba@468
    40
deba@468
    41
    typedef ArcSetExtender Digraph;
deba@468
    42
deba@468
    43
    // Base extensions
deba@468
    44
deba@468
    45
    typedef typename Parent::Node Node;
deba@468
    46
    typedef typename Parent::Arc Arc;
deba@468
    47
deba@468
    48
    int maxId(Node) const {
deba@468
    49
      return Parent::maxNodeId();
deba@468
    50
    }
deba@468
    51
deba@468
    52
    int maxId(Arc) const {
deba@468
    53
      return Parent::maxArcId();
deba@468
    54
    }
deba@468
    55
deba@468
    56
    Node fromId(int id, Node) const {
deba@468
    57
      return Parent::nodeFromId(id);
deba@468
    58
    }
deba@468
    59
deba@468
    60
    Arc fromId(int id, Arc) const {
deba@468
    61
      return Parent::arcFromId(id);
deba@468
    62
    }
deba@468
    63
deba@468
    64
    Node oppositeNode(const Node &n, const Arc &e) const {
deba@468
    65
      if (n == Parent::source(e))
alpar@877
    66
        return Parent::target(e);
deba@468
    67
      else if(n==Parent::target(e))
alpar@877
    68
        return Parent::source(e);
deba@468
    69
      else
alpar@877
    70
        return INVALID;
deba@468
    71
    }
deba@468
    72
deba@468
    73
deba@468
    74
    // Alteration notifier extensions
deba@468
    75
kpeter@559
    76
    // The arc observer registry.
deba@468
    77
    typedef AlterationNotifier<ArcSetExtender, Arc> ArcNotifier;
deba@468
    78
deba@468
    79
  protected:
deba@468
    80
deba@468
    81
    mutable ArcNotifier arc_notifier;
deba@468
    82
deba@468
    83
  public:
deba@468
    84
deba@468
    85
    using Parent::notifier;
deba@468
    86
kpeter@559
    87
    // Gives back the arc alteration notifier.
deba@468
    88
    ArcNotifier& notifier(Arc) const {
deba@468
    89
      return arc_notifier;
deba@468
    90
    }
deba@468
    91
deba@468
    92
    // Iterable extensions
deba@468
    93
alpar@877
    94
    class NodeIt : public Node {
deba@468
    95
      const Digraph* digraph;
deba@468
    96
    public:
deba@468
    97
deba@468
    98
      NodeIt() {}
deba@468
    99
deba@468
   100
      NodeIt(Invalid i) : Node(i) { }
deba@468
   101
deba@468
   102
      explicit NodeIt(const Digraph& _graph) : digraph(&_graph) {
alpar@877
   103
        _graph.first(static_cast<Node&>(*this));
deba@468
   104
      }
deba@468
   105
alpar@877
   106
      NodeIt(const Digraph& _graph, const Node& node)
alpar@877
   107
        : Node(node), digraph(&_graph) {}
deba@468
   108
alpar@877
   109
      NodeIt& operator++() {
alpar@877
   110
        digraph->next(*this);
alpar@877
   111
        return *this;
deba@468
   112
      }
deba@468
   113
deba@468
   114
    };
deba@468
   115
deba@468
   116
alpar@877
   117
    class ArcIt : public Arc {
deba@468
   118
      const Digraph* digraph;
deba@468
   119
    public:
deba@468
   120
deba@468
   121
      ArcIt() { }
deba@468
   122
deba@468
   123
      ArcIt(Invalid i) : Arc(i) { }
deba@468
   124
deba@468
   125
      explicit ArcIt(const Digraph& _graph) : digraph(&_graph) {
alpar@877
   126
        _graph.first(static_cast<Arc&>(*this));
deba@468
   127
      }
deba@468
   128
alpar@877
   129
      ArcIt(const Digraph& _graph, const Arc& e) :
alpar@877
   130
        Arc(e), digraph(&_graph) { }
deba@468
   131
alpar@877
   132
      ArcIt& operator++() {
alpar@877
   133
        digraph->next(*this);
alpar@877
   134
        return *this;
deba@468
   135
      }
deba@468
   136
deba@468
   137
    };
deba@468
   138
deba@468
   139
alpar@877
   140
    class OutArcIt : public Arc {
deba@468
   141
      const Digraph* digraph;
deba@468
   142
    public:
deba@468
   143
deba@468
   144
      OutArcIt() { }
deba@468
   145
deba@468
   146
      OutArcIt(Invalid i) : Arc(i) { }
deba@468
   147
alpar@877
   148
      OutArcIt(const Digraph& _graph, const Node& node)
alpar@877
   149
        : digraph(&_graph) {
alpar@877
   150
        _graph.firstOut(*this, node);
deba@468
   151
      }
deba@468
   152
alpar@877
   153
      OutArcIt(const Digraph& _graph, const Arc& arc)
alpar@877
   154
        : Arc(arc), digraph(&_graph) {}
deba@468
   155
alpar@877
   156
      OutArcIt& operator++() {
alpar@877
   157
        digraph->nextOut(*this);
alpar@877
   158
        return *this;
deba@468
   159
      }
deba@468
   160
deba@468
   161
    };
deba@468
   162
deba@468
   163
alpar@877
   164
    class InArcIt : public Arc {
deba@468
   165
      const Digraph* digraph;
deba@468
   166
    public:
deba@468
   167
deba@468
   168
      InArcIt() { }
deba@468
   169
deba@468
   170
      InArcIt(Invalid i) : Arc(i) { }
deba@468
   171
alpar@877
   172
      InArcIt(const Digraph& _graph, const Node& node)
alpar@877
   173
        : digraph(&_graph) {
alpar@877
   174
        _graph.firstIn(*this, node);
deba@468
   175
      }
deba@468
   176
alpar@877
   177
      InArcIt(const Digraph& _graph, const Arc& arc) :
alpar@877
   178
        Arc(arc), digraph(&_graph) {}
deba@468
   179
alpar@877
   180
      InArcIt& operator++() {
alpar@877
   181
        digraph->nextIn(*this);
alpar@877
   182
        return *this;
deba@468
   183
      }
deba@468
   184
deba@468
   185
    };
deba@468
   186
kpeter@559
   187
    // \brief Base node of the iterator
kpeter@559
   188
    //
kpeter@559
   189
    // Returns the base node (ie. the source in this case) of the iterator
deba@468
   190
    Node baseNode(const OutArcIt &e) const {
deba@468
   191
      return Parent::source(static_cast<const Arc&>(e));
deba@468
   192
    }
kpeter@559
   193
    // \brief Running node of the iterator
kpeter@559
   194
    //
kpeter@559
   195
    // Returns the running node (ie. the target in this case) of the
kpeter@559
   196
    // iterator
deba@468
   197
    Node runningNode(const OutArcIt &e) const {
deba@468
   198
      return Parent::target(static_cast<const Arc&>(e));
deba@468
   199
    }
deba@468
   200
kpeter@559
   201
    // \brief Base node of the iterator
kpeter@559
   202
    //
kpeter@559
   203
    // Returns the base node (ie. the target in this case) of the iterator
deba@468
   204
    Node baseNode(const InArcIt &e) const {
deba@468
   205
      return Parent::target(static_cast<const Arc&>(e));
deba@468
   206
    }
kpeter@559
   207
    // \brief Running node of the iterator
kpeter@559
   208
    //
kpeter@559
   209
    // Returns the running node (ie. the source in this case) of the
kpeter@559
   210
    // iterator
deba@468
   211
    Node runningNode(const InArcIt &e) const {
deba@468
   212
      return Parent::source(static_cast<const Arc&>(e));
deba@468
   213
    }
deba@468
   214
deba@468
   215
    using Parent::first;
deba@468
   216
deba@468
   217
    // Mappable extension
alpar@877
   218
deba@468
   219
    template <typename _Value>
alpar@877
   220
    class ArcMap
deba@468
   221
      : public MapExtender<DefaultMap<Digraph, Arc, _Value> > {
deba@468
   222
      typedef MapExtender<DefaultMap<Digraph, Arc, _Value> > Parent;
deba@468
   223
kpeter@617
   224
    public:
alpar@877
   225
      explicit ArcMap(const Digraph& _g)
alpar@877
   226
        : Parent(_g) {}
alpar@877
   227
      ArcMap(const Digraph& _g, const _Value& _v)
alpar@877
   228
        : Parent(_g, _v) {}
deba@468
   229
deba@468
   230
      ArcMap& operator=(const ArcMap& cmap) {
alpar@877
   231
        return operator=<ArcMap>(cmap);
deba@468
   232
      }
deba@468
   233
deba@468
   234
      template <typename CMap>
deba@468
   235
      ArcMap& operator=(const CMap& cmap) {
deba@468
   236
        Parent::operator=(cmap);
alpar@877
   237
        return *this;
deba@468
   238
      }
deba@468
   239
deba@468
   240
    };
deba@468
   241
deba@468
   242
deba@468
   243
    // Alteration extension
deba@468
   244
deba@468
   245
    Arc addArc(const Node& from, const Node& to) {
deba@468
   246
      Arc arc = Parent::addArc(from, to);
deba@468
   247
      notifier(Arc()).add(arc);
deba@468
   248
      return arc;
deba@468
   249
    }
alpar@877
   250
deba@468
   251
    void clear() {
deba@468
   252
      notifier(Arc()).clear();
deba@468
   253
      Parent::clear();
deba@468
   254
    }
deba@468
   255
deba@468
   256
    void erase(const Arc& arc) {
deba@468
   257
      notifier(Arc()).erase(arc);
deba@468
   258
      Parent::erase(arc);
deba@468
   259
    }
deba@468
   260
deba@468
   261
    ArcSetExtender() {
deba@468
   262
      arc_notifier.setContainer(*this);
deba@468
   263
    }
deba@468
   264
deba@468
   265
    ~ArcSetExtender() {
deba@468
   266
      arc_notifier.clear();
deba@468
   267
    }
deba@468
   268
deba@468
   269
  };
deba@468
   270
deba@468
   271
kpeter@559
   272
  // \ingroup digraphbits
kpeter@559
   273
  //
kpeter@559
   274
  // \brief Extender for the EdgeSets
deba@468
   275
  template <typename Base>
deba@468
   276
  class EdgeSetExtender : public Base {
kpeter@617
   277
    typedef Base Parent;
deba@468
   278
deba@468
   279
  public:
deba@468
   280
kpeter@617
   281
    typedef EdgeSetExtender Graph;
deba@468
   282
kpeter@882
   283
    typedef True UndirectedTag;
kpeter@882
   284
deba@468
   285
    typedef typename Parent::Node Node;
deba@468
   286
    typedef typename Parent::Arc Arc;
deba@468
   287
    typedef typename Parent::Edge Edge;
deba@468
   288
deba@468
   289
    int maxId(Node) const {
deba@468
   290
      return Parent::maxNodeId();
deba@468
   291
    }
deba@468
   292
deba@468
   293
    int maxId(Arc) const {
deba@468
   294
      return Parent::maxArcId();
deba@468
   295
    }
deba@468
   296
deba@468
   297
    int maxId(Edge) const {
deba@468
   298
      return Parent::maxEdgeId();
deba@468
   299
    }
deba@468
   300
deba@468
   301
    Node fromId(int id, Node) const {
deba@468
   302
      return Parent::nodeFromId(id);
deba@468
   303
    }
deba@468
   304
deba@468
   305
    Arc fromId(int id, Arc) const {
deba@468
   306
      return Parent::arcFromId(id);
deba@468
   307
    }
deba@468
   308
deba@468
   309
    Edge fromId(int id, Edge) const {
deba@468
   310
      return Parent::edgeFromId(id);
deba@468
   311
    }
deba@468
   312
deba@468
   313
    Node oppositeNode(const Node &n, const Edge &e) const {
deba@468
   314
      if( n == Parent::u(e))
alpar@877
   315
        return Parent::v(e);
deba@468
   316
      else if( n == Parent::v(e))
alpar@877
   317
        return Parent::u(e);
deba@468
   318
      else
alpar@877
   319
        return INVALID;
deba@468
   320
    }
deba@468
   321
deba@468
   322
    Arc oppositeArc(const Arc &e) const {
deba@468
   323
      return Parent::direct(e, !Parent::direction(e));
deba@468
   324
    }
deba@468
   325
deba@468
   326
    using Parent::direct;
deba@468
   327
    Arc direct(const Edge &e, const Node &s) const {
deba@468
   328
      return Parent::direct(e, Parent::u(e) == s);
deba@468
   329
    }
deba@468
   330
deba@468
   331
    typedef AlterationNotifier<EdgeSetExtender, Arc> ArcNotifier;
deba@468
   332
    typedef AlterationNotifier<EdgeSetExtender, Edge> EdgeNotifier;
deba@468
   333
deba@468
   334
deba@468
   335
  protected:
deba@468
   336
deba@468
   337
    mutable ArcNotifier arc_notifier;
deba@468
   338
    mutable EdgeNotifier edge_notifier;
deba@468
   339
deba@468
   340
  public:
deba@468
   341
deba@468
   342
    using Parent::notifier;
alpar@877
   343
deba@468
   344
    ArcNotifier& notifier(Arc) const {
deba@468
   345
      return arc_notifier;
deba@468
   346
    }
deba@468
   347
deba@468
   348
    EdgeNotifier& notifier(Edge) const {
deba@468
   349
      return edge_notifier;
deba@468
   350
    }
deba@468
   351
deba@468
   352
alpar@877
   353
    class NodeIt : public Node {
kpeter@617
   354
      const Graph* graph;
deba@468
   355
    public:
deba@468
   356
deba@468
   357
      NodeIt() {}
deba@468
   358
deba@468
   359
      NodeIt(Invalid i) : Node(i) { }
deba@468
   360
kpeter@617
   361
      explicit NodeIt(const Graph& _graph) : graph(&_graph) {
alpar@877
   362
        _graph.first(static_cast<Node&>(*this));
deba@468
   363
      }
deba@468
   364
alpar@877
   365
      NodeIt(const Graph& _graph, const Node& node)
alpar@877
   366
        : Node(node), graph(&_graph) {}
deba@468
   367
alpar@877
   368
      NodeIt& operator++() {
alpar@877
   369
        graph->next(*this);
alpar@877
   370
        return *this;
deba@468
   371
      }
deba@468
   372
deba@468
   373
    };
deba@468
   374
deba@468
   375
alpar@877
   376
    class ArcIt : public Arc {
kpeter@617
   377
      const Graph* graph;
deba@468
   378
    public:
deba@468
   379
deba@468
   380
      ArcIt() { }
deba@468
   381
deba@468
   382
      ArcIt(Invalid i) : Arc(i) { }
deba@468
   383
kpeter@617
   384
      explicit ArcIt(const Graph& _graph) : graph(&_graph) {
alpar@877
   385
        _graph.first(static_cast<Arc&>(*this));
deba@468
   386
      }
deba@468
   387
alpar@877
   388
      ArcIt(const Graph& _graph, const Arc& e) :
alpar@877
   389
        Arc(e), graph(&_graph) { }
deba@468
   390
alpar@877
   391
      ArcIt& operator++() {
alpar@877
   392
        graph->next(*this);
alpar@877
   393
        return *this;
deba@468
   394
      }
deba@468
   395
deba@468
   396
    };
deba@468
   397
deba@468
   398
alpar@877
   399
    class OutArcIt : public Arc {
kpeter@617
   400
      const Graph* graph;
deba@468
   401
    public:
deba@468
   402
deba@468
   403
      OutArcIt() { }
deba@468
   404
deba@468
   405
      OutArcIt(Invalid i) : Arc(i) { }
deba@468
   406
alpar@877
   407
      OutArcIt(const Graph& _graph, const Node& node)
alpar@877
   408
        : graph(&_graph) {
alpar@877
   409
        _graph.firstOut(*this, node);
deba@468
   410
      }
deba@468
   411
alpar@877
   412
      OutArcIt(const Graph& _graph, const Arc& arc)
alpar@877
   413
        : Arc(arc), graph(&_graph) {}
deba@468
   414
alpar@877
   415
      OutArcIt& operator++() {
alpar@877
   416
        graph->nextOut(*this);
alpar@877
   417
        return *this;
deba@468
   418
      }
deba@468
   419
deba@468
   420
    };
deba@468
   421
deba@468
   422
alpar@877
   423
    class InArcIt : public Arc {
kpeter@617
   424
      const Graph* graph;
deba@468
   425
    public:
deba@468
   426
deba@468
   427
      InArcIt() { }
deba@468
   428
deba@468
   429
      InArcIt(Invalid i) : Arc(i) { }
deba@468
   430
alpar@877
   431
      InArcIt(const Graph& _graph, const Node& node)
alpar@877
   432
        : graph(&_graph) {
alpar@877
   433
        _graph.firstIn(*this, node);
deba@468
   434
      }
deba@468
   435
alpar@877
   436
      InArcIt(const Graph& _graph, const Arc& arc) :
alpar@877
   437
        Arc(arc), graph(&_graph) {}
deba@468
   438
alpar@877
   439
      InArcIt& operator++() {
alpar@877
   440
        graph->nextIn(*this);
alpar@877
   441
        return *this;
deba@468
   442
      }
deba@468
   443
deba@468
   444
    };
deba@468
   445
deba@468
   446
alpar@877
   447
    class EdgeIt : public Parent::Edge {
kpeter@617
   448
      const Graph* graph;
deba@468
   449
    public:
deba@468
   450
deba@468
   451
      EdgeIt() { }
deba@468
   452
deba@468
   453
      EdgeIt(Invalid i) : Edge(i) { }
deba@468
   454
kpeter@617
   455
      explicit EdgeIt(const Graph& _graph) : graph(&_graph) {
alpar@877
   456
        _graph.first(static_cast<Edge&>(*this));
deba@468
   457
      }
deba@468
   458
alpar@877
   459
      EdgeIt(const Graph& _graph, const Edge& e) :
alpar@877
   460
        Edge(e), graph(&_graph) { }
deba@468
   461
alpar@877
   462
      EdgeIt& operator++() {
alpar@877
   463
        graph->next(*this);
alpar@877
   464
        return *this;
deba@468
   465
      }
deba@468
   466
deba@468
   467
    };
deba@468
   468
deba@468
   469
    class IncEdgeIt : public Parent::Edge {
deba@468
   470
      friend class EdgeSetExtender;
kpeter@617
   471
      const Graph* graph;
deba@468
   472
      bool direction;
deba@468
   473
    public:
deba@468
   474
deba@468
   475
      IncEdgeIt() { }
deba@468
   476
deba@468
   477
      IncEdgeIt(Invalid i) : Edge(i), direction(false) { }
deba@468
   478
kpeter@617
   479
      IncEdgeIt(const Graph& _graph, const Node &n) : graph(&_graph) {
alpar@877
   480
        _graph.firstInc(*this, direction, n);
deba@468
   481
      }
deba@468
   482
kpeter@617
   483
      IncEdgeIt(const Graph& _graph, const Edge &ue, const Node &n)
alpar@877
   484
        : graph(&_graph), Edge(ue) {
alpar@877
   485
        direction = (_graph.source(ue) == n);
deba@468
   486
      }
deba@468
   487
deba@468
   488
      IncEdgeIt& operator++() {
alpar@877
   489
        graph->nextInc(*this, direction);
alpar@877
   490
        return *this;
deba@468
   491
      }
deba@468
   492
    };
deba@468
   493
kpeter@559
   494
    // \brief Base node of the iterator
kpeter@559
   495
    //
kpeter@559
   496
    // Returns the base node (ie. the source in this case) of the iterator
deba@468
   497
    Node baseNode(const OutArcIt &e) const {
deba@468
   498
      return Parent::source(static_cast<const Arc&>(e));
deba@468
   499
    }
kpeter@559
   500
    // \brief Running node of the iterator
kpeter@559
   501
    //
kpeter@559
   502
    // Returns the running node (ie. the target in this case) of the
kpeter@559
   503
    // iterator
deba@468
   504
    Node runningNode(const OutArcIt &e) const {
deba@468
   505
      return Parent::target(static_cast<const Arc&>(e));
deba@468
   506
    }
deba@468
   507
kpeter@559
   508
    // \brief Base node of the iterator
kpeter@559
   509
    //
kpeter@559
   510
    // Returns the base node (ie. the target in this case) of the iterator
deba@468
   511
    Node baseNode(const InArcIt &e) const {
deba@468
   512
      return Parent::target(static_cast<const Arc&>(e));
deba@468
   513
    }
kpeter@559
   514
    // \brief Running node of the iterator
kpeter@559
   515
    //
kpeter@559
   516
    // Returns the running node (ie. the source in this case) of the
kpeter@559
   517
    // iterator
deba@468
   518
    Node runningNode(const InArcIt &e) const {
deba@468
   519
      return Parent::source(static_cast<const Arc&>(e));
deba@468
   520
    }
deba@468
   521
kpeter@559
   522
    // Base node of the iterator
kpeter@559
   523
    //
kpeter@559
   524
    // Returns the base node of the iterator
deba@468
   525
    Node baseNode(const IncEdgeIt &e) const {
deba@468
   526
      return e.direction ? u(e) : v(e);
deba@468
   527
    }
kpeter@559
   528
    // Running node of the iterator
kpeter@559
   529
    //
kpeter@559
   530
    // Returns the running node of the iterator
deba@468
   531
    Node runningNode(const IncEdgeIt &e) const {
deba@468
   532
      return e.direction ? v(e) : u(e);
deba@468
   533
    }
deba@468
   534
deba@468
   535
deba@468
   536
    template <typename _Value>
alpar@877
   537
    class ArcMap
kpeter@617
   538
      : public MapExtender<DefaultMap<Graph, Arc, _Value> > {
kpeter@617
   539
      typedef MapExtender<DefaultMap<Graph, Arc, _Value> > Parent;
kpeter@617
   540
deba@468
   541
    public:
alpar@877
   542
      explicit ArcMap(const Graph& _g)
alpar@877
   543
        : Parent(_g) {}
alpar@877
   544
      ArcMap(const Graph& _g, const _Value& _v)
alpar@877
   545
        : Parent(_g, _v) {}
deba@468
   546
deba@468
   547
      ArcMap& operator=(const ArcMap& cmap) {
alpar@877
   548
        return operator=<ArcMap>(cmap);
deba@468
   549
      }
deba@468
   550
deba@468
   551
      template <typename CMap>
deba@468
   552
      ArcMap& operator=(const CMap& cmap) {
deba@468
   553
        Parent::operator=(cmap);
alpar@877
   554
        return *this;
deba@468
   555
      }
deba@468
   556
deba@468
   557
    };
deba@468
   558
deba@468
   559
deba@468
   560
    template <typename _Value>
alpar@877
   561
    class EdgeMap
kpeter@617
   562
      : public MapExtender<DefaultMap<Graph, Edge, _Value> > {
kpeter@617
   563
      typedef MapExtender<DefaultMap<Graph, Edge, _Value> > Parent;
kpeter@617
   564
deba@468
   565
    public:
alpar@877
   566
      explicit EdgeMap(const Graph& _g)
alpar@877
   567
        : Parent(_g) {}
deba@468
   568
alpar@877
   569
      EdgeMap(const Graph& _g, const _Value& _v)
alpar@877
   570
        : Parent(_g, _v) {}
deba@468
   571
deba@468
   572
      EdgeMap& operator=(const EdgeMap& cmap) {
alpar@877
   573
        return operator=<EdgeMap>(cmap);
deba@468
   574
      }
deba@468
   575
deba@468
   576
      template <typename CMap>
deba@468
   577
      EdgeMap& operator=(const CMap& cmap) {
deba@468
   578
        Parent::operator=(cmap);
alpar@877
   579
        return *this;
deba@468
   580
      }
deba@468
   581
deba@468
   582
    };
deba@468
   583
deba@468
   584
deba@468
   585
    // Alteration extension
deba@468
   586
deba@468
   587
    Edge addEdge(const Node& from, const Node& to) {
deba@468
   588
      Edge edge = Parent::addEdge(from, to);
deba@468
   589
      notifier(Edge()).add(edge);
deba@468
   590
      std::vector<Arc> arcs;
deba@468
   591
      arcs.push_back(Parent::direct(edge, true));
deba@468
   592
      arcs.push_back(Parent::direct(edge, false));
deba@468
   593
      notifier(Arc()).add(arcs);
deba@468
   594
      return edge;
deba@468
   595
    }
alpar@877
   596
deba@468
   597
    void clear() {
deba@468
   598
      notifier(Arc()).clear();
deba@468
   599
      notifier(Edge()).clear();
deba@468
   600
      Parent::clear();
deba@468
   601
    }
deba@468
   602
deba@468
   603
    void erase(const Edge& edge) {
deba@468
   604
      std::vector<Arc> arcs;
deba@468
   605
      arcs.push_back(Parent::direct(edge, true));
deba@468
   606
      arcs.push_back(Parent::direct(edge, false));
deba@468
   607
      notifier(Arc()).erase(arcs);
deba@468
   608
      notifier(Edge()).erase(edge);
deba@468
   609
      Parent::erase(edge);
deba@468
   610
    }
deba@468
   611
deba@468
   612
deba@468
   613
    EdgeSetExtender() {
deba@468
   614
      arc_notifier.setContainer(*this);
deba@468
   615
      edge_notifier.setContainer(*this);
deba@468
   616
    }
deba@468
   617
deba@468
   618
    ~EdgeSetExtender() {
deba@468
   619
      edge_notifier.clear();
deba@468
   620
      arc_notifier.clear();
deba@468
   621
    }
alpar@877
   622
deba@468
   623
  };
deba@468
   624
deba@468
   625
}
deba@468
   626
deba@468
   627
#endif