lemon/bpugraph_adaptor.h
author alpar
Mon, 04 Sep 2006 19:12:44 +0000
changeset 2194 eaf16c8f6fef
parent 2040 c7bd55c0d820
child 2231 06faf3f06d67
permissions -rw-r--r--
'make doc' is now working also in case of external build.
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@2031
    90
deba@2031
    91
    void next(Node& i) const { graph->next(i); }
deba@2031
    92
    void nextANode(Node& i) const { graph->nextANode(i); }
deba@2031
    93
    void nextBNode(Node& i) const { graph->nextBNode(i); }
deba@2031
    94
    void next(Edge& i) const { graph->next(i); }
deba@2031
    95
    void next(UEdge& i) const { graph->next(i); }
deba@2031
    96
    void nextIn(Edge& i) const { graph->nextIn(i); }
deba@2031
    97
    void nextOut(Edge& i) const { graph->nextOut(i); }
deba@2031
    98
    void nextInc(UEdge &i, bool &d) const { graph->nextInc(i, d); }
deba@2031
    99
deba@2031
   100
    Node source(const UEdge& e) const { return graph->source(e); }
deba@2031
   101
    Node target(const UEdge& e) const { return graph->target(e); }
deba@2031
   102
deba@2031
   103
    Node source(const Edge& e) const { return graph->source(e); }
deba@2031
   104
    Node target(const Edge& e) const { return graph->target(e); }
deba@2031
   105
deba@2040
   106
    Node aNode(const UEdge& e) const { return graph->aNode(e); }
deba@2040
   107
    Node bNode(const UEdge& e) const { return graph->bNode(e); }
deba@2040
   108
deba@2040
   109
    bool aNode(const Node& n) const { return graph->aNode(n); }
deba@2040
   110
    bool bNode(const Node& n) const { return graph->bNode(n); }
deba@2040
   111
deba@2031
   112
    typedef NodeNumTagIndicator<Graph> NodeNumTag;
deba@2031
   113
    int nodeNum() const { return graph->nodeNum(); }
deba@2031
   114
    int aNodeNum() const { return graph->aNodeNum(); }
deba@2031
   115
    int bNodeNum() const { return graph->bNodeNum(); }
deba@2031
   116
    
deba@2031
   117
    typedef EdgeNumTagIndicator<Graph> EdgeNumTag;
deba@2031
   118
    int edgeNum() const { return graph->edgeNum(); }
deba@2031
   119
    int uEdgeNum() const { return graph->uEdgeNum(); }
deba@2031
   120
deba@2031
   121
    typedef FindEdgeTagIndicator<Graph> FindEdgeTag;
deba@2031
   122
    Edge findEdge(const Node& source, const Node& target, 
deba@2031
   123
		  const Edge& prev = INVALID) {
deba@2031
   124
      return graph->findEdge(source, target, prev);
deba@2031
   125
    }
deba@2031
   126
    UEdge findUEdge(const Node& source, const Node& target, 
deba@2031
   127
                    const UEdge& prev = INVALID) {
deba@2031
   128
      return graph->findUEdge(source, target, prev);
deba@2031
   129
    }
deba@2031
   130
  
deba@2040
   131
    Node addANode() const { return graph->addANode(); }
deba@2040
   132
    Node addBNode() const { return graph->addBNode(); }
deba@2031
   133
    UEdge addEdge(const Node& source, const Node& target) const { 
deba@2031
   134
      return graph->addEdge(source, target); 
deba@2031
   135
    }
deba@2031
   136
deba@2031
   137
    void erase(const Node& i) const { graph->erase(i); }
deba@2031
   138
    void erase(const UEdge& i) const { graph->erase(i); }
deba@2031
   139
  
deba@2031
   140
    void clear() const { graph->clear(); }
deba@2031
   141
deba@2031
   142
    bool direction(const Edge& e) const { return graph->direction(e); }
deba@2031
   143
    Edge direct(const UEdge& e, bool d) const { return graph->direct(e, d); }
deba@2031
   144
    
deba@2031
   145
    int id(const Node& v) const { return graph->id(v); }
deba@2031
   146
    int id(const ANode& v) const { return graph->id(v); }
deba@2031
   147
    int id(const BNode& v) const { return graph->id(v); }
deba@2031
   148
    int id(const Edge& e) const { return graph->id(e); }
deba@2031
   149
    int id(const UEdge& e) const { return graph->id(e); }
deba@2031
   150
deba@2031
   151
    Node fromNodeId(int id) const { return graph->fromNodeId(id); }
deba@2031
   152
    ANode fromANodeId(int id) const { return graph->fromANodeId(id); }
deba@2031
   153
    BNode fromBNodeId(int id) const { return graph->fromBNodeId(id); }
deba@2031
   154
    Edge fromEdgeId(int id) const { return graph->fromEdgeId(id); }
deba@2031
   155
    UEdge fromUEdgeId(int id) const { return graph->fromUEdgeId(id); }
deba@2031
   156
deba@2031
   157
    int maxNodeId() const { return graph->maxNodeId(); }
deba@2031
   158
    int maxANodeId() const { return graph->maxANodeId(); }
deba@2031
   159
    int maxBNodeId() const { return graph->maxBNodeId(); }
deba@2031
   160
    int maxEdgeId() const { return graph->maxEdgeId(); }
deba@2031
   161
    int maxUEdgeId() const { return graph->maxEdgeId(); }
deba@2031
   162
deba@2031
   163
    typedef typename ItemSetTraits<Graph, Node>::ItemNotifier NodeNotifier;
deba@2031
   164
    NodeNotifier& getNotifier(Node) const {
deba@2031
   165
      return graph->getNotifier(Node()); 
deba@2031
   166
    } 
deba@2031
   167
deba@2031
   168
    typedef typename ItemSetTraits<Graph, ANode>::ItemNotifier ANodeNotifier;
deba@2031
   169
    ANodeNotifier& getNotifier(ANode) const {
deba@2031
   170
      return graph->getNotifier(ANode());
deba@2031
   171
    } 
deba@2031
   172
deba@2031
   173
    typedef typename ItemSetTraits<Graph, BNode>::ItemNotifier BNodeNotifier;
deba@2031
   174
    BNodeNotifier& getNotifier(BNode) const {
deba@2031
   175
      return graph->getNotifier(BNode());
deba@2031
   176
    } 
deba@2031
   177
deba@2031
   178
    typedef typename ItemSetTraits<Graph, Edge>::ItemNotifier EdgeNotifier;
deba@2031
   179
    EdgeNotifier& getNotifier(Edge) const {
deba@2031
   180
      return graph->getNotifier(Edge());
deba@2031
   181
    } 
deba@2031
   182
deba@2031
   183
    typedef typename ItemSetTraits<Graph, UEdge>::ItemNotifier UEdgeNotifier;
deba@2031
   184
    UEdgeNotifier& getNotifier(UEdge) const {
deba@2031
   185
      return graph->getNotifier(UEdge());
deba@2031
   186
    } 
deba@2031
   187
deba@2031
   188
    template <typename _Value>
deba@2031
   189
    class NodeMap : public Graph::template NodeMap<_Value> {
deba@2031
   190
    public:
deba@2031
   191
      typedef typename Graph::template NodeMap<_Value> Parent;
deba@2031
   192
      explicit NodeMap(const BpUGraphAdaptorBase<Graph>& ga) 
deba@2031
   193
	: Parent(*ga.graph) {}
deba@2031
   194
      NodeMap(const BpUGraphAdaptorBase<Graph>& ga, const _Value& value)
deba@2031
   195
	: Parent(*ga.graph, value) {}
deba@2031
   196
deba@2031
   197
      NodeMap& operator=(const NodeMap& cmap) {
deba@2031
   198
	return operator=<NodeMap>(cmap);
deba@2031
   199
      }
deba@2031
   200
deba@2031
   201
      template <typename CMap>
deba@2031
   202
      NodeMap& operator=(const CMap& cmap) {
deba@2031
   203
        Parent::operator=(cmap);
deba@2031
   204
	return *this;
deba@2031
   205
      }
deba@2031
   206
    };
deba@2031
   207
deba@2031
   208
    template <typename _Value>
deba@2031
   209
    class ANodeMap : public Graph::template ANodeMap<_Value> {
deba@2031
   210
    public:
deba@2031
   211
      typedef typename Graph::template ANodeMap<_Value> Parent;
deba@2031
   212
      explicit ANodeMap(const BpUGraphAdaptorBase& ga) 
deba@2031
   213
	: Parent(*ga.graph) {}
deba@2031
   214
      ANodeMap(const BpUGraphAdaptorBase& ga, const _Value& value)
deba@2031
   215
	: Parent(*ga.graph, value) {}
deba@2031
   216
deba@2031
   217
      ANodeMap& operator=(const ANodeMap& cmap) {
deba@2031
   218
	return operator=<ANodeMap>(cmap);
deba@2031
   219
      }
deba@2031
   220
deba@2031
   221
      template <typename CMap>
deba@2031
   222
      ANodeMap& operator=(const CMap& cmap) {
deba@2031
   223
        Parent::operator=(cmap);
deba@2031
   224
	return *this;
deba@2031
   225
      }
deba@2031
   226
    };
deba@2031
   227
deba@2031
   228
    template <typename _Value>
deba@2031
   229
    class BNodeMap : public Graph::template BNodeMap<_Value> {
deba@2031
   230
    public:
deba@2031
   231
      typedef typename Graph::template BNodeMap<_Value> Parent;
deba@2031
   232
      explicit BNodeMap(const BpUGraphAdaptorBase<Graph>& ga) 
deba@2031
   233
	: Parent(*ga.graph) {}
deba@2031
   234
      BNodeMap(const BpUGraphAdaptorBase<Graph>& ga, const _Value& value)
deba@2031
   235
	: Parent(*ga.graph, value) {}
deba@2031
   236
deba@2031
   237
      BNodeMap& operator=(const BNodeMap& cmap) {
deba@2031
   238
	return operator=<BNodeMap>(cmap);
deba@2031
   239
      }
deba@2031
   240
deba@2031
   241
      template <typename CMap>
deba@2031
   242
      BNodeMap& operator=(const CMap& cmap) {
deba@2031
   243
        Parent::operator=(cmap);
deba@2031
   244
	return *this;
deba@2031
   245
      }
deba@2031
   246
    };
deba@2031
   247
deba@2031
   248
    template <typename _Value>
deba@2031
   249
    class EdgeMap : public Graph::template EdgeMap<_Value> {
deba@2031
   250
    public:
deba@2031
   251
      typedef typename Graph::template EdgeMap<_Value> Parent;
deba@2031
   252
      explicit EdgeMap(const BpUGraphAdaptorBase<Graph>& ga) 
deba@2031
   253
	: Parent(*ga.graph) {}
deba@2031
   254
      EdgeMap(const BpUGraphAdaptorBase<Graph>& ga, const _Value& value)
deba@2031
   255
	: Parent(*ga.graph, value) {}
deba@2031
   256
deba@2031
   257
      EdgeMap& operator=(const EdgeMap& cmap) {
deba@2031
   258
	return operator=<EdgeMap>(cmap);
deba@2031
   259
      }
deba@2031
   260
deba@2031
   261
      template <typename CMap>
deba@2031
   262
      EdgeMap& operator=(const CMap& cmap) {
deba@2031
   263
        Parent::operator=(cmap);
deba@2031
   264
	return *this;
deba@2031
   265
      }
deba@2031
   266
    };
deba@2031
   267
deba@2031
   268
    template <typename _Value>
deba@2031
   269
    class UEdgeMap : public Graph::template UEdgeMap<_Value> {
deba@2031
   270
    public:
deba@2031
   271
      typedef typename Graph::template UEdgeMap<_Value> Parent;
deba@2031
   272
      explicit UEdgeMap(const BpUGraphAdaptorBase<Graph>& ga) 
deba@2031
   273
	: Parent(*ga.graph) {}
deba@2031
   274
      UEdgeMap(const BpUGraphAdaptorBase<Graph>& ga, const _Value& value)
deba@2031
   275
	: Parent(*ga.graph, value) {}
deba@2031
   276
deba@2031
   277
      UEdgeMap& operator=(const UEdgeMap& cmap) {
deba@2031
   278
	return operator=<UEdgeMap>(cmap);
deba@2031
   279
      }
deba@2031
   280
deba@2031
   281
      template <typename CMap>
deba@2031
   282
      UEdgeMap& operator=(const CMap& cmap) {
deba@2031
   283
        Parent::operator=(cmap);
deba@2031
   284
	return *this;
deba@2031
   285
      }
deba@2031
   286
    };
deba@2031
   287
deba@2031
   288
  };
deba@2031
   289
deba@2031
   290
  /// \ingroup graph_adaptors
deba@2040
   291
  ///
deba@2040
   292
  /// \brief Trivial Bipartite Undirected Graph Adaptor
deba@2040
   293
  ///
deba@2040
   294
  /// Trivial Bipartite Undirected Graph Adaptor. It does not change
deba@2040
   295
  /// the functionality of the adapted graph.
deba@2031
   296
  template <typename _BpUGraph>
deba@2031
   297
  class BpUGraphAdaptor 
deba@2031
   298
    : public BpUGraphAdaptorExtender< BpUGraphAdaptorBase<_BpUGraph> > { 
deba@2031
   299
  public:
deba@2031
   300
    typedef _BpUGraph Graph;
deba@2031
   301
    typedef BpUGraphAdaptorExtender<BpUGraphAdaptorBase<_BpUGraph> > Parent;
deba@2031
   302
  protected:
deba@2031
   303
    BpUGraphAdaptor() : Parent() {}
deba@2031
   304
deba@2031
   305
  public:
deba@2031
   306
    explicit BpUGraphAdaptor(Graph& _graph) { setGraph(_graph); }
deba@2031
   307
  };
deba@2031
   308
deba@2031
   309
  template <typename _BpUGraph>
deba@2031
   310
  class SwapBpUGraphAdaptorBase : public BpUGraphAdaptorBase<_BpUGraph> {
deba@2031
   311
  public:
deba@2031
   312
    
deba@2031
   313
    typedef _BpUGraph Graph;
deba@2031
   314
    typedef BpUGraphAdaptorBase<_BpUGraph> Parent;
deba@2031
   315
deba@2031
   316
  protected:
deba@2031
   317
    
deba@2031
   318
    SwapBpUGraphAdaptorBase() {}
deba@2031
   319
deba@2031
   320
  public:
deba@2031
   321
deba@2031
   322
    typedef typename Parent::Node Node;
deba@2031
   323
    typedef typename Parent::BNode ANode;
deba@2031
   324
    typedef typename Parent::ANode BNode;
deba@2040
   325
    typedef typename Parent::Edge Edge;
deba@2040
   326
    typedef typename Parent::UEdge UEdge;
deba@2040
   327
deba@2040
   328
    bool direction(const Edge& e) const { return !Parent::direction(e); }
deba@2040
   329
    Edge direct(const UEdge& e, bool b) const { return Parent::direct(e, !b); }
deba@2040
   330
deba@2040
   331
    Node aNode(const UEdge& e) const { return Parent::bNode(e); }
deba@2040
   332
    Node bNode(const UEdge& e) const { return Parent::aNode(e); }
deba@2040
   333
deba@2040
   334
    bool aNode(const Node& n) const { return Parent::bNode(n); }
deba@2040
   335
    bool bNode(const Node& n) const { return Parent::aNode(n); }
deba@2031
   336
deba@2031
   337
    void firstANode(Node& i) const { Parent::firstBNode(i); }
deba@2031
   338
    void firstBNode(Node& i) const { Parent::firstANode(i); }
deba@2031
   339
deba@2031
   340
    void nextANode(Node& i) const { Parent::nextBNode(i); }
deba@2031
   341
    void nextBNode(Node& i) const { Parent::nextANode(i); }
deba@2031
   342
deba@2031
   343
    int id(const ANode& v) const { return Parent::id(v); }
deba@2031
   344
    int id(const BNode& v) const { return Parent::id(v); }
deba@2031
   345
deba@2031
   346
    ANode fromANodeId(int id) const { return Parent::fromBNodeId(id); }
deba@2031
   347
    BNode fromBNodeId(int id) const { return Parent::fromANodeId(id); }
deba@2031
   348
deba@2031
   349
    int maxANodeId() const { return Parent::maxBNodeId(); }
deba@2031
   350
    int maxBNodeId() const { return Parent::maxANodeId(); }
deba@2031
   351
deba@2031
   352
    int aNodeNum() const { return Parent::bNodeNum(); }
deba@2031
   353
    int bNodeNum() const { return Parent::aNodeNum(); }
deba@2031
   354
deba@2031
   355
    typedef typename Parent::BNodeNotifier ANodeNotifier;
deba@2031
   356
    ANodeNotifier& getNotifier(ANode) const {
deba@2031
   357
      return Parent::getNotifier(typename Parent::BNode());
deba@2031
   358
    } 
deba@2031
   359
deba@2031
   360
    typedef typename Parent::ANodeNotifier BNodeNotifier;
deba@2031
   361
    BNodeNotifier& getNotifier(BNode) const {
deba@2031
   362
      return Parent::getNotifier(typename Parent::ANode());
deba@2031
   363
    } 
deba@2031
   364
deba@2031
   365
    template <typename _Value>
deba@2031
   366
    class ANodeMap : public Graph::template BNodeMap<_Value> {
deba@2031
   367
    public:
deba@2031
   368
      typedef typename Graph::template BNodeMap<_Value> Parent;
deba@2031
   369
      explicit ANodeMap(const SwapBpUGraphAdaptorBase& ga) 
deba@2031
   370
	: Parent(*ga.graph) {}
deba@2031
   371
      ANodeMap(const SwapBpUGraphAdaptorBase& ga, const _Value& value)
deba@2031
   372
	: Parent(*ga.graph, value) {}
deba@2031
   373
deba@2031
   374
      ANodeMap& operator=(const ANodeMap& cmap) {
deba@2031
   375
	return operator=<ANodeMap>(cmap);
deba@2031
   376
      }
deba@2031
   377
deba@2031
   378
      template <typename CMap>
deba@2031
   379
      ANodeMap& operator=(const CMap& cmap) {
deba@2031
   380
        Parent::operator=(cmap);
deba@2031
   381
	return *this;
deba@2031
   382
      }
deba@2031
   383
    };
deba@2031
   384
deba@2031
   385
    template <typename _Value>
deba@2031
   386
    class BNodeMap : public Graph::template ANodeMap<_Value> {
deba@2031
   387
    public:
deba@2031
   388
      typedef typename Graph::template ANodeMap<_Value> Parent;
deba@2031
   389
      explicit BNodeMap(const SwapBpUGraphAdaptorBase<Graph>& ga) 
deba@2031
   390
	: Parent(*ga.graph) {}
deba@2031
   391
      BNodeMap(const SwapBpUGraphAdaptorBase<Graph>& ga, const _Value& value)
deba@2031
   392
	: Parent(*ga.graph, value) {}
deba@2031
   393
deba@2031
   394
      BNodeMap& operator=(const BNodeMap& cmap) {
deba@2031
   395
	return operator=<BNodeMap>(cmap);
deba@2031
   396
      }
deba@2031
   397
deba@2031
   398
      template <typename CMap>
deba@2031
   399
      BNodeMap& operator=(const CMap& cmap) {
deba@2031
   400
        Parent::operator=(cmap);
deba@2031
   401
	return *this;
deba@2031
   402
      }
deba@2031
   403
    };
deba@2031
   404
    
deba@2031
   405
  };
deba@2031
   406
deba@2031
   407
  /// \ingroup graph_adaptors
deba@2031
   408
  ///
deba@2031
   409
  /// \brief Bipartite graph adaptor which swaps the two nodeset.
deba@2031
   410
  ///
deba@2031
   411
  /// Bipartite graph adaptor which swaps the two nodeset. The adaptor's
deba@2084
   412
  /// anode-set will be the original graph's bnode-set and the adaptor's
deba@2084
   413
  /// bnode-set will be the original graph's anode-set.
deba@2084
   414
  ///
deba@2084
   415
  /// As example look at an algorithm what can be sped up with the
deba@2084
   416
  /// swap bipartite undirected graph adaptor. If we want to find the
deba@2084
   417
  /// maximum matching in the bipartite graph then it will be not changed
deba@2084
   418
  /// if we swap the two nodesets. But the algorithm use the two nodeset
deba@2084
   419
  /// different way. If we swap the nodesets it provides different
deba@2084
   420
  /// running time. We run a test on random bipartite graphs with
deba@2084
   421
  /// different rate of the anode-set size and bnode-set size.
deba@2084
   422
  /// We always made graphs with 10000 nodes and 20000 edges and we
deba@2084
   423
  /// computed the maximum cardinality matching with the Hopcroft-Karp 
deba@2084
   424
  /// algorithm.
deba@2084
   425
  ///
deba@2084
   426
  /// The next diagram shows the running time of the tests. If the anode-set
deba@2084
   427
  /// is smaller than the bnode-set the running time is better than with 
deba@2084
   428
  /// the swapped graph. Other conclusion is that the running time
deba@2084
   429
  /// is greater when the two nodesets size are nearly equal. 
deba@2084
   430
  ///
deba@2084
   431
  /// \image html swap_test.png
deba@2084
   432
  /// \image latex swap_test.eps "Swapping nodesets" width=\textwidth
deba@2084
   433
  /// 
deba@2084
   434
  /// The next part shows how can we swap the two nodeset:
deba@2084
   435
  ///
deba@2084
   436
  ///\code
deba@2084
   437
  /// typedef SwapBpUGraphAdaptor<BpUGraph> SBpUGraph;
deba@2084
   438
  /// SBpUGraph sbpugraph(bpugraph);
deba@2084
   439
  /// MaxBipartiteMatching<SBpUGraph> sbpumatch(sbpugraph);
deba@2084
   440
  ///\endcode
deba@2031
   441
  template <typename _BpUGraph>
deba@2031
   442
  class SwapBpUGraphAdaptor 
deba@2031
   443
    : public BpUGraphAdaptorExtender<SwapBpUGraphAdaptorBase<_BpUGraph> > { 
deba@2031
   444
  public:
deba@2031
   445
deba@2031
   446
    typedef _BpUGraph Graph;
deba@2031
   447
    typedef BpUGraphAdaptorExtender<SwapBpUGraphAdaptorBase<_BpUGraph> > 
deba@2031
   448
    Parent;
deba@2031
   449
deba@2031
   450
  protected:
deba@2031
   451
    SwapBpUGraphAdaptor() : Parent() {}
deba@2031
   452
deba@2031
   453
  public:
deba@2031
   454
deba@2084
   455
    /// \brief Construct a swapped graph.
deba@2084
   456
    ///
deba@2084
   457
    /// Construct a swapped graph.
deba@2031
   458
    explicit SwapBpUGraphAdaptor(Graph& _graph) { setGraph(_graph); }
deba@2031
   459
deba@2031
   460
  };
deba@2031
   461
deba@2031
   462
deba@2040
   463
  template <typename _BpUGraph, 
deba@2040
   464
            typename _ANMatchingMap, typename _BNMatchingMap>
deba@2040
   465
  class MatchingBpUGraphAdaptorBase 
deba@2040
   466
    : public BpUGraphAdaptorBase<const _BpUGraph>
deba@2040
   467
  {
deba@2040
   468
  public:
deba@2040
   469
    
deba@2040
   470
    typedef _BpUGraph Graph;
deba@2040
   471
    typedef _ANMatchingMap ANodeMatchingMap;
deba@2040
   472
    typedef _BNMatchingMap BNodeMatchingMap;
deba@2040
   473
deba@2040
   474
    typedef BpUGraphAdaptorBase<const _BpUGraph> Parent;
deba@2040
   475
deba@2040
   476
  protected:
deba@2040
   477
    
deba@2040
   478
    MatchingBpUGraphAdaptorBase() {}
deba@2040
   479
deba@2040
   480
    void setANodeMatchingMap(ANodeMatchingMap& _anode_matching) {
deba@2040
   481
      anode_matching = &_anode_matching;
deba@2040
   482
    }
deba@2040
   483
deba@2040
   484
    void setBNodeMatchingMap(BNodeMatchingMap& _bnode_matching) {
deba@2040
   485
      bnode_matching = &_bnode_matching;
deba@2040
   486
    }
deba@2040
   487
deba@2040
   488
  public:
deba@2040
   489
deba@2040
   490
    typedef typename Parent::Node Node;
deba@2040
   491
    typedef typename Parent::Edge Edge;
deba@2040
   492
deba@2040
   493
    void firstOut(Edge& edge, const Node& node) const {
deba@2040
   494
      if (Parent::aNode(node)) {
deba@2040
   495
        Parent::firstOut(edge, node);
deba@2040
   496
        if (edge != INVALID && (*anode_matching)[node] == edge) {
deba@2040
   497
          Parent::nextOut(edge);
deba@2040
   498
        }
deba@2040
   499
      } else {
deba@2040
   500
        edge = (*bnode_matching)[node] != INVALID ?
deba@2040
   501
          Parent::direct((*bnode_matching)[node], false) : INVALID;
deba@2040
   502
      }
deba@2040
   503
    }
deba@2040
   504
deba@2040
   505
    void nextOut(Edge& edge) const {
deba@2040
   506
      if (Parent::aNode(Parent::source(edge))) {
deba@2040
   507
        Parent::nextOut(edge);
deba@2040
   508
        if (edge != INVALID && (*anode_matching)[Parent::aNode(edge)] == edge) {
deba@2040
   509
          Parent::nextOut(edge);
deba@2040
   510
        }
deba@2040
   511
      } else {
deba@2040
   512
        edge = INVALID;
deba@2040
   513
      }
deba@2040
   514
    }
deba@2040
   515
 
deba@2040
   516
    void firstIn(Edge& edge, const Node& node) const {
deba@2040
   517
      if (Parent::aNode(node)) {
deba@2040
   518
        edge = (*bnode_matching)[node] != INVALID ?
deba@2040
   519
          Parent::direct((*anode_matching)[node], false) : INVALID;
deba@2040
   520
      } else {
deba@2040
   521
        Parent::firstIn(edge, node);
deba@2040
   522
        if (edge != INVALID && (*bnode_matching)[node] == edge) {
deba@2040
   523
          Parent::nextIn(edge);
deba@2040
   524
        }
deba@2040
   525
      }
deba@2040
   526
    }
deba@2040
   527
deba@2040
   528
    void nextIn(Edge& edge) const {
deba@2040
   529
      if (Parent::aNode(Parent::target(edge))) {
deba@2040
   530
        edge = INVALID;
deba@2040
   531
      } else {
deba@2040
   532
        Parent::nextIn(edge);
deba@2040
   533
        if (edge != INVALID && (*bnode_matching)[Parent::bNode(edge)] == edge) {
deba@2040
   534
          Parent::nextIn(edge);
deba@2040
   535
        }
deba@2040
   536
      }
deba@2040
   537
    } 
deba@2040
   538
deba@2040
   539
  private:
deba@2040
   540
    ANodeMatchingMap* anode_matching;
deba@2040
   541
    BNodeMatchingMap* bnode_matching;
deba@2040
   542
  };
deba@2040
   543
deba@2040
   544
deba@2040
   545
  /// \ingroup graph_adaptors
deba@2040
   546
  ///
deba@2040
   547
  /// \brief Bipartite graph adaptor to implement matching algorithms.
deba@2040
   548
  ///
deba@2040
   549
  /// Bipartite graph adaptor to implement matchings. It implements
deba@2040
   550
  /// the residual graph of the matching.
deba@2040
   551
  template <typename _BpUGraph, 
deba@2040
   552
            typename _ANMatchingMap, typename _BNMatchingMap>
deba@2040
   553
  class MatchingBpUGraphAdaptor 
deba@2040
   554
    : public BpUGraphAdaptorExtender<
deba@2040
   555
    MatchingBpUGraphAdaptorBase<_BpUGraph, _ANMatchingMap, _BNMatchingMap> > 
deba@2040
   556
  { 
deba@2040
   557
  public:
deba@2040
   558
deba@2040
   559
    typedef _BpUGraph BpUGraph;
deba@2040
   560
    typedef _BpUGraph Graph;
deba@2040
   561
    typedef _ANMatchingMap ANodeMatchingMap;
deba@2040
   562
    typedef _BNMatchingMap BNodeMatchingMap;
deba@2040
   563
    typedef BpUGraphAdaptorExtender<
deba@2040
   564
      MatchingBpUGraphAdaptorBase<BpUGraph, 
deba@2040
   565
                                  ANodeMatchingMap, BNodeMatchingMap> > 
deba@2040
   566
    Parent;
deba@2040
   567
deba@2040
   568
  protected:
deba@2040
   569
    MatchingBpUGraphAdaptor() : Parent() {}
deba@2040
   570
deba@2040
   571
  public:
deba@2040
   572
deba@2040
   573
    MatchingBpUGraphAdaptor(const Graph& _graph, 
deba@2040
   574
                            ANodeMatchingMap& _anode_matching,
deba@2040
   575
                            BNodeMatchingMap& _bnode_matching) {
deba@2040
   576
      setGraph(_graph);
deba@2040
   577
      setANodeMatchingMap(_anode_matching);
deba@2040
   578
      setBNodeMatchingMap(_bnode_matching);
deba@2040
   579
    }
deba@2040
   580
deba@2040
   581
  };
deba@2040
   582
deba@2031
   583
}
deba@2031
   584
deba@2031
   585
#endif