lemon/bits/base_extender.h
author deba
Tue, 17 Oct 2006 10:50:57 +0000
changeset 2247 269a0dcee70b
parent 2222 a24939ee343c
child 2260 4274224f8a7d
permissions -rw-r--r--
Update the Path concept
Concept check for paths

DirPath renamed to Path
The interface updated to the new lemon interface
Make difference between the empty path and the path from one node
Builder interface have not been changed
// I wanted but there was not accordance about it

UPath is removed
It was a buggy implementation, it could not iterate on the
nodes in the right order
Right way to use undirected paths => path of edges in undirected graphs

The tests have been modified to the current implementation
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@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@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@2187
   205
      return Parent::edgeFromId(id);
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@2222
   241
    Edge findEdge(Node source, Node target, Edge prev = INVALID) 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@2222
   259
    UEdge findUEdge(Node source, Node target, UEdge prev = INVALID) const {
deba@2222
   260
      if (source != target) {
deba@2222
   261
        if (prev == INVALID) {
deba@2222
   262
          UEdge edge = Parent::findEdge(source, target);
deba@2222
   263
          if (edge != INVALID) return edge;
deba@2222
   264
          edge = Parent::findEdge(target, source);
deba@2222
   265
          if (edge != INVALID) return edge;
deba@2222
   266
        } else if (Parent::source(prev) == source) {
deba@2222
   267
          UEdge edge = Parent::findEdge(source, target, prev);
deba@2222
   268
          if (edge != INVALID) return edge;
deba@2222
   269
          edge = Parent::findEdge(target, source);
deba@2222
   270
          if (edge != INVALID) return edge;	
deba@2222
   271
        } else {
deba@2222
   272
          UEdge edge = Parent::findEdge(target, source, prev);
deba@2222
   273
          if (edge != INVALID) return edge;	      
deba@2222
   274
        }
deba@1999
   275
      } else {
deba@2222
   276
        return Parent::findEdge(source, target, prev);
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@2231
   312
    };
deba@2231
   313
deba@2231
   314
    void first(ANode& node) const {
deba@2231
   315
      Parent::firstANode(static_cast<Node&>(node));
deba@2231
   316
    }
deba@2231
   317
    void next(ANode& node) const {
deba@2231
   318
      Parent::nextANode(static_cast<Node&>(node));
deba@2231
   319
    }
deba@2231
   320
deba@2231
   321
    int id(const ANode& node) const {
deba@2231
   322
      return Parent::aNodeId(node);
deba@2231
   323
    }
deba@2231
   324
deba@2231
   325
    class BNode : public Node {
deba@2231
   326
      friend class BidirBpUGraphExtender;
deba@2231
   327
    public:
deba@2231
   328
      BNode() {}
deba@2231
   329
      BNode(const Node& node) : Node(node) {
deba@2231
   330
	LEMON_ASSERT(Parent::bNode(node) || node == INVALID,
deba@2231
   331
		     typename Parent::NodeSetError());
deba@2231
   332
      }
deba@2231
   333
      BNode& operator=(const Node& node) {
deba@2231
   334
	LEMON_ASSERT(Parent::bNode(node) || node == INVALID, 
deba@2231
   335
		     typename Parent::NodeSetError());
deba@2231
   336
        Node::operator=(node);
deba@2231
   337
        return *this;
deba@2231
   338
      }
deba@2231
   339
      BNode(Invalid) : Node(INVALID) {}
deba@2231
   340
    };
deba@2231
   341
deba@2231
   342
    void first(BNode& node) const {
deba@2231
   343
      Parent::firstBNode(static_cast<Node&>(node));
deba@2231
   344
    }
deba@2231
   345
    void next(BNode& node) const {
deba@2231
   346
      Parent::nextBNode(static_cast<Node&>(node));
deba@2231
   347
    }
deba@2231
   348
  
deba@2231
   349
    int id(const BNode& node) const {
deba@2231
   350
      return Parent::aNodeId(node);
deba@2231
   351
    }
deba@2231
   352
deba@2231
   353
    Node source(const UEdge& edge) const {
deba@2231
   354
      return aNode(edge);
deba@2231
   355
    }
deba@2231
   356
    Node target(const UEdge& edge) const {
deba@2231
   357
      return bNode(edge);
deba@2231
   358
    }
deba@2231
   359
deba@2231
   360
    void firstInc(UEdge& edge, bool& direction, const Node& node) const {
deba@2231
   361
      if (Parent::aNode(node)) {
deba@2231
   362
	Parent::firstFromANode(edge, node);
deba@2231
   363
	direction = true;
deba@2231
   364
      } else {
deba@2231
   365
	Parent::firstFromBNode(edge, node);
deba@2231
   366
	direction = static_cast<UEdge&>(edge) == INVALID;
deba@2231
   367
      }
deba@2231
   368
    }
deba@2231
   369
    void nextInc(UEdge& edge, bool& direction) const {
deba@2231
   370
      if (direction) {
deba@2231
   371
	Parent::nextFromANode(edge);
deba@2231
   372
      } else {
deba@2231
   373
	Parent::nextFromBNode(edge);
deba@2231
   374
	if (edge == INVALID) direction = true;
deba@2231
   375
      }
deba@2231
   376
    }
deba@2231
   377
deba@2231
   378
    class Edge : public UEdge {
deba@2231
   379
      friend class BidirBpUGraphExtender;
deba@2231
   380
    protected:
deba@2231
   381
      bool forward;
deba@2231
   382
deba@2231
   383
      Edge(const UEdge& edge, bool _forward)
deba@2231
   384
	: UEdge(edge), forward(_forward) {}
deba@2231
   385
deba@2231
   386
    public:
deba@2231
   387
      Edge() {}
deba@2231
   388
      Edge (Invalid) : UEdge(INVALID), forward(true) {}
deba@2231
   389
      bool operator==(const Edge& i) const {
deba@2231
   390
	return UEdge::operator==(i) && forward == i.forward;
deba@2231
   391
      }
deba@2231
   392
      bool operator!=(const Edge& i) const {
deba@2231
   393
	return UEdge::operator!=(i) || forward != i.forward;
deba@2231
   394
      }
deba@2231
   395
      bool operator<(const Edge& i) const {
deba@2231
   396
	return UEdge::operator<(i) || 
deba@2231
   397
	  (!(i.forward<forward) && UEdge(*this)<UEdge(i));
deba@2231
   398
      }
deba@2231
   399
    };
deba@2231
   400
deba@2231
   401
    void first(Edge& edge) const {
deba@2231
   402
      Parent::first(static_cast<UEdge&>(edge));
deba@2231
   403
      edge.forward = true;
deba@2231
   404
    }
deba@2231
   405
deba@2231
   406
    void next(Edge& edge) const {
deba@2231
   407
      if (!edge.forward) {
deba@2231
   408
	Parent::next(static_cast<UEdge&>(edge));
deba@2231
   409
      }
deba@2231
   410
      edge.forward = !edge.forward;
deba@2231
   411
    }
deba@2231
   412
deba@2231
   413
    void firstOut(Edge& edge, const Node& node) const {
deba@2231
   414
      if (Parent::aNode(node)) {
deba@2231
   415
	Parent::firstFromANode(edge, node);
deba@2231
   416
	edge.forward = true;
deba@2231
   417
      } else {
deba@2231
   418
	Parent::firstFromBNode(edge, node);
deba@2231
   419
	edge.forward = static_cast<UEdge&>(edge) == INVALID;
deba@2231
   420
      }
deba@2231
   421
    }
deba@2231
   422
    void nextOut(Edge& edge) const {
deba@2231
   423
      if (edge.forward) {
deba@2231
   424
	Parent::nextFromANode(edge);
deba@2231
   425
      } else {
deba@2231
   426
	Parent::nextFromBNode(edge);
deba@2231
   427
        edge.forward = static_cast<UEdge&>(edge) == INVALID;
deba@2231
   428
      }
deba@2231
   429
    }
deba@2231
   430
deba@2231
   431
    void firstIn(Edge& edge, const Node& node) const {
deba@2231
   432
      if (Parent::bNode(node)) {
deba@2231
   433
	Parent::firstFromBNode(edge, node);
deba@2231
   434
	edge.forward = true;	
deba@2231
   435
      } else {
deba@2231
   436
	Parent::firstFromANode(edge, node);
deba@2231
   437
	edge.forward = static_cast<UEdge&>(edge) == INVALID;
deba@2231
   438
      }
deba@2231
   439
    }
deba@2231
   440
    void nextIn(Edge& edge) const {
deba@2231
   441
      if (edge.forward) {
deba@2231
   442
	Parent::nextFromBNode(edge);
deba@2231
   443
      } else {
deba@2231
   444
	Parent::nextFromANode(edge);
deba@2231
   445
	edge.forward = static_cast<UEdge&>(edge) == INVALID;
deba@2231
   446
      }
deba@2231
   447
    }
deba@2231
   448
deba@2231
   449
    Node source(const Edge& edge) const {
deba@2231
   450
      return edge.forward ? Parent::aNode(edge) : Parent::bNode(edge);
deba@2231
   451
    }
deba@2231
   452
    Node target(const Edge& edge) const {
deba@2231
   453
      return edge.forward ? Parent::bNode(edge) : Parent::aNode(edge);
deba@2231
   454
    }
deba@2231
   455
deba@2231
   456
    int id(const Edge& edge) const {
deba@2231
   457
      return (Parent::id(static_cast<const UEdge&>(edge)) << 1) + 
deba@2231
   458
        (edge.forward ? 0 : 1);
deba@2231
   459
    }
deba@2231
   460
    Edge edgeFromId(int id) const {
deba@2231
   461
      return Edge(Parent::fromUEdgeId(id >> 1), (id & 1) == 0);
deba@2231
   462
    }
deba@2231
   463
    int maxEdgeId() const {
deba@2231
   464
      return (Parent::maxUEdgeId() << 1) + 1;
deba@2231
   465
    }
deba@2231
   466
deba@2231
   467
    bool direction(const Edge& edge) const {
deba@2231
   468
      return edge.forward;
deba@2231
   469
    }
deba@2231
   470
deba@2231
   471
    Edge direct(const UEdge& edge, bool direction) const {
deba@2231
   472
      return Edge(edge, direction);
deba@2231
   473
    }
deba@2231
   474
deba@2231
   475
    int edgeNum() const {
deba@2231
   476
      return 2 * Parent::uEdgeNum();
deba@2231
   477
    }
deba@2231
   478
deba@2231
   479
    int uEdgeNum() const {
deba@2231
   480
      return Parent::uEdgeNum();
deba@2231
   481
    }
deba@2231
   482
deba@2231
   483
deba@2231
   484
  };
deba@1999
   485
}
deba@1999
   486
deba@1999
   487
#endif