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