lemon/bits/graph_adaptor_extender.h
author Balazs Dezso <deba@google.com>
Fri, 22 Jan 2021 10:55:32 +0100
changeset 1208 c6aa2cc1af04
parent 1130 0759d974de81
permissions -rw-r--r--
Factor out recursion from weighted matching algorithms (#638)
deba@416
     1
/* -*- mode: C++; indent-tabs-mode: nil; -*-
deba@414
     2
 *
deba@416
     3
 * This file is a part of LEMON, a generic C++ optimization library.
deba@414
     4
 *
alpar@1092
     5
 * Copyright (C) 2003-2013
deba@414
     6
 * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
deba@414
     7
 * (Egervary Research Group on Combinatorial Optimization, EGRES).
deba@414
     8
 *
deba@414
     9
 * Permission to use, modify and distribute this software is granted
deba@414
    10
 * provided that this copyright notice appears in all copies. For
deba@414
    11
 * precise terms see the accompanying LICENSE file.
deba@414
    12
 *
deba@414
    13
 * This software is provided "AS IS" with no warranty of any kind,
deba@414
    14
 * express or implied, and with no claim as to its suitability for any
deba@414
    15
 * purpose.
deba@414
    16
 *
deba@414
    17
 */
deba@414
    18
deba@414
    19
#ifndef LEMON_BITS_GRAPH_ADAPTOR_EXTENDER_H
deba@414
    20
#define LEMON_BITS_GRAPH_ADAPTOR_EXTENDER_H
deba@414
    21
deba@414
    22
#include <lemon/core.h>
deba@414
    23
#include <lemon/error.h>
deba@414
    24
deba@414
    25
namespace lemon {
deba@414
    26
deba@414
    27
  template <typename _Digraph>
deba@414
    28
  class DigraphAdaptorExtender : public _Digraph {
kpeter@617
    29
    typedef _Digraph Parent;
kpeter@617
    30
deba@414
    31
  public:
deba@414
    32
deba@414
    33
    typedef _Digraph Digraph;
deba@414
    34
    typedef DigraphAdaptorExtender Adaptor;
deba@414
    35
deba@414
    36
    // Base extensions
deba@414
    37
deba@414
    38
    typedef typename Parent::Node Node;
deba@414
    39
    typedef typename Parent::Arc Arc;
deba@414
    40
deba@414
    41
    int maxId(Node) const {
deba@414
    42
      return Parent::maxNodeId();
deba@414
    43
    }
deba@414
    44
deba@414
    45
    int maxId(Arc) const {
deba@414
    46
      return Parent::maxArcId();
deba@414
    47
    }
deba@414
    48
deba@414
    49
    Node fromId(int id, Node) const {
deba@414
    50
      return Parent::nodeFromId(id);
deba@414
    51
    }
deba@414
    52
deba@414
    53
    Arc fromId(int id, Arc) const {
deba@414
    54
      return Parent::arcFromId(id);
deba@414
    55
    }
deba@414
    56
deba@414
    57
    Node oppositeNode(const Node &n, const Arc &e) const {
deba@414
    58
      if (n == Parent::source(e))
deba@416
    59
        return Parent::target(e);
deba@414
    60
      else if(n==Parent::target(e))
deba@416
    61
        return Parent::source(e);
deba@414
    62
      else
deba@416
    63
        return INVALID;
deba@414
    64
    }
deba@414
    65
deba@416
    66
    class NodeIt : public Node {
deba@414
    67
      const Adaptor* _adaptor;
deba@414
    68
    public:
deba@414
    69
deba@414
    70
      NodeIt() {}
deba@414
    71
deba@414
    72
      NodeIt(Invalid i) : Node(i) { }
deba@414
    73
deba@414
    74
      explicit NodeIt(const Adaptor& adaptor) : _adaptor(&adaptor) {
deba@416
    75
        _adaptor->first(static_cast<Node&>(*this));
deba@414
    76
      }
deba@414
    77
deba@416
    78
      NodeIt(const Adaptor& adaptor, const Node& node)
deba@416
    79
        : Node(node), _adaptor(&adaptor) {}
deba@414
    80
deba@416
    81
      NodeIt& operator++() {
deba@416
    82
        _adaptor->next(*this);
deba@416
    83
        return *this;
deba@414
    84
      }
deba@414
    85
deba@414
    86
    };
deba@414
    87
alpar@1131
    88
    LemonRangeWrapper1<NodeIt, Adaptor> nodes() const {
ggab90@1130
    89
      return LemonRangeWrapper1<NodeIt, Adaptor>(*this);
ggab90@1130
    90
    }
deba@414
    91
deba@416
    92
    class ArcIt : public Arc {
deba@414
    93
      const Adaptor* _adaptor;
deba@414
    94
    public:
deba@414
    95
deba@414
    96
      ArcIt() { }
deba@414
    97
deba@414
    98
      ArcIt(Invalid i) : Arc(i) { }
deba@414
    99
deba@414
   100
      explicit ArcIt(const Adaptor& adaptor) : _adaptor(&adaptor) {
deba@416
   101
        _adaptor->first(static_cast<Arc&>(*this));
deba@414
   102
      }
deba@414
   103
deba@416
   104
      ArcIt(const Adaptor& adaptor, const Arc& e) :
deba@416
   105
        Arc(e), _adaptor(&adaptor) { }
deba@414
   106
deba@416
   107
      ArcIt& operator++() {
deba@416
   108
        _adaptor->next(*this);
deba@416
   109
        return *this;
deba@414
   110
      }
deba@414
   111
deba@414
   112
    };
deba@414
   113
alpar@1131
   114
    LemonRangeWrapper1<ArcIt, Adaptor> arcs() const {
ggab90@1130
   115
      return LemonRangeWrapper1<ArcIt, Adaptor>(*this);
ggab90@1130
   116
    }
ggab90@1130
   117
deba@414
   118
deba@416
   119
    class OutArcIt : public Arc {
deba@414
   120
      const Adaptor* _adaptor;
deba@414
   121
    public:
deba@414
   122
deba@414
   123
      OutArcIt() { }
deba@414
   124
deba@414
   125
      OutArcIt(Invalid i) : Arc(i) { }
deba@414
   126
deba@416
   127
      OutArcIt(const Adaptor& adaptor, const Node& node)
deba@416
   128
        : _adaptor(&adaptor) {
deba@416
   129
        _adaptor->firstOut(*this, node);
deba@414
   130
      }
deba@414
   131
deba@416
   132
      OutArcIt(const Adaptor& adaptor, const Arc& arc)
deba@416
   133
        : Arc(arc), _adaptor(&adaptor) {}
deba@414
   134
deba@416
   135
      OutArcIt& operator++() {
deba@416
   136
        _adaptor->nextOut(*this);
deba@416
   137
        return *this;
deba@414
   138
      }
deba@414
   139
deba@414
   140
    };
deba@414
   141
ggab90@1130
   142
    LemonRangeWrapper2<OutArcIt, Adaptor, Node> outArcs(const Node& u) const {
ggab90@1130
   143
      return LemonRangeWrapper2<OutArcIt, Adaptor, Node>(*this, u);
ggab90@1130
   144
    }
ggab90@1130
   145
deba@414
   146
deba@416
   147
    class InArcIt : public Arc {
deba@414
   148
      const Adaptor* _adaptor;
deba@414
   149
    public:
deba@414
   150
deba@414
   151
      InArcIt() { }
deba@414
   152
deba@414
   153
      InArcIt(Invalid i) : Arc(i) { }
deba@414
   154
deba@416
   155
      InArcIt(const Adaptor& adaptor, const Node& node)
deba@416
   156
        : _adaptor(&adaptor) {
deba@416
   157
        _adaptor->firstIn(*this, node);
deba@414
   158
      }
deba@414
   159
deba@416
   160
      InArcIt(const Adaptor& adaptor, const Arc& arc) :
deba@416
   161
        Arc(arc), _adaptor(&adaptor) {}
deba@414
   162
deba@416
   163
      InArcIt& operator++() {
deba@416
   164
        _adaptor->nextIn(*this);
deba@416
   165
        return *this;
deba@414
   166
      }
deba@414
   167
deba@414
   168
    };
deba@414
   169
ggab90@1130
   170
    LemonRangeWrapper2<InArcIt, Adaptor, Node> inArcs(const Node& u) const {
ggab90@1130
   171
      return LemonRangeWrapper2<InArcIt, Adaptor, Node>(*this, u);
ggab90@1130
   172
    }
ggab90@1130
   173
deba@414
   174
    Node baseNode(const OutArcIt &e) const {
deba@414
   175
      return Parent::source(e);
deba@414
   176
    }
deba@414
   177
    Node runningNode(const OutArcIt &e) const {
deba@414
   178
      return Parent::target(e);
deba@414
   179
    }
deba@414
   180
deba@414
   181
    Node baseNode(const InArcIt &e) const {
deba@414
   182
      return Parent::target(e);
deba@414
   183
    }
deba@414
   184
    Node runningNode(const InArcIt &e) const {
deba@414
   185
      return Parent::source(e);
deba@414
   186
    }
deba@414
   187
deba@414
   188
  };
deba@414
   189
deba@416
   190
  template <typename _Graph>
deba@414
   191
  class GraphAdaptorExtender : public _Graph {
kpeter@617
   192
    typedef _Graph Parent;
kpeter@617
   193
deba@414
   194
  public:
deba@416
   195
deba@414
   196
    typedef _Graph Graph;
deba@414
   197
    typedef GraphAdaptorExtender Adaptor;
deba@414
   198
kpeter@882
   199
    typedef True UndirectedTag;
kpeter@882
   200
deba@414
   201
    typedef typename Parent::Node Node;
deba@414
   202
    typedef typename Parent::Arc Arc;
deba@414
   203
    typedef typename Parent::Edge Edge;
deba@414
   204
deba@416
   205
    // Graph extension
deba@414
   206
deba@414
   207
    int maxId(Node) const {
deba@414
   208
      return Parent::maxNodeId();
deba@414
   209
    }
deba@414
   210
deba@414
   211
    int maxId(Arc) const {
deba@414
   212
      return Parent::maxArcId();
deba@414
   213
    }
deba@414
   214
deba@414
   215
    int maxId(Edge) const {
deba@414
   216
      return Parent::maxEdgeId();
deba@414
   217
    }
deba@414
   218
deba@414
   219
    Node fromId(int id, Node) const {
deba@414
   220
      return Parent::nodeFromId(id);
deba@414
   221
    }
deba@414
   222
deba@414
   223
    Arc fromId(int id, Arc) const {
deba@414
   224
      return Parent::arcFromId(id);
deba@414
   225
    }
deba@414
   226
deba@414
   227
    Edge fromId(int id, Edge) const {
deba@414
   228
      return Parent::edgeFromId(id);
deba@414
   229
    }
deba@414
   230
deba@414
   231
    Node oppositeNode(const Node &n, const Edge &e) const {
deba@414
   232
      if( n == Parent::u(e))
deba@416
   233
        return Parent::v(e);
deba@414
   234
      else if( n == Parent::v(e))
deba@416
   235
        return Parent::u(e);
deba@414
   236
      else
deba@416
   237
        return INVALID;
deba@414
   238
    }
deba@414
   239
deba@414
   240
    Arc oppositeArc(const Arc &a) const {
deba@414
   241
      return Parent::direct(a, !Parent::direction(a));
deba@414
   242
    }
deba@414
   243
deba@414
   244
    using Parent::direct;
deba@414
   245
    Arc direct(const Edge &e, const Node &s) const {
deba@414
   246
      return Parent::direct(e, Parent::u(e) == s);
deba@414
   247
    }
deba@414
   248
deba@414
   249
deba@416
   250
    class NodeIt : public Node {
deba@414
   251
      const Adaptor* _adaptor;
deba@414
   252
    public:
deba@414
   253
deba@414
   254
      NodeIt() {}
deba@414
   255
deba@414
   256
      NodeIt(Invalid i) : Node(i) { }
deba@414
   257
deba@414
   258
      explicit NodeIt(const Adaptor& adaptor) : _adaptor(&adaptor) {
deba@416
   259
        _adaptor->first(static_cast<Node&>(*this));
deba@414
   260
      }
deba@414
   261
deba@416
   262
      NodeIt(const Adaptor& adaptor, const Node& node)
deba@416
   263
        : Node(node), _adaptor(&adaptor) {}
deba@414
   264
deba@416
   265
      NodeIt& operator++() {
deba@416
   266
        _adaptor->next(*this);
deba@416
   267
        return *this;
deba@414
   268
      }
deba@414
   269
deba@414
   270
    };
deba@414
   271
alpar@1131
   272
    LemonRangeWrapper1<NodeIt, Adaptor> nodes() const {
ggab90@1130
   273
      return LemonRangeWrapper1<NodeIt, Adaptor>(*this);
ggab90@1130
   274
    }
ggab90@1130
   275
deba@414
   276
deba@416
   277
    class ArcIt : public Arc {
deba@414
   278
      const Adaptor* _adaptor;
deba@414
   279
    public:
deba@414
   280
deba@414
   281
      ArcIt() { }
deba@414
   282
deba@414
   283
      ArcIt(Invalid i) : Arc(i) { }
deba@414
   284
deba@414
   285
      explicit ArcIt(const Adaptor& adaptor) : _adaptor(&adaptor) {
deba@416
   286
        _adaptor->first(static_cast<Arc&>(*this));
deba@414
   287
      }
deba@414
   288
deba@416
   289
      ArcIt(const Adaptor& adaptor, const Arc& e) :
deba@416
   290
        Arc(e), _adaptor(&adaptor) { }
deba@414
   291
deba@416
   292
      ArcIt& operator++() {
deba@416
   293
        _adaptor->next(*this);
deba@416
   294
        return *this;
deba@414
   295
      }
deba@414
   296
deba@414
   297
    };
deba@414
   298
alpar@1131
   299
    LemonRangeWrapper1<ArcIt, Adaptor> arcs() const {
ggab90@1130
   300
      return LemonRangeWrapper1<ArcIt, Adaptor>(*this);
ggab90@1130
   301
    }
ggab90@1130
   302
deba@414
   303
deba@416
   304
    class OutArcIt : public Arc {
deba@414
   305
      const Adaptor* _adaptor;
deba@414
   306
    public:
deba@414
   307
deba@414
   308
      OutArcIt() { }
deba@414
   309
deba@414
   310
      OutArcIt(Invalid i) : Arc(i) { }
deba@414
   311
deba@416
   312
      OutArcIt(const Adaptor& adaptor, const Node& node)
deba@416
   313
        : _adaptor(&adaptor) {
deba@416
   314
        _adaptor->firstOut(*this, node);
deba@414
   315
      }
deba@414
   316
deba@416
   317
      OutArcIt(const Adaptor& adaptor, const Arc& arc)
deba@416
   318
        : Arc(arc), _adaptor(&adaptor) {}
deba@414
   319
deba@416
   320
      OutArcIt& operator++() {
deba@416
   321
        _adaptor->nextOut(*this);
deba@416
   322
        return *this;
deba@414
   323
      }
deba@414
   324
deba@414
   325
    };
deba@414
   326
ggab90@1130
   327
    LemonRangeWrapper2<OutArcIt, Adaptor, Node> outArcs(const Node& u) const {
ggab90@1130
   328
      return LemonRangeWrapper2<OutArcIt, Adaptor, Node>(*this, u);
ggab90@1130
   329
    }
ggab90@1130
   330
deba@414
   331
deba@416
   332
    class InArcIt : public Arc {
deba@414
   333
      const Adaptor* _adaptor;
deba@414
   334
    public:
deba@414
   335
deba@414
   336
      InArcIt() { }
deba@414
   337
deba@414
   338
      InArcIt(Invalid i) : Arc(i) { }
deba@414
   339
deba@416
   340
      InArcIt(const Adaptor& adaptor, const Node& node)
deba@416
   341
        : _adaptor(&adaptor) {
deba@416
   342
        _adaptor->firstIn(*this, node);
deba@414
   343
      }
deba@414
   344
deba@416
   345
      InArcIt(const Adaptor& adaptor, const Arc& arc) :
deba@416
   346
        Arc(arc), _adaptor(&adaptor) {}
deba@414
   347
deba@416
   348
      InArcIt& operator++() {
deba@416
   349
        _adaptor->nextIn(*this);
deba@416
   350
        return *this;
deba@414
   351
      }
deba@414
   352
deba@414
   353
    };
deba@414
   354
ggab90@1130
   355
    LemonRangeWrapper2<InArcIt, Adaptor, Node> inArcs(const Node& u) const {
ggab90@1130
   356
      return LemonRangeWrapper2<InArcIt, Adaptor, Node>(*this, u);
ggab90@1130
   357
    }
ggab90@1130
   358
deba@416
   359
    class EdgeIt : public Parent::Edge {
deba@414
   360
      const Adaptor* _adaptor;
deba@414
   361
    public:
deba@414
   362
deba@414
   363
      EdgeIt() { }
deba@414
   364
deba@414
   365
      EdgeIt(Invalid i) : Edge(i) { }
deba@414
   366
deba@414
   367
      explicit EdgeIt(const Adaptor& adaptor) : _adaptor(&adaptor) {
deba@416
   368
        _adaptor->first(static_cast<Edge&>(*this));
deba@414
   369
      }
deba@414
   370
deba@416
   371
      EdgeIt(const Adaptor& adaptor, const Edge& e) :
deba@416
   372
        Edge(e), _adaptor(&adaptor) { }
deba@414
   373
deba@416
   374
      EdgeIt& operator++() {
deba@416
   375
        _adaptor->next(*this);
deba@416
   376
        return *this;
deba@414
   377
      }
deba@414
   378
deba@414
   379
    };
deba@414
   380
alpar@1131
   381
    LemonRangeWrapper1<EdgeIt, Adaptor> edges() const {
ggab90@1130
   382
      return LemonRangeWrapper1<EdgeIt, Adaptor>(*this);
ggab90@1130
   383
    }
ggab90@1130
   384
ggab90@1130
   385
deba@416
   386
    class IncEdgeIt : public Edge {
deba@414
   387
      friend class GraphAdaptorExtender;
deba@414
   388
      const Adaptor* _adaptor;
deba@414
   389
      bool direction;
deba@414
   390
    public:
deba@414
   391
deba@414
   392
      IncEdgeIt() { }
deba@414
   393
deba@414
   394
      IncEdgeIt(Invalid i) : Edge(i), direction(false) { }
deba@414
   395
deba@414
   396
      IncEdgeIt(const Adaptor& adaptor, const Node &n) : _adaptor(&adaptor) {
deba@416
   397
        _adaptor->firstInc(static_cast<Edge&>(*this), direction, n);
deba@414
   398
      }
deba@414
   399
deba@414
   400
      IncEdgeIt(const Adaptor& adaptor, const Edge &e, const Node &n)
deba@416
   401
        : _adaptor(&adaptor), Edge(e) {
deba@416
   402
        direction = (_adaptor->u(e) == n);
deba@414
   403
      }
deba@414
   404
deba@414
   405
      IncEdgeIt& operator++() {
deba@416
   406
        _adaptor->nextInc(*this, direction);
deba@416
   407
        return *this;
deba@414
   408
      }
deba@414
   409
    };
deba@414
   410
ggab90@1130
   411
    LemonRangeWrapper2<IncEdgeIt, Adaptor, Node> incEdges(const Node& u) const {
ggab90@1130
   412
      return LemonRangeWrapper2<IncEdgeIt, Adaptor, Node>(*this, u);
ggab90@1130
   413
    }
ggab90@1130
   414
ggab90@1130
   415
deba@414
   416
    Node baseNode(const OutArcIt &a) const {
deba@414
   417
      return Parent::source(a);
deba@414
   418
    }
deba@414
   419
    Node runningNode(const OutArcIt &a) const {
deba@414
   420
      return Parent::target(a);
deba@414
   421
    }
deba@414
   422
deba@414
   423
    Node baseNode(const InArcIt &a) const {
deba@414
   424
      return Parent::target(a);
deba@414
   425
    }
deba@414
   426
    Node runningNode(const InArcIt &a) const {
deba@414
   427
      return Parent::source(a);
deba@414
   428
    }
deba@414
   429
deba@414
   430
    Node baseNode(const IncEdgeIt &e) const {
deba@414
   431
      return e.direction ? Parent::u(e) : Parent::v(e);
deba@414
   432
    }
deba@414
   433
    Node runningNode(const IncEdgeIt &e) const {
deba@414
   434
      return e.direction ? Parent::v(e) : Parent::u(e);
deba@414
   435
    }
deba@414
   436
deba@414
   437
  };
deba@414
   438
deba@414
   439
}
deba@414
   440
deba@414
   441
deba@414
   442
#endif