lemon/bits/base_extender.h
author klao
Thu, 13 Apr 2006 17:57:03 +0000
changeset 2046 66d160810c0a
parent 1999 2ff283124dfc
child 2076 10681ee9d8ae
permissions -rw-r--r--
more explicit :)
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
 *
deba@1999
     5
 * Copyright (C) 2003-2006
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>
deba@1999
    29
#include <lemon/concept/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@1999
    38
  /// \brief BaseExtender for the UGraphs
deba@1999
    39
  template <typename Base>
deba@1999
    40
  class UGraphBaseExtender : 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@1999
    51
      friend class UGraphBaseExtender;
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@1999
   196
    Node nodeFromId(int id) const {
deba@1999
   197
      return Parent::nodeFromId(id);
deba@1999
   198
    }
deba@1999
   199
deba@1999
   200
    Edge edgeFromId(int id) const {
deba@1999
   201
      return direct(Parent::edgeFromId(id >> 1), bool(id & 1));
deba@1999
   202
    }
deba@1999
   203
deba@1999
   204
    UEdge uEdgeFromId(int id) const {
deba@1999
   205
      return Parent::edgeFromId(id >> 1);
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@1999
   241
    Edge findEdge(Node source, Node target, Edge prev) const {
deba@1999
   242
      if (prev == INVALID) {
deba@1999
   243
	UEdge edge = Parent::findEdge(source, target);
deba@1999
   244
	if (edge != INVALID) return direct(edge, true);
deba@1999
   245
	edge = Parent::findEdge(target, source);
deba@1999
   246
	if (edge != INVALID) return direct(edge, false);
deba@1999
   247
      } else if (direction(prev)) {
deba@1999
   248
	UEdge edge = Parent::findEdge(source, target, prev);
deba@1999
   249
	if (edge != INVALID) return direct(edge, true);
deba@1999
   250
	edge = Parent::findEdge(target, source);
deba@1999
   251
	if (edge != INVALID) return direct(edge, false);	
deba@1999
   252
      } else {
deba@1999
   253
	UEdge edge = Parent::findEdge(target, source, prev);
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@1999
   259
    UEdge findUEdge(Node source, Node target, UEdge prev) const {
deba@1999
   260
      if (prev == INVALID) {
deba@1999
   261
	UEdge edge = Parent::findEdge(source, target);
deba@1999
   262
	if (edge != INVALID) return edge;
deba@1999
   263
	edge = Parent::findEdge(target, source);
deba@1999
   264
	if (edge != INVALID) return edge;
deba@1999
   265
      } else if (Parent::source(prev) == source) {
deba@1999
   266
	UEdge edge = Parent::findEdge(source, target, prev);
deba@1999
   267
	if (edge != INVALID) return edge;
deba@1999
   268
	edge = Parent::findEdge(target, source);
deba@1999
   269
	if (edge != INVALID) return edge;	
deba@1999
   270
      } else {
deba@1999
   271
	UEdge edge = Parent::findEdge(target, source, prev);
deba@1999
   272
	if (edge != INVALID) return edge;	      
deba@1999
   273
      }
deba@1999
   274
      return INVALID;
deba@1999
   275
    }
deba@1999
   276
  };
deba@1999
   277
deba@1999
   278
deba@1999
   279
  /// \ingroup graphbits
deba@1999
   280
  ///
deba@1999
   281
  /// \brief BaseExtender for the BpUGraphs
deba@1999
   282
  template <typename Base>
deba@1999
   283
  class BpUGraphBaseExtender : public Base {
deba@1999
   284
  public:
deba@1999
   285
    typedef Base Parent;
deba@1999
   286
    typedef BpUGraphBaseExtender Graph;
deba@1999
   287
deba@1999
   288
    typedef typename Parent::Node Node;
deba@1999
   289
    typedef typename Parent::Edge UEdge;
deba@1999
   290
deba@1999
   291
deba@1999
   292
    using Parent::first;
deba@1999
   293
    using Parent::next;
deba@1999
   294
deba@1999
   295
    using Parent::id;
deba@1999
   296
deba@1999
   297
    class ANode : public Node {
deba@1999
   298
      friend class BpUGraphBaseExtender;
deba@1999
   299
    public:
deba@1999
   300
      ANode() {}
deba@1999
   301
      ANode(const Node& node) : Node(node) {
deba@1999
   302
	LEMON_ASSERT(Parent::aNode(node) || node == INVALID, 
deba@1999
   303
		     typename Parent::NodeSetError());
deba@1999
   304
      }
deba@1999
   305
      ANode(Invalid) : Node(INVALID) {}
deba@1999
   306
    };
deba@1999
   307
deba@1999
   308
    void first(ANode& node) const {
deba@1999
   309
      Parent::firstANode(static_cast<Node&>(node));
deba@1999
   310
    }
deba@1999
   311
    void next(ANode& node) const {
deba@1999
   312
      Parent::nextANode(static_cast<Node&>(node));
deba@1999
   313
    }
deba@1999
   314
deba@1999
   315
    int id(const ANode& node) const {
deba@1999
   316
      return Parent::aNodeId(node);
deba@1999
   317
    }
deba@1999
   318
deba@1999
   319
    class BNode : public Node {
deba@1999
   320
      friend class BpUGraphBaseExtender;
deba@1999
   321
    public:
deba@1999
   322
      BNode() {}
deba@1999
   323
      BNode(const Node& node) : Node(node) {
deba@1999
   324
	LEMON_ASSERT(Parent::bNode(node) || node == INVALID,
deba@1999
   325
		     typename Parent::NodeSetError());
deba@1999
   326
      }
deba@1999
   327
      BNode(Invalid) : Node(INVALID) {}
deba@1999
   328
    };
deba@1999
   329
deba@1999
   330
    void first(BNode& node) const {
deba@1999
   331
      Parent::firstBNode(static_cast<Node&>(node));
deba@1999
   332
    }
deba@1999
   333
    void next(BNode& node) const {
deba@1999
   334
      Parent::nextBNode(static_cast<Node&>(node));
deba@1999
   335
    }
deba@1999
   336
  
deba@1999
   337
    int id(const BNode& node) const {
deba@1999
   338
      return Parent::aNodeId(node);
deba@1999
   339
    }
deba@1999
   340
deba@1999
   341
    Node source(const UEdge& edge) const {
deba@1999
   342
      return aNode(edge);
deba@1999
   343
    }
deba@1999
   344
    Node target(const UEdge& edge) const {
deba@1999
   345
      return bNode(edge);
deba@1999
   346
    }
deba@1999
   347
deba@1999
   348
    void firstInc(UEdge& edge, bool& direction, const Node& node) const {
deba@1999
   349
      if (Parent::aNode(node)) {
deba@1999
   350
	Parent::firstOut(edge, node);
deba@1999
   351
	direction = true;
deba@1999
   352
      } else {
deba@1999
   353
	Parent::firstIn(edge, node);
deba@1999
   354
	direction = static_cast<UEdge&>(edge) == INVALID;
deba@1999
   355
      }
deba@1999
   356
    }
deba@1999
   357
    void nextInc(UEdge& edge, bool& direction) const {
deba@1999
   358
      if (direction) {
deba@1999
   359
	Parent::nextOut(edge);
deba@1999
   360
      } else {
deba@1999
   361
	Parent::nextIn(edge);
deba@1999
   362
	if (edge == INVALID) direction = true;
deba@1999
   363
      }
deba@1999
   364
    }
deba@1999
   365
deba@1999
   366
    int maxUEdgeId() const {
deba@1999
   367
      return Parent::maxEdgeId();
deba@1999
   368
    }
deba@1999
   369
deba@1999
   370
    UEdge uEdgeFromId(int id) const {
deba@1999
   371
      return Parent::edgeFromId(id);
deba@1999
   372
    }
deba@1999
   373
deba@1999
   374
    class Edge : public UEdge {
deba@1999
   375
      friend class BpUGraphBaseExtender;
deba@1999
   376
    protected:
deba@1999
   377
      bool forward;
deba@1999
   378
deba@1999
   379
      Edge(const UEdge& edge, bool _forward)
deba@1999
   380
	: UEdge(edge), forward(_forward) {}
deba@1999
   381
deba@1999
   382
    public:
deba@1999
   383
      Edge() {}
deba@1999
   384
      Edge (Invalid) : UEdge(INVALID), forward(true) {}
deba@1999
   385
      bool operator==(const Edge& i) const {
deba@1999
   386
	return UEdge::operator==(i) && forward == i.forward;
deba@1999
   387
      }
deba@1999
   388
      bool operator!=(const Edge& i) const {
deba@1999
   389
	return UEdge::operator!=(i) || forward != i.forward;
deba@1999
   390
      }
deba@1999
   391
      bool operator<(const Edge& i) const {
deba@1999
   392
	return UEdge::operator<(i) || 
deba@1999
   393
	  (!(i.forward<forward) && UEdge(*this)<UEdge(i));
deba@1999
   394
      }
deba@1999
   395
    };
deba@1999
   396
deba@1999
   397
    void first(Edge& edge) const {
deba@1999
   398
      Parent::first(static_cast<UEdge&>(edge));
deba@1999
   399
      edge.forward = true;
deba@1999
   400
    }
deba@1999
   401
deba@1999
   402
    void next(Edge& edge) const {
deba@1999
   403
      if (!edge.forward) {
deba@1999
   404
	Parent::next(static_cast<UEdge&>(edge));
deba@1999
   405
      }
deba@1999
   406
      edge.forward = !edge.forward;
deba@1999
   407
    }
deba@1999
   408
deba@1999
   409
    void firstOut(Edge& edge, const Node& node) const {
deba@1999
   410
      if (Parent::aNode(node)) {
deba@1999
   411
	Parent::firstOut(edge, node);
deba@1999
   412
	edge.forward = true;
deba@1999
   413
      } else {
deba@1999
   414
	Parent::firstIn(edge, node);
deba@1999
   415
	edge.forward = static_cast<UEdge&>(edge) == INVALID;
deba@1999
   416
      }
deba@1999
   417
    }
deba@1999
   418
    void nextOut(Edge& edge) const {
deba@1999
   419
      if (edge.forward) {
deba@1999
   420
	Parent::nextOut(edge);
deba@1999
   421
      } else {
deba@1999
   422
	Parent::nextIn(edge);
deba@1999
   423
        edge.forward = static_cast<UEdge&>(edge) == INVALID;
deba@1999
   424
      }
deba@1999
   425
    }
deba@1999
   426
deba@1999
   427
    void firstIn(Edge& edge, const Node& node) const {
deba@1999
   428
      if (Parent::bNode(node)) {
deba@1999
   429
	Parent::firstIn(edge, node);
deba@1999
   430
	edge.forward = true;	
deba@1999
   431
      } else {
deba@1999
   432
	Parent::firstOut(edge, node);
deba@1999
   433
	edge.forward = static_cast<UEdge&>(edge) == INVALID;
deba@1999
   434
      }
deba@1999
   435
    }
deba@1999
   436
    void nextIn(Edge& edge) const {
deba@1999
   437
      if (edge.forward) {
deba@1999
   438
	Parent::nextIn(edge);
deba@1999
   439
      } else {
deba@1999
   440
	Parent::nextOut(edge);
deba@1999
   441
	edge.forward = static_cast<UEdge&>(edge) == INVALID;
deba@1999
   442
      }
deba@1999
   443
    }
deba@1999
   444
deba@1999
   445
    Node source(const Edge& edge) const {
deba@1999
   446
      return edge.forward ? Parent::aNode(edge) : Parent::bNode(edge);
deba@1999
   447
    }
deba@1999
   448
    Node target(const Edge& edge) const {
deba@1999
   449
      return edge.forward ? Parent::bNode(edge) : Parent::aNode(edge);
deba@1999
   450
    }
deba@1999
   451
deba@1999
   452
    int id(const Edge& edge) const {
deba@1999
   453
      return (Parent::id(edge) << 1) + (edge.forward ? 0 : 1);
deba@1999
   454
    }
deba@1999
   455
    Edge edgeFromId(int id) const {
deba@1999
   456
      return Edge(Parent::fromId(id >> 1, UEdge()), (id & 1) == 0);
deba@1999
   457
    }
deba@1999
   458
    int maxEdgeId() const {
deba@1999
   459
      return (Parent::maxId(UEdge()) << 1) + 1;
deba@1999
   460
    }
deba@1999
   461
deba@1999
   462
    bool direction(const Edge& edge) const {
deba@1999
   463
      return edge.forward;
deba@1999
   464
    }
deba@1999
   465
deba@1999
   466
    Edge direct(const UEdge& edge, bool direction) const {
deba@1999
   467
      return Edge(edge, direction);
deba@1999
   468
    }
deba@2031
   469
deba@2031
   470
    int edgeNum() const {
deba@2031
   471
      return 2 * Parent::edgeNum();
deba@2031
   472
    }
deba@2031
   473
deba@2031
   474
    int uEdgeNum() const {
deba@2031
   475
      return Parent::edgeNum();
deba@2031
   476
    }
deba@2031
   477
deba@1999
   478
  };
deba@1999
   479
deba@1999
   480
}
deba@1999
   481
deba@1999
   482
#endif