lemon/bits/base_extender.h
author Peter Kovacs <kpeter@inf.elte.hu>
Fri, 03 Apr 2009 18:59:15 +0200
changeset 608 6ac5d9ae1d3d
parent 361 f58410582b9b
child 617 4137ef9aacc6
permissions -rw-r--r--
Support real types + numerical stability fix in NS (#254)

- Real types are supported by appropriate inicialization.
- A feature of the XTI spanning tree structure is removed to ensure
numerical stability (could cause problems using integer types).
The node potentials are updated always on the lower subtree,
in order to prevent overflow problems.
The former method isn't notably faster during to our tests.
alpar@209
     1
/* -*- mode: C++; indent-tabs-mode: nil; -*-
deba@57
     2
 *
alpar@209
     3
 * This file is a part of LEMON, a generic C++ optimization library.
deba@57
     4
 *
alpar@440
     5
 * Copyright (C) 2003-2009
deba@57
     6
 * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
deba@57
     7
 * (Egervary Research Group on Combinatorial Optimization, EGRES).
deba@57
     8
 *
deba@57
     9
 * Permission to use, modify and distribute this software is granted
deba@57
    10
 * provided that this copyright notice appears in all copies. For
deba@57
    11
 * precise terms see the accompanying LICENSE file.
deba@57
    12
 *
deba@57
    13
 * This software is provided "AS IS" with no warranty of any kind,
deba@57
    14
 * express or implied, and with no claim as to its suitability for any
deba@57
    15
 * purpose.
deba@57
    16
 *
deba@57
    17
 */
deba@57
    18
deba@57
    19
#ifndef LEMON_BITS_BASE_EXTENDER_H
deba@57
    20
#define LEMON_BITS_BASE_EXTENDER_H
deba@57
    21
deba@220
    22
#include <lemon/core.h>
deba@57
    23
#include <lemon/error.h>
deba@57
    24
deba@57
    25
#include <lemon/bits/map_extender.h>
deba@57
    26
#include <lemon/bits/default_map.h>
deba@57
    27
deba@57
    28
#include <lemon/concept_check.h>
deba@57
    29
#include <lemon/concepts/maps.h>
deba@57
    30
kpeter@314
    31
//\ingroup digraphbits
kpeter@314
    32
//\file
kpeter@361
    33
//\brief Extenders for the graph types
deba@57
    34
namespace lemon {
deba@57
    35
kpeter@314
    36
  // \ingroup digraphbits
kpeter@314
    37
  //
kpeter@314
    38
  // \brief BaseDigraph to BaseGraph extender
deba@57
    39
  template <typename Base>
deba@57
    40
  class UndirDigraphExtender : public Base {
deba@57
    41
deba@57
    42
  public:
deba@57
    43
deba@57
    44
    typedef Base Parent;
deba@57
    45
    typedef typename Parent::Arc Edge;
deba@57
    46
    typedef typename Parent::Node Node;
deba@57
    47
deba@57
    48
    typedef True UndirectedTag;
deba@57
    49
deba@57
    50
    class Arc : public Edge {
deba@57
    51
      friend class UndirDigraphExtender;
deba@57
    52
deba@57
    53
    protected:
deba@57
    54
      bool forward;
deba@57
    55
deba@57
    56
      Arc(const Edge &ue, bool _forward) :
deba@57
    57
        Edge(ue), forward(_forward) {}
deba@57
    58
deba@57
    59
    public:
deba@57
    60
      Arc() {}
deba@57
    61
kpeter@256
    62
      // Invalid arc constructor
deba@57
    63
      Arc(Invalid i) : Edge(i), forward(true) {}
deba@57
    64
deba@57
    65
      bool operator==(const Arc &that) const {
alpar@209
    66
        return forward==that.forward && Edge(*this)==Edge(that);
deba@57
    67
      }
deba@57
    68
      bool operator!=(const Arc &that) const {
alpar@209
    69
        return forward!=that.forward || Edge(*this)!=Edge(that);
deba@57
    70
      }
deba@57
    71
      bool operator<(const Arc &that) const {
alpar@209
    72
        return forward<that.forward ||
alpar@209
    73
          (!(that.forward<forward) && Edge(*this)<Edge(that));
deba@57
    74
      }
deba@57
    75
    };
deba@57
    76
kpeter@314
    77
    // First node of the edge
kpeter@256
    78
    Node u(const Edge &e) const {
kpeter@256
    79
      return Parent::source(e);
kpeter@256
    80
    }
deba@57
    81
kpeter@314
    82
    // Source of the given arc
deba@57
    83
    Node source(const Arc &e) const {
deba@57
    84
      return e.forward ? Parent::source(e) : Parent::target(e);
deba@57
    85
    }
deba@57
    86
kpeter@314
    87
    // Second node of the edge
kpeter@256
    88
    Node v(const Edge &e) const {
kpeter@256
    89
      return Parent::target(e);
kpeter@256
    90
    }
deba@57
    91
kpeter@314
    92
    // Target of the given arc
deba@57
    93
    Node target(const Arc &e) const {
deba@57
    94
      return e.forward ? Parent::target(e) : Parent::source(e);
deba@57
    95
    }
deba@57
    96
kpeter@314
    97
    // \brief Directed arc from an edge.
kpeter@314
    98
    //
kpeter@314
    99
    // Returns a directed arc corresponding to the specified edge.
kpeter@314
   100
    // If the given bool is true, the first node of the given edge and
kpeter@314
   101
    // the source node of the returned arc are the same.
kpeter@256
   102
    static Arc direct(const Edge &e, bool d) {
kpeter@256
   103
      return Arc(e, d);
deba@57
   104
    }
deba@57
   105
kpeter@314
   106
    // Returns whether the given directed arc has the same orientation
kpeter@314
   107
    // as the corresponding edge.
kpeter@256
   108
    static bool direction(const Arc &a) { return a.forward; }
deba@57
   109
deba@57
   110
    using Parent::first;
deba@57
   111
    using Parent::next;
deba@57
   112
deba@57
   113
    void first(Arc &e) const {
deba@57
   114
      Parent::first(e);
deba@57
   115
      e.forward=true;
deba@57
   116
    }
deba@57
   117
deba@57
   118
    void next(Arc &e) const {
deba@57
   119
      if( e.forward ) {
alpar@209
   120
        e.forward = false;
deba@57
   121
      }
deba@57
   122
      else {
alpar@209
   123
        Parent::next(e);
alpar@209
   124
        e.forward = true;
deba@57
   125
      }
deba@57
   126
    }
deba@57
   127
deba@57
   128
    void firstOut(Arc &e, const Node &n) const {
deba@57
   129
      Parent::firstIn(e,n);
deba@57
   130
      if( Edge(e) != INVALID ) {
alpar@209
   131
        e.forward = false;
deba@57
   132
      }
deba@57
   133
      else {
alpar@209
   134
        Parent::firstOut(e,n);
alpar@209
   135
        e.forward = true;
deba@57
   136
      }
deba@57
   137
    }
deba@57
   138
    void nextOut(Arc &e) const {
deba@57
   139
      if( ! e.forward ) {
alpar@209
   140
        Node n = Parent::target(e);
alpar@209
   141
        Parent::nextIn(e);
alpar@209
   142
        if( Edge(e) == INVALID ) {
alpar@209
   143
          Parent::firstOut(e, n);
alpar@209
   144
          e.forward = true;
alpar@209
   145
        }
deba@57
   146
      }
deba@57
   147
      else {
alpar@209
   148
        Parent::nextOut(e);
deba@57
   149
      }
deba@57
   150
    }
deba@57
   151
deba@57
   152
    void firstIn(Arc &e, const Node &n) const {
deba@57
   153
      Parent::firstOut(e,n);
deba@57
   154
      if( Edge(e) != INVALID ) {
alpar@209
   155
        e.forward = false;
deba@57
   156
      }
deba@57
   157
      else {
alpar@209
   158
        Parent::firstIn(e,n);
alpar@209
   159
        e.forward = true;
deba@57
   160
      }
deba@57
   161
    }
deba@57
   162
    void nextIn(Arc &e) const {
deba@57
   163
      if( ! e.forward ) {
alpar@209
   164
        Node n = Parent::source(e);
alpar@209
   165
        Parent::nextOut(e);
alpar@209
   166
        if( Edge(e) == INVALID ) {
alpar@209
   167
          Parent::firstIn(e, n);
alpar@209
   168
          e.forward = true;
alpar@209
   169
        }
deba@57
   170
      }
deba@57
   171
      else {
alpar@209
   172
        Parent::nextIn(e);
deba@57
   173
      }
deba@57
   174
    }
deba@57
   175
deba@57
   176
    void firstInc(Edge &e, bool &d, const Node &n) const {
deba@57
   177
      d = true;
deba@57
   178
      Parent::firstOut(e, n);
deba@57
   179
      if (e != INVALID) return;
deba@57
   180
      d = false;
deba@57
   181
      Parent::firstIn(e, n);
deba@57
   182
    }
deba@57
   183
deba@57
   184
    void nextInc(Edge &e, bool &d) const {
deba@57
   185
      if (d) {
alpar@209
   186
        Node s = Parent::source(e);
alpar@209
   187
        Parent::nextOut(e);
alpar@209
   188
        if (e != INVALID) return;
alpar@209
   189
        d = false;
alpar@209
   190
        Parent::firstIn(e, s);
deba@57
   191
      } else {
alpar@209
   192
        Parent::nextIn(e);
deba@57
   193
      }
deba@57
   194
    }
deba@57
   195
deba@57
   196
    Node nodeFromId(int ix) const {
deba@57
   197
      return Parent::nodeFromId(ix);
deba@57
   198
    }
deba@57
   199
deba@57
   200
    Arc arcFromId(int ix) const {
deba@57
   201
      return direct(Parent::arcFromId(ix >> 1), bool(ix & 1));
deba@57
   202
    }
deba@57
   203
deba@57
   204
    Edge edgeFromId(int ix) const {
deba@57
   205
      return Parent::arcFromId(ix);
deba@57
   206
    }
deba@57
   207
deba@57
   208
    int id(const Node &n) const {
deba@57
   209
      return Parent::id(n);
deba@57
   210
    }
deba@57
   211
deba@57
   212
    int id(const Edge &e) const {
deba@57
   213
      return Parent::id(e);
deba@57
   214
    }
deba@57
   215
deba@57
   216
    int id(const Arc &e) const {
deba@57
   217
      return 2 * Parent::id(e) + int(e.forward);
deba@57
   218
    }
deba@57
   219
deba@57
   220
    int maxNodeId() const {
deba@57
   221
      return Parent::maxNodeId();
deba@57
   222
    }
deba@57
   223
deba@57
   224
    int maxArcId() const {
deba@57
   225
      return 2 * Parent::maxArcId() + 1;
deba@57
   226
    }
deba@57
   227
deba@57
   228
    int maxEdgeId() const {
deba@57
   229
      return Parent::maxArcId();
deba@57
   230
    }
deba@57
   231
deba@57
   232
    int arcNum() const {
deba@57
   233
      return 2 * Parent::arcNum();
deba@57
   234
    }
deba@57
   235
deba@57
   236
    int edgeNum() const {
deba@57
   237
      return Parent::arcNum();
deba@57
   238
    }
deba@57
   239
deba@57
   240
    Arc findArc(Node s, Node t, Arc p = INVALID) const {
deba@57
   241
      if (p == INVALID) {
alpar@209
   242
        Edge arc = Parent::findArc(s, t);
alpar@209
   243
        if (arc != INVALID) return direct(arc, true);
alpar@209
   244
        arc = Parent::findArc(t, s);
alpar@209
   245
        if (arc != INVALID) return direct(arc, false);
deba@57
   246
      } else if (direction(p)) {
alpar@209
   247
        Edge arc = Parent::findArc(s, t, p);
alpar@209
   248
        if (arc != INVALID) return direct(arc, true);
alpar@209
   249
        arc = Parent::findArc(t, s);
alpar@209
   250
        if (arc != INVALID) return direct(arc, false);
deba@57
   251
      } else {
alpar@209
   252
        Edge arc = Parent::findArc(t, s, p);
alpar@209
   253
        if (arc != INVALID) return direct(arc, false);
deba@57
   254
      }
deba@57
   255
      return INVALID;
deba@57
   256
    }
deba@57
   257
deba@57
   258
    Edge findEdge(Node s, Node t, Edge p = INVALID) const {
deba@57
   259
      if (s != t) {
deba@57
   260
        if (p == INVALID) {
deba@57
   261
          Edge arc = Parent::findArc(s, t);
deba@57
   262
          if (arc != INVALID) return arc;
deba@57
   263
          arc = Parent::findArc(t, s);
deba@57
   264
          if (arc != INVALID) return arc;
deba@57
   265
        } else if (Parent::s(p) == s) {
deba@57
   266
          Edge arc = Parent::findArc(s, t, p);
deba@57
   267
          if (arc != INVALID) return arc;
deba@57
   268
          arc = Parent::findArc(t, s);
alpar@209
   269
          if (arc != INVALID) return arc;
deba@57
   270
        } else {
deba@57
   271
          Edge arc = Parent::findArc(t, s, p);
alpar@209
   272
          if (arc != INVALID) return arc;
deba@57
   273
        }
deba@57
   274
      } else {
deba@57
   275
        return Parent::findArc(s, t, p);
deba@57
   276
      }
deba@57
   277
      return INVALID;
deba@57
   278
    }
deba@57
   279
  };
deba@57
   280
deba@57
   281
  template <typename Base>
deba@57
   282
  class BidirBpGraphExtender : public Base {
deba@57
   283
  public:
deba@57
   284
    typedef Base Parent;
deba@57
   285
    typedef BidirBpGraphExtender Digraph;
deba@57
   286
deba@57
   287
    typedef typename Parent::Node Node;
deba@57
   288
    typedef typename Parent::Edge Edge;
deba@57
   289
deba@57
   290
deba@57
   291
    using Parent::first;
deba@57
   292
    using Parent::next;
deba@57
   293
deba@57
   294
    using Parent::id;
deba@57
   295
deba@57
   296
    class Red : public Node {
deba@57
   297
      friend class BidirBpGraphExtender;
deba@57
   298
    public:
deba@57
   299
      Red() {}
deba@57
   300
      Red(const Node& node) : Node(node) {
kpeter@289
   301
        LEMON_DEBUG(Parent::red(node) || node == INVALID,
kpeter@289
   302
                    typename Parent::NodeSetError());
deba@57
   303
      }
deba@57
   304
      Red& operator=(const Node& node) {
kpeter@289
   305
        LEMON_DEBUG(Parent::red(node) || node == INVALID,
kpeter@289
   306
                    typename Parent::NodeSetError());
deba@57
   307
        Node::operator=(node);
deba@57
   308
        return *this;
deba@57
   309
      }
deba@57
   310
      Red(Invalid) : Node(INVALID) {}
deba@57
   311
      Red& operator=(Invalid) {
deba@57
   312
        Node::operator=(INVALID);
deba@57
   313
        return *this;
deba@57
   314
      }
deba@57
   315
    };
deba@57
   316
deba@57
   317
    void first(Red& node) const {
deba@57
   318
      Parent::firstRed(static_cast<Node&>(node));
deba@57
   319
    }
deba@57
   320
    void next(Red& node) const {
deba@57
   321
      Parent::nextRed(static_cast<Node&>(node));
deba@57
   322
    }
deba@57
   323
deba@57
   324
    int id(const Red& node) const {
deba@57
   325
      return Parent::redId(node);
deba@57
   326
    }
deba@57
   327
deba@57
   328
    class Blue : public Node {
deba@57
   329
      friend class BidirBpGraphExtender;
deba@57
   330
    public:
deba@57
   331
      Blue() {}
deba@57
   332
      Blue(const Node& node) : Node(node) {
kpeter@289
   333
        LEMON_DEBUG(Parent::blue(node) || node == INVALID,
kpeter@289
   334
                    typename Parent::NodeSetError());
deba@57
   335
      }
deba@57
   336
      Blue& operator=(const Node& node) {
kpeter@289
   337
        LEMON_DEBUG(Parent::blue(node) || node == INVALID,
kpeter@289
   338
                    typename Parent::NodeSetError());
deba@57
   339
        Node::operator=(node);
deba@57
   340
        return *this;
deba@57
   341
      }
deba@57
   342
      Blue(Invalid) : Node(INVALID) {}
deba@57
   343
      Blue& operator=(Invalid) {
deba@57
   344
        Node::operator=(INVALID);
deba@57
   345
        return *this;
deba@57
   346
      }
deba@57
   347
    };
deba@57
   348
deba@57
   349
    void first(Blue& node) const {
deba@57
   350
      Parent::firstBlue(static_cast<Node&>(node));
deba@57
   351
    }
deba@57
   352
    void next(Blue& node) const {
deba@57
   353
      Parent::nextBlue(static_cast<Node&>(node));
deba@57
   354
    }
alpar@209
   355
deba@57
   356
    int id(const Blue& node) const {
deba@57
   357
      return Parent::redId(node);
deba@57
   358
    }
deba@57
   359
deba@57
   360
    Node source(const Edge& arc) const {
deba@57
   361
      return red(arc);
deba@57
   362
    }
deba@57
   363
    Node target(const Edge& arc) const {
deba@57
   364
      return blue(arc);
deba@57
   365
    }
deba@57
   366
deba@57
   367
    void firstInc(Edge& arc, bool& dir, const Node& node) const {
deba@57
   368
      if (Parent::red(node)) {
alpar@209
   369
        Parent::firstFromRed(arc, node);
alpar@209
   370
        dir = true;
deba@57
   371
      } else {
alpar@209
   372
        Parent::firstFromBlue(arc, node);
alpar@209
   373
        dir = static_cast<Edge&>(arc) == INVALID;
deba@57
   374
      }
deba@57
   375
    }
deba@57
   376
    void nextInc(Edge& arc, bool& dir) const {
deba@57
   377
      if (dir) {
alpar@209
   378
        Parent::nextFromRed(arc);
deba@57
   379
      } else {
alpar@209
   380
        Parent::nextFromBlue(arc);
alpar@209
   381
        if (arc == INVALID) dir = true;
deba@57
   382
      }
deba@57
   383
    }
deba@57
   384
deba@57
   385
    class Arc : public Edge {
deba@57
   386
      friend class BidirBpGraphExtender;
deba@57
   387
    protected:
deba@57
   388
      bool forward;
deba@57
   389
deba@57
   390
      Arc(const Edge& arc, bool _forward)
alpar@209
   391
        : Edge(arc), forward(_forward) {}
deba@57
   392
deba@57
   393
    public:
deba@57
   394
      Arc() {}
deba@57
   395
      Arc (Invalid) : Edge(INVALID), forward(true) {}
deba@57
   396
      bool operator==(const Arc& i) const {
alpar@209
   397
        return Edge::operator==(i) && forward == i.forward;
deba@57
   398
      }
deba@57
   399
      bool operator!=(const Arc& i) const {
alpar@209
   400
        return Edge::operator!=(i) || forward != i.forward;
deba@57
   401
      }
deba@57
   402
      bool operator<(const Arc& i) const {
alpar@209
   403
        return Edge::operator<(i) ||
alpar@209
   404
          (!(i.forward<forward) && Edge(*this)<Edge(i));
deba@57
   405
      }
deba@57
   406
    };
deba@57
   407
deba@57
   408
    void first(Arc& arc) const {
deba@57
   409
      Parent::first(static_cast<Edge&>(arc));
deba@57
   410
      arc.forward = true;
deba@57
   411
    }
deba@57
   412
deba@57
   413
    void next(Arc& arc) const {
deba@57
   414
      if (!arc.forward) {
alpar@209
   415
        Parent::next(static_cast<Edge&>(arc));
deba@57
   416
      }
deba@57
   417
      arc.forward = !arc.forward;
deba@57
   418
    }
deba@57
   419
deba@57
   420
    void firstOut(Arc& arc, const Node& node) const {
deba@57
   421
      if (Parent::red(node)) {
alpar@209
   422
        Parent::firstFromRed(arc, node);
alpar@209
   423
        arc.forward = true;
deba@57
   424
      } else {
alpar@209
   425
        Parent::firstFromBlue(arc, node);
alpar@209
   426
        arc.forward = static_cast<Edge&>(arc) == INVALID;
deba@57
   427
      }
deba@57
   428
    }
deba@57
   429
    void nextOut(Arc& arc) const {
deba@57
   430
      if (arc.forward) {
alpar@209
   431
        Parent::nextFromRed(arc);
deba@57
   432
      } else {
alpar@209
   433
        Parent::nextFromBlue(arc);
deba@57
   434
        arc.forward = static_cast<Edge&>(arc) == INVALID;
deba@57
   435
      }
deba@57
   436
    }
deba@57
   437
deba@57
   438
    void firstIn(Arc& arc, const Node& node) const {
deba@57
   439
      if (Parent::blue(node)) {
alpar@209
   440
        Parent::firstFromBlue(arc, node);
alpar@209
   441
        arc.forward = true;
deba@57
   442
      } else {
alpar@209
   443
        Parent::firstFromRed(arc, node);
alpar@209
   444
        arc.forward = static_cast<Edge&>(arc) == INVALID;
deba@57
   445
      }
deba@57
   446
    }
deba@57
   447
    void nextIn(Arc& arc) const {
deba@57
   448
      if (arc.forward) {
alpar@209
   449
        Parent::nextFromBlue(arc);
deba@57
   450
      } else {
alpar@209
   451
        Parent::nextFromRed(arc);
alpar@209
   452
        arc.forward = static_cast<Edge&>(arc) == INVALID;
deba@57
   453
      }
deba@57
   454
    }
deba@57
   455
deba@57
   456
    Node source(const Arc& arc) const {
deba@57
   457
      return arc.forward ? Parent::red(arc) : Parent::blue(arc);
deba@57
   458
    }
deba@57
   459
    Node target(const Arc& arc) const {
deba@57
   460
      return arc.forward ? Parent::blue(arc) : Parent::red(arc);
deba@57
   461
    }
deba@57
   462
deba@57
   463
    int id(const Arc& arc) const {
alpar@209
   464
      return (Parent::id(static_cast<const Edge&>(arc)) << 1) +
deba@57
   465
        (arc.forward ? 0 : 1);
deba@57
   466
    }
deba@57
   467
    Arc arcFromId(int ix) const {
deba@57
   468
      return Arc(Parent::fromEdgeId(ix >> 1), (ix & 1) == 0);
deba@57
   469
    }
deba@57
   470
    int maxArcId() const {
deba@57
   471
      return (Parent::maxEdgeId() << 1) + 1;
deba@57
   472
    }
deba@57
   473
deba@57
   474
    bool direction(const Arc& arc) const {
deba@57
   475
      return arc.forward;
deba@57
   476
    }
deba@57
   477
deba@57
   478
    Arc direct(const Edge& arc, bool dir) const {
deba@57
   479
      return Arc(arc, dir);
deba@57
   480
    }
deba@57
   481
deba@57
   482
    int arcNum() const {
deba@57
   483
      return 2 * Parent::edgeNum();
deba@57
   484
    }
deba@57
   485
deba@57
   486
    int edgeNum() const {
deba@57
   487
      return Parent::edgeNum();
deba@57
   488
    }
deba@57
   489
deba@57
   490
deba@57
   491
  };
deba@57
   492
}
deba@57
   493
deba@57
   494
#endif