lemon/bpugraph_adaptor.h
author deba
Tue, 17 Oct 2006 10:50:57 +0000
changeset 2247 269a0dcee70b
parent 2084 59769591eb60
child 2384 805c5a2a36dd
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@2031
     1
/* -*- C++ -*-
deba@2031
     2
 *
deba@2031
     3
 * This file is a part of LEMON, a generic C++ optimization library
deba@2031
     4
 *
deba@2031
     5
 * Copyright (C) 2003-2006
deba@2031
     6
 * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
deba@2031
     7
 * (Egervary Research Group on Combinatorial Optimization, EGRES).
deba@2031
     8
 *
deba@2031
     9
 * Permission to use, modify and distribute this software is granted
deba@2031
    10
 * provided that this copyright notice appears in all copies. For
deba@2031
    11
 * precise terms see the accompanying LICENSE file.
deba@2031
    12
 *
deba@2031
    13
 * This software is provided "AS IS" with no warranty of any kind,
deba@2031
    14
 * express or implied, and with no claim as to its suitability for any
deba@2031
    15
 * purpose.
deba@2031
    16
 *
deba@2031
    17
 */
deba@2031
    18
deba@2031
    19
#ifndef LEMON_BPUGRAPH_ADAPTOR_H
deba@2031
    20
#define LEMON_BPUGRAPH_ADAPTOR_H
deba@2031
    21
deba@2031
    22
#include <lemon/bits/invalid.h>
deba@2031
    23
#include <lemon/maps.h>
deba@2031
    24
deba@2031
    25
#include <lemon/bits/graph_adaptor_extender.h>
deba@2031
    26
deba@2031
    27
#include <lemon/bits/traits.h>
deba@2031
    28
deba@2031
    29
#include <iostream>
deba@2031
    30
deba@2031
    31
///\ingroup graph_adaptors
deba@2031
    32
///\file
deba@2031
    33
///\brief Several graph adaptors.
deba@2031
    34
///
deba@2031
    35
///This file contains several useful bpugraph adaptor functions.
deba@2031
    36
///
deba@2031
    37
///\author Balazs Dezso
deba@2031
    38
deba@2031
    39
namespace lemon {
deba@2031
    40
deba@2031
    41
  /// \ingroup graph_adaptors
deba@2031
    42
  ///
deba@2031
    43
  /// \brief Base type for the Bipartite Undirected Graph Adaptors
deba@2031
    44
  ///
deba@2031
    45
  /// This is the base type for most of LEMON bpugraph adaptors. 
deba@2031
    46
  /// This class implements a trivial graph adaptor i.e. it only wraps the 
deba@2031
    47
  /// functions and types of the graph. The purpose of this class is to 
deba@2031
    48
  /// make easier implementing graph adaptors. E.g. if an adaptor is 
deba@2031
    49
  /// considered which differs from the wrapped graph only in some of its 
deba@2031
    50
  /// functions or types, then it can be derived from BpUGraphAdaptor, and 
deba@2031
    51
  /// only the differences should be implemented.
deba@2031
    52
  ///
deba@2031
    53
  /// \author Balazs Dezso 
deba@2031
    54
  template<typename _BpUGraph>
deba@2031
    55
  class BpUGraphAdaptorBase {
deba@2031
    56
  public:
deba@2031
    57
    typedef _BpUGraph Graph;
deba@2031
    58
    typedef Graph ParentGraph;
deba@2031
    59
deba@2031
    60
  protected:
deba@2031
    61
    Graph* graph;
deba@2031
    62
deba@2031
    63
    BpUGraphAdaptorBase() : graph(0) {}
deba@2031
    64
deba@2031
    65
    void setGraph(Graph& _graph) { graph = &_graph; }
deba@2031
    66
deba@2031
    67
    Graph& getGraph() { return *graph; }
deba@2031
    68
    const Graph& getGraph() const { return *graph; }
deba@2031
    69
deba@2031
    70
  public:
deba@2031
    71
deba@2031
    72
    BpUGraphAdaptorBase(Graph& _graph) : graph(&_graph) {}
deba@2031
    73
 
deba@2031
    74
    typedef typename Graph::Node Node;
deba@2031
    75
    typedef typename Graph::ANode ANode;
deba@2031
    76
    typedef typename Graph::BNode BNode;
deba@2031
    77
    typedef typename Graph::Edge Edge;
deba@2031
    78
    typedef typename Graph::UEdge UEdge;
deba@2031
    79
   
deba@2031
    80
    void first(Node& i) const { graph->first(i); }
deba@2031
    81
    void firstANode(Node& i) const { graph->firstANode(i); }
deba@2031
    82
    void firstBNode(Node& i) const { graph->firstBNode(i); }
deba@2031
    83
    void first(Edge& i) const { graph->first(i); }
deba@2031
    84
    void first(UEdge& i) const { graph->first(i); }
deba@2031
    85
    void firstIn(Edge& i, const Node& n) const { graph->firstIn(i, n); }
deba@2031
    86
    void firstOut(Edge& i, const Node& n ) const { graph->firstOut(i, n); }
deba@2031
    87
    void firstInc(UEdge &i, bool &d, const Node &n) const {
deba@2031
    88
      graph->firstInc(i, d, n);
deba@2031
    89
    }
deba@2231
    90
    void firstFromANode(UEdge& i, const Node& n) const {
deba@2231
    91
      graph->firstFromANode(i, n);
deba@2231
    92
    }
deba@2231
    93
    void firstFromBNode(UEdge& i, const Node& n) const {
deba@2231
    94
      graph->firstFromBNode(i, n);
deba@2231
    95
    }
deba@2031
    96
deba@2031
    97
    void next(Node& i) const { graph->next(i); }
deba@2031
    98
    void nextANode(Node& i) const { graph->nextANode(i); }
deba@2031
    99
    void nextBNode(Node& i) const { graph->nextBNode(i); }
deba@2031
   100
    void next(Edge& i) const { graph->next(i); }
deba@2031
   101
    void next(UEdge& i) const { graph->next(i); }
deba@2031
   102
    void nextIn(Edge& i) const { graph->nextIn(i); }
deba@2031
   103
    void nextOut(Edge& i) const { graph->nextOut(i); }
deba@2031
   104
    void nextInc(UEdge &i, bool &d) const { graph->nextInc(i, d); }
deba@2231
   105
    void nextFromANode(UEdge& i) const { graph->nextFromANode(i); }
deba@2231
   106
    void nextFromBNode(UEdge& i) const { graph->nextFromBNode(i); }
deba@2031
   107
deba@2031
   108
    Node source(const UEdge& e) const { return graph->source(e); }
deba@2031
   109
    Node target(const UEdge& e) const { return graph->target(e); }
deba@2031
   110
deba@2031
   111
    Node source(const Edge& e) const { return graph->source(e); }
deba@2031
   112
    Node target(const Edge& e) const { return graph->target(e); }
deba@2031
   113
deba@2040
   114
    Node aNode(const UEdge& e) const { return graph->aNode(e); }
deba@2040
   115
    Node bNode(const UEdge& e) const { return graph->bNode(e); }
deba@2040
   116
deba@2040
   117
    bool aNode(const Node& n) const { return graph->aNode(n); }
deba@2040
   118
    bool bNode(const Node& n) const { return graph->bNode(n); }
deba@2040
   119
deba@2031
   120
    typedef NodeNumTagIndicator<Graph> NodeNumTag;
deba@2031
   121
    int nodeNum() const { return graph->nodeNum(); }
deba@2031
   122
    int aNodeNum() const { return graph->aNodeNum(); }
deba@2031
   123
    int bNodeNum() const { return graph->bNodeNum(); }
deba@2031
   124
    
deba@2031
   125
    typedef EdgeNumTagIndicator<Graph> EdgeNumTag;
deba@2031
   126
    int edgeNum() const { return graph->edgeNum(); }
deba@2031
   127
    int uEdgeNum() const { return graph->uEdgeNum(); }
deba@2031
   128
deba@2031
   129
    typedef FindEdgeTagIndicator<Graph> FindEdgeTag;
deba@2031
   130
    Edge findEdge(const Node& source, const Node& target, 
deba@2031
   131
		  const Edge& prev = INVALID) {
deba@2031
   132
      return graph->findEdge(source, target, prev);
deba@2031
   133
    }
deba@2031
   134
    UEdge findUEdge(const Node& source, const Node& target, 
deba@2031
   135
                    const UEdge& prev = INVALID) {
deba@2031
   136
      return graph->findUEdge(source, target, prev);
deba@2031
   137
    }
deba@2031
   138
  
deba@2040
   139
    Node addANode() const { return graph->addANode(); }
deba@2040
   140
    Node addBNode() const { return graph->addBNode(); }
deba@2031
   141
    UEdge addEdge(const Node& source, const Node& target) const { 
deba@2031
   142
      return graph->addEdge(source, target); 
deba@2031
   143
    }
deba@2031
   144
deba@2031
   145
    void erase(const Node& i) const { graph->erase(i); }
deba@2031
   146
    void erase(const UEdge& i) const { graph->erase(i); }
deba@2031
   147
  
deba@2031
   148
    void clear() const { graph->clear(); }
deba@2031
   149
deba@2031
   150
    bool direction(const Edge& e) const { return graph->direction(e); }
deba@2031
   151
    Edge direct(const UEdge& e, bool d) const { return graph->direct(e, d); }
deba@2031
   152
    
deba@2031
   153
    int id(const Node& v) const { return graph->id(v); }
deba@2031
   154
    int id(const ANode& v) const { return graph->id(v); }
deba@2031
   155
    int id(const BNode& v) const { return graph->id(v); }
deba@2031
   156
    int id(const Edge& e) const { return graph->id(e); }
deba@2031
   157
    int id(const UEdge& e) const { return graph->id(e); }
deba@2031
   158
deba@2031
   159
    Node fromNodeId(int id) const { return graph->fromNodeId(id); }
deba@2231
   160
    ANode nodeFromANodeId(int id) const { return graph->nodeFromANodeId(id); }
deba@2231
   161
    BNode nodeFromBNodeId(int id) const { return graph->nodeFromBNodeId(id); }
deba@2031
   162
    Edge fromEdgeId(int id) const { return graph->fromEdgeId(id); }
deba@2031
   163
    UEdge fromUEdgeId(int id) const { return graph->fromUEdgeId(id); }
deba@2031
   164
deba@2031
   165
    int maxNodeId() const { return graph->maxNodeId(); }
deba@2031
   166
    int maxANodeId() const { return graph->maxANodeId(); }
deba@2031
   167
    int maxBNodeId() const { return graph->maxBNodeId(); }
deba@2031
   168
    int maxEdgeId() const { return graph->maxEdgeId(); }
deba@2031
   169
    int maxUEdgeId() const { return graph->maxEdgeId(); }
deba@2031
   170
deba@2031
   171
    typedef typename ItemSetTraits<Graph, Node>::ItemNotifier NodeNotifier;
deba@2031
   172
    NodeNotifier& getNotifier(Node) const {
deba@2031
   173
      return graph->getNotifier(Node()); 
deba@2031
   174
    } 
deba@2031
   175
deba@2031
   176
    typedef typename ItemSetTraits<Graph, ANode>::ItemNotifier ANodeNotifier;
deba@2031
   177
    ANodeNotifier& getNotifier(ANode) const {
deba@2031
   178
      return graph->getNotifier(ANode());
deba@2031
   179
    } 
deba@2031
   180
deba@2031
   181
    typedef typename ItemSetTraits<Graph, BNode>::ItemNotifier BNodeNotifier;
deba@2031
   182
    BNodeNotifier& getNotifier(BNode) const {
deba@2031
   183
      return graph->getNotifier(BNode());
deba@2031
   184
    } 
deba@2031
   185
deba@2031
   186
    typedef typename ItemSetTraits<Graph, Edge>::ItemNotifier EdgeNotifier;
deba@2031
   187
    EdgeNotifier& getNotifier(Edge) const {
deba@2031
   188
      return graph->getNotifier(Edge());
deba@2031
   189
    } 
deba@2031
   190
deba@2031
   191
    typedef typename ItemSetTraits<Graph, UEdge>::ItemNotifier UEdgeNotifier;
deba@2031
   192
    UEdgeNotifier& getNotifier(UEdge) const {
deba@2031
   193
      return graph->getNotifier(UEdge());
deba@2031
   194
    } 
deba@2031
   195
deba@2031
   196
    template <typename _Value>
deba@2031
   197
    class NodeMap : public Graph::template NodeMap<_Value> {
deba@2031
   198
    public:
deba@2031
   199
      typedef typename Graph::template NodeMap<_Value> Parent;
deba@2031
   200
      explicit NodeMap(const BpUGraphAdaptorBase<Graph>& ga) 
deba@2031
   201
	: Parent(*ga.graph) {}
deba@2031
   202
      NodeMap(const BpUGraphAdaptorBase<Graph>& ga, const _Value& value)
deba@2031
   203
	: Parent(*ga.graph, value) {}
deba@2031
   204
deba@2031
   205
      NodeMap& operator=(const NodeMap& cmap) {
deba@2031
   206
	return operator=<NodeMap>(cmap);
deba@2031
   207
      }
deba@2031
   208
deba@2031
   209
      template <typename CMap>
deba@2031
   210
      NodeMap& operator=(const CMap& cmap) {
deba@2031
   211
        Parent::operator=(cmap);
deba@2031
   212
	return *this;
deba@2031
   213
      }
deba@2031
   214
    };
deba@2031
   215
deba@2031
   216
    template <typename _Value>
deba@2031
   217
    class ANodeMap : public Graph::template ANodeMap<_Value> {
deba@2031
   218
    public:
deba@2031
   219
      typedef typename Graph::template ANodeMap<_Value> Parent;
deba@2031
   220
      explicit ANodeMap(const BpUGraphAdaptorBase& ga) 
deba@2031
   221
	: Parent(*ga.graph) {}
deba@2031
   222
      ANodeMap(const BpUGraphAdaptorBase& ga, const _Value& value)
deba@2031
   223
	: Parent(*ga.graph, value) {}
deba@2031
   224
deba@2031
   225
      ANodeMap& operator=(const ANodeMap& cmap) {
deba@2031
   226
	return operator=<ANodeMap>(cmap);
deba@2031
   227
      }
deba@2031
   228
deba@2031
   229
      template <typename CMap>
deba@2031
   230
      ANodeMap& operator=(const CMap& cmap) {
deba@2031
   231
        Parent::operator=(cmap);
deba@2031
   232
	return *this;
deba@2031
   233
      }
deba@2031
   234
    };
deba@2031
   235
deba@2031
   236
    template <typename _Value>
deba@2031
   237
    class BNodeMap : public Graph::template BNodeMap<_Value> {
deba@2031
   238
    public:
deba@2031
   239
      typedef typename Graph::template BNodeMap<_Value> Parent;
deba@2031
   240
      explicit BNodeMap(const BpUGraphAdaptorBase<Graph>& ga) 
deba@2031
   241
	: Parent(*ga.graph) {}
deba@2031
   242
      BNodeMap(const BpUGraphAdaptorBase<Graph>& ga, const _Value& value)
deba@2031
   243
	: Parent(*ga.graph, value) {}
deba@2031
   244
deba@2031
   245
      BNodeMap& operator=(const BNodeMap& cmap) {
deba@2031
   246
	return operator=<BNodeMap>(cmap);
deba@2031
   247
      }
deba@2031
   248
deba@2031
   249
      template <typename CMap>
deba@2031
   250
      BNodeMap& operator=(const CMap& cmap) {
deba@2031
   251
        Parent::operator=(cmap);
deba@2031
   252
	return *this;
deba@2031
   253
      }
deba@2031
   254
    };
deba@2031
   255
deba@2031
   256
    template <typename _Value>
deba@2031
   257
    class EdgeMap : public Graph::template EdgeMap<_Value> {
deba@2031
   258
    public:
deba@2031
   259
      typedef typename Graph::template EdgeMap<_Value> Parent;
deba@2031
   260
      explicit EdgeMap(const BpUGraphAdaptorBase<Graph>& ga) 
deba@2031
   261
	: Parent(*ga.graph) {}
deba@2031
   262
      EdgeMap(const BpUGraphAdaptorBase<Graph>& ga, const _Value& value)
deba@2031
   263
	: Parent(*ga.graph, value) {}
deba@2031
   264
deba@2031
   265
      EdgeMap& operator=(const EdgeMap& cmap) {
deba@2031
   266
	return operator=<EdgeMap>(cmap);
deba@2031
   267
      }
deba@2031
   268
deba@2031
   269
      template <typename CMap>
deba@2031
   270
      EdgeMap& operator=(const CMap& cmap) {
deba@2031
   271
        Parent::operator=(cmap);
deba@2031
   272
	return *this;
deba@2031
   273
      }
deba@2031
   274
    };
deba@2031
   275
deba@2031
   276
    template <typename _Value>
deba@2031
   277
    class UEdgeMap : public Graph::template UEdgeMap<_Value> {
deba@2031
   278
    public:
deba@2031
   279
      typedef typename Graph::template UEdgeMap<_Value> Parent;
deba@2031
   280
      explicit UEdgeMap(const BpUGraphAdaptorBase<Graph>& ga) 
deba@2031
   281
	: Parent(*ga.graph) {}
deba@2031
   282
      UEdgeMap(const BpUGraphAdaptorBase<Graph>& ga, const _Value& value)
deba@2031
   283
	: Parent(*ga.graph, value) {}
deba@2031
   284
deba@2031
   285
      UEdgeMap& operator=(const UEdgeMap& cmap) {
deba@2031
   286
	return operator=<UEdgeMap>(cmap);
deba@2031
   287
      }
deba@2031
   288
deba@2031
   289
      template <typename CMap>
deba@2031
   290
      UEdgeMap& operator=(const CMap& cmap) {
deba@2031
   291
        Parent::operator=(cmap);
deba@2031
   292
	return *this;
deba@2031
   293
      }
deba@2031
   294
    };
deba@2031
   295
deba@2031
   296
  };
deba@2031
   297
deba@2031
   298
  /// \ingroup graph_adaptors
deba@2040
   299
  ///
deba@2040
   300
  /// \brief Trivial Bipartite Undirected Graph Adaptor
deba@2040
   301
  ///
deba@2040
   302
  /// Trivial Bipartite Undirected Graph Adaptor. It does not change
deba@2040
   303
  /// the functionality of the adapted graph.
deba@2031
   304
  template <typename _BpUGraph>
deba@2031
   305
  class BpUGraphAdaptor 
deba@2031
   306
    : public BpUGraphAdaptorExtender< BpUGraphAdaptorBase<_BpUGraph> > { 
deba@2031
   307
  public:
deba@2031
   308
    typedef _BpUGraph Graph;
deba@2031
   309
    typedef BpUGraphAdaptorExtender<BpUGraphAdaptorBase<_BpUGraph> > Parent;
deba@2031
   310
  protected:
deba@2031
   311
    BpUGraphAdaptor() : Parent() {}
deba@2031
   312
deba@2031
   313
  public:
deba@2031
   314
    explicit BpUGraphAdaptor(Graph& _graph) { setGraph(_graph); }
deba@2031
   315
  };
deba@2031
   316
deba@2031
   317
  template <typename _BpUGraph>
deba@2031
   318
  class SwapBpUGraphAdaptorBase : public BpUGraphAdaptorBase<_BpUGraph> {
deba@2031
   319
  public:
deba@2031
   320
    
deba@2031
   321
    typedef _BpUGraph Graph;
deba@2031
   322
    typedef BpUGraphAdaptorBase<_BpUGraph> Parent;
deba@2031
   323
deba@2031
   324
  protected:
deba@2031
   325
    
deba@2031
   326
    SwapBpUGraphAdaptorBase() {}
deba@2031
   327
deba@2031
   328
  public:
deba@2031
   329
deba@2031
   330
    typedef typename Parent::Node Node;
deba@2031
   331
    typedef typename Parent::BNode ANode;
deba@2031
   332
    typedef typename Parent::ANode BNode;
deba@2040
   333
    typedef typename Parent::Edge Edge;
deba@2040
   334
    typedef typename Parent::UEdge UEdge;
deba@2040
   335
deba@2040
   336
    bool direction(const Edge& e) const { return !Parent::direction(e); }
deba@2040
   337
    Edge direct(const UEdge& e, bool b) const { return Parent::direct(e, !b); }
deba@2040
   338
deba@2040
   339
    Node aNode(const UEdge& e) const { return Parent::bNode(e); }
deba@2040
   340
    Node bNode(const UEdge& e) const { return Parent::aNode(e); }
deba@2040
   341
deba@2040
   342
    bool aNode(const Node& n) const { return Parent::bNode(n); }
deba@2040
   343
    bool bNode(const Node& n) const { return Parent::aNode(n); }
deba@2031
   344
deba@2031
   345
    void firstANode(Node& i) const { Parent::firstBNode(i); }
deba@2031
   346
    void firstBNode(Node& i) const { Parent::firstANode(i); }
deba@2031
   347
deba@2031
   348
    void nextANode(Node& i) const { Parent::nextBNode(i); }
deba@2031
   349
    void nextBNode(Node& i) const { Parent::nextANode(i); }
deba@2031
   350
deba@2231
   351
    void firstFromANode(UEdge& i, const Node& n) const {
deba@2231
   352
      Parent::firstFromBNode(i, n);
deba@2231
   353
    }
deba@2231
   354
    void firstFromBNode(UEdge& i, const Node& n) const {
deba@2231
   355
      Parent::firstFromANode(i, n);
deba@2231
   356
    }
deba@2231
   357
deba@2231
   358
    void nextFromANode(UEdge& i) const { Parent::nextFromBNode(i); }
deba@2231
   359
    void nextFromBNode(UEdge& i) const { Parent::nextFromANode(i); }
deba@2231
   360
deba@2031
   361
    int id(const ANode& v) const { return Parent::id(v); }
deba@2031
   362
    int id(const BNode& v) const { return Parent::id(v); }
deba@2031
   363
deba@2231
   364
    ANode nodeFromANodeId(int id) const { return Parent::nodeFromBNodeId(id); }
deba@2231
   365
    BNode nodeFromBNodeId(int id) const { return Parent::nodeFromANodeId(id); }
deba@2031
   366
deba@2031
   367
    int maxANodeId() const { return Parent::maxBNodeId(); }
deba@2031
   368
    int maxBNodeId() const { return Parent::maxANodeId(); }
deba@2031
   369
deba@2031
   370
    int aNodeNum() const { return Parent::bNodeNum(); }
deba@2031
   371
    int bNodeNum() const { return Parent::aNodeNum(); }
deba@2031
   372
deba@2031
   373
    typedef typename Parent::BNodeNotifier ANodeNotifier;
deba@2031
   374
    ANodeNotifier& getNotifier(ANode) const {
deba@2031
   375
      return Parent::getNotifier(typename Parent::BNode());
deba@2031
   376
    } 
deba@2031
   377
deba@2031
   378
    typedef typename Parent::ANodeNotifier BNodeNotifier;
deba@2031
   379
    BNodeNotifier& getNotifier(BNode) const {
deba@2031
   380
      return Parent::getNotifier(typename Parent::ANode());
deba@2031
   381
    } 
deba@2031
   382
deba@2031
   383
    template <typename _Value>
deba@2031
   384
    class ANodeMap : public Graph::template BNodeMap<_Value> {
deba@2031
   385
    public:
deba@2031
   386
      typedef typename Graph::template BNodeMap<_Value> Parent;
deba@2031
   387
      explicit ANodeMap(const SwapBpUGraphAdaptorBase& ga) 
deba@2031
   388
	: Parent(*ga.graph) {}
deba@2031
   389
      ANodeMap(const SwapBpUGraphAdaptorBase& ga, const _Value& value)
deba@2031
   390
	: Parent(*ga.graph, value) {}
deba@2031
   391
deba@2031
   392
      ANodeMap& operator=(const ANodeMap& cmap) {
deba@2031
   393
	return operator=<ANodeMap>(cmap);
deba@2031
   394
      }
deba@2031
   395
deba@2031
   396
      template <typename CMap>
deba@2031
   397
      ANodeMap& operator=(const CMap& cmap) {
deba@2031
   398
        Parent::operator=(cmap);
deba@2031
   399
	return *this;
deba@2031
   400
      }
deba@2031
   401
    };
deba@2031
   402
deba@2031
   403
    template <typename _Value>
deba@2031
   404
    class BNodeMap : public Graph::template ANodeMap<_Value> {
deba@2031
   405
    public:
deba@2031
   406
      typedef typename Graph::template ANodeMap<_Value> Parent;
deba@2031
   407
      explicit BNodeMap(const SwapBpUGraphAdaptorBase<Graph>& ga) 
deba@2031
   408
	: Parent(*ga.graph) {}
deba@2031
   409
      BNodeMap(const SwapBpUGraphAdaptorBase<Graph>& ga, const _Value& value)
deba@2031
   410
	: Parent(*ga.graph, value) {}
deba@2031
   411
deba@2031
   412
      BNodeMap& operator=(const BNodeMap& cmap) {
deba@2031
   413
	return operator=<BNodeMap>(cmap);
deba@2031
   414
      }
deba@2031
   415
deba@2031
   416
      template <typename CMap>
deba@2031
   417
      BNodeMap& operator=(const CMap& cmap) {
deba@2031
   418
        Parent::operator=(cmap);
deba@2031
   419
	return *this;
deba@2031
   420
      }
deba@2031
   421
    };
deba@2031
   422
    
deba@2031
   423
  };
deba@2031
   424
deba@2031
   425
  /// \ingroup graph_adaptors
deba@2031
   426
  ///
deba@2031
   427
  /// \brief Bipartite graph adaptor which swaps the two nodeset.
deba@2031
   428
  ///
deba@2031
   429
  /// Bipartite graph adaptor which swaps the two nodeset. The adaptor's
deba@2084
   430
  /// anode-set will be the original graph's bnode-set and the adaptor's
deba@2084
   431
  /// bnode-set will be the original graph's anode-set.
deba@2084
   432
  ///
deba@2084
   433
  /// As example look at an algorithm what can be sped up with the
deba@2084
   434
  /// swap bipartite undirected graph adaptor. If we want to find the
deba@2084
   435
  /// maximum matching in the bipartite graph then it will be not changed
deba@2084
   436
  /// if we swap the two nodesets. But the algorithm use the two nodeset
deba@2084
   437
  /// different way. If we swap the nodesets it provides different
deba@2084
   438
  /// running time. We run a test on random bipartite graphs with
deba@2084
   439
  /// different rate of the anode-set size and bnode-set size.
deba@2084
   440
  /// We always made graphs with 10000 nodes and 20000 edges and we
deba@2084
   441
  /// computed the maximum cardinality matching with the Hopcroft-Karp 
deba@2084
   442
  /// algorithm.
deba@2084
   443
  ///
deba@2084
   444
  /// The next diagram shows the running time of the tests. If the anode-set
deba@2084
   445
  /// is smaller than the bnode-set the running time is better than with 
deba@2084
   446
  /// the swapped graph. Other conclusion is that the running time
deba@2084
   447
  /// is greater when the two nodesets size are nearly equal. 
deba@2084
   448
  ///
deba@2084
   449
  /// \image html swap_test.png
deba@2084
   450
  /// \image latex swap_test.eps "Swapping nodesets" width=\textwidth
deba@2084
   451
  /// 
deba@2084
   452
  /// The next part shows how can we swap the two nodeset:
deba@2084
   453
  ///
deba@2084
   454
  ///\code
deba@2084
   455
  /// typedef SwapBpUGraphAdaptor<BpUGraph> SBpUGraph;
deba@2084
   456
  /// SBpUGraph sbpugraph(bpugraph);
deba@2084
   457
  /// MaxBipartiteMatching<SBpUGraph> sbpumatch(sbpugraph);
deba@2084
   458
  ///\endcode
deba@2031
   459
  template <typename _BpUGraph>
deba@2031
   460
  class SwapBpUGraphAdaptor 
deba@2031
   461
    : public BpUGraphAdaptorExtender<SwapBpUGraphAdaptorBase<_BpUGraph> > { 
deba@2031
   462
  public:
deba@2031
   463
deba@2031
   464
    typedef _BpUGraph Graph;
deba@2031
   465
    typedef BpUGraphAdaptorExtender<SwapBpUGraphAdaptorBase<_BpUGraph> > 
deba@2031
   466
    Parent;
deba@2031
   467
deba@2031
   468
  protected:
deba@2031
   469
    SwapBpUGraphAdaptor() : Parent() {}
deba@2031
   470
deba@2031
   471
  public:
deba@2031
   472
deba@2084
   473
    /// \brief Construct a swapped graph.
deba@2084
   474
    ///
deba@2084
   475
    /// Construct a swapped graph.
deba@2031
   476
    explicit SwapBpUGraphAdaptor(Graph& _graph) { setGraph(_graph); }
deba@2031
   477
deba@2031
   478
  };
deba@2031
   479
deba@2031
   480
deba@2040
   481
  template <typename _BpUGraph, 
deba@2040
   482
            typename _ANMatchingMap, typename _BNMatchingMap>
deba@2040
   483
  class MatchingBpUGraphAdaptorBase 
deba@2040
   484
    : public BpUGraphAdaptorBase<const _BpUGraph>
deba@2040
   485
  {
deba@2040
   486
  public:
deba@2040
   487
    
deba@2040
   488
    typedef _BpUGraph Graph;
deba@2040
   489
    typedef _ANMatchingMap ANodeMatchingMap;
deba@2040
   490
    typedef _BNMatchingMap BNodeMatchingMap;
deba@2040
   491
deba@2040
   492
    typedef BpUGraphAdaptorBase<const _BpUGraph> Parent;
deba@2040
   493
deba@2040
   494
  protected:
deba@2040
   495
    
deba@2040
   496
    MatchingBpUGraphAdaptorBase() {}
deba@2040
   497
deba@2040
   498
    void setANodeMatchingMap(ANodeMatchingMap& _anode_matching) {
deba@2040
   499
      anode_matching = &_anode_matching;
deba@2040
   500
    }
deba@2040
   501
deba@2040
   502
    void setBNodeMatchingMap(BNodeMatchingMap& _bnode_matching) {
deba@2040
   503
      bnode_matching = &_bnode_matching;
deba@2040
   504
    }
deba@2040
   505
deba@2040
   506
  public:
deba@2040
   507
deba@2040
   508
    typedef typename Parent::Node Node;
deba@2040
   509
    typedef typename Parent::Edge Edge;
deba@2040
   510
deba@2040
   511
    void firstOut(Edge& edge, const Node& node) const {
deba@2040
   512
      if (Parent::aNode(node)) {
deba@2040
   513
        Parent::firstOut(edge, node);
deba@2040
   514
        if (edge != INVALID && (*anode_matching)[node] == edge) {
deba@2040
   515
          Parent::nextOut(edge);
deba@2040
   516
        }
deba@2040
   517
      } else {
deba@2040
   518
        edge = (*bnode_matching)[node] != INVALID ?
deba@2040
   519
          Parent::direct((*bnode_matching)[node], false) : INVALID;
deba@2040
   520
      }
deba@2040
   521
    }
deba@2040
   522
deba@2040
   523
    void nextOut(Edge& edge) const {
deba@2040
   524
      if (Parent::aNode(Parent::source(edge))) {
deba@2040
   525
        Parent::nextOut(edge);
deba@2040
   526
        if (edge != INVALID && (*anode_matching)[Parent::aNode(edge)] == edge) {
deba@2040
   527
          Parent::nextOut(edge);
deba@2040
   528
        }
deba@2040
   529
      } else {
deba@2040
   530
        edge = INVALID;
deba@2040
   531
      }
deba@2040
   532
    }
deba@2040
   533
 
deba@2040
   534
    void firstIn(Edge& edge, const Node& node) const {
deba@2040
   535
      if (Parent::aNode(node)) {
deba@2040
   536
        edge = (*bnode_matching)[node] != INVALID ?
deba@2040
   537
          Parent::direct((*anode_matching)[node], false) : INVALID;
deba@2040
   538
      } else {
deba@2040
   539
        Parent::firstIn(edge, node);
deba@2040
   540
        if (edge != INVALID && (*bnode_matching)[node] == edge) {
deba@2040
   541
          Parent::nextIn(edge);
deba@2040
   542
        }
deba@2040
   543
      }
deba@2040
   544
    }
deba@2040
   545
deba@2040
   546
    void nextIn(Edge& edge) const {
deba@2040
   547
      if (Parent::aNode(Parent::target(edge))) {
deba@2040
   548
        edge = INVALID;
deba@2040
   549
      } else {
deba@2040
   550
        Parent::nextIn(edge);
deba@2040
   551
        if (edge != INVALID && (*bnode_matching)[Parent::bNode(edge)] == edge) {
deba@2040
   552
          Parent::nextIn(edge);
deba@2040
   553
        }
deba@2040
   554
      }
deba@2040
   555
    } 
deba@2040
   556
deba@2040
   557
  private:
deba@2040
   558
    ANodeMatchingMap* anode_matching;
deba@2040
   559
    BNodeMatchingMap* bnode_matching;
deba@2040
   560
  };
deba@2040
   561
deba@2040
   562
deba@2040
   563
  /// \ingroup graph_adaptors
deba@2040
   564
  ///
deba@2040
   565
  /// \brief Bipartite graph adaptor to implement matching algorithms.
deba@2040
   566
  ///
deba@2040
   567
  /// Bipartite graph adaptor to implement matchings. It implements
deba@2040
   568
  /// the residual graph of the matching.
deba@2040
   569
  template <typename _BpUGraph, 
deba@2231
   570
            typename _ANMatchingMap = 
deba@2231
   571
            typename _BpUGraph::template ANodeMap<typename _BpUGraph::UEdge>, 
deba@2231
   572
            typename _BNMatchingMap =
deba@2231
   573
            typename _BpUGraph::template BNodeMap<typename _BpUGraph::UEdge> >
deba@2040
   574
  class MatchingBpUGraphAdaptor 
deba@2040
   575
    : public BpUGraphAdaptorExtender<
deba@2040
   576
    MatchingBpUGraphAdaptorBase<_BpUGraph, _ANMatchingMap, _BNMatchingMap> > 
deba@2040
   577
  { 
deba@2040
   578
  public:
deba@2040
   579
deba@2040
   580
    typedef _BpUGraph BpUGraph;
deba@2040
   581
    typedef _BpUGraph Graph;
deba@2040
   582
    typedef _ANMatchingMap ANodeMatchingMap;
deba@2040
   583
    typedef _BNMatchingMap BNodeMatchingMap;
deba@2040
   584
    typedef BpUGraphAdaptorExtender<
deba@2040
   585
      MatchingBpUGraphAdaptorBase<BpUGraph, 
deba@2040
   586
                                  ANodeMatchingMap, BNodeMatchingMap> > 
deba@2040
   587
    Parent;
deba@2040
   588
deba@2040
   589
  protected:
deba@2040
   590
    MatchingBpUGraphAdaptor() : Parent() {}
deba@2040
   591
deba@2040
   592
  public:
deba@2040
   593
deba@2040
   594
    MatchingBpUGraphAdaptor(const Graph& _graph, 
deba@2040
   595
                            ANodeMatchingMap& _anode_matching,
deba@2040
   596
                            BNodeMatchingMap& _bnode_matching) {
deba@2040
   597
      setGraph(_graph);
deba@2040
   598
      setANodeMatchingMap(_anode_matching);
deba@2040
   599
      setBNodeMatchingMap(_bnode_matching);
deba@2040
   600
    }
deba@2040
   601
deba@2040
   602
  };
deba@2040
   603
deba@2031
   604
}
deba@2031
   605
deba@2031
   606
#endif