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