src/work/marci/bipartite_graph_wrapper.h
author deba
Wed, 08 Sep 2004 12:06:45 +0000 (2004-09-08)
changeset 822 88226d9fe821
parent 762 511200bdb71f
child 902 309d81806228
permissions -rw-r--r--
The MapFactories have been removed from the code because
if we use macros then they increases only the complexity.

The pair iterators of the maps are separeted from the maps.

Some macros and comments has been changed.
     1 // -*- c++ -*-
     2 #ifndef HUGO_BIPARTITE_GRAPH_WRAPPER_H
     3 #define HUGO_BIPARTITE_GRAPH_WRAPPER_H
     4 
     5 ///\ingroup gwrappers
     6 ///\file
     7 ///\brief Several graph wrappers.
     8 ///
     9 ///This file contains several useful graph wrapper functions.
    10 ///
    11 ///\author Marton Makai
    12 
    13 #include <hugo/invalid.h>
    14 #include <iter_map.h>
    15 #include <hugo/graph_wrapper.h>
    16 #include <for_each_macros.h>
    17 
    18 namespace hugo {
    19 
    20   /// \brief A wrapper for composing a bipartite graph from a graph 
    21   /// and from a node-map showing for any node which color class it belongs to.
    22   ///
    23   /// A wrapper for composing a bipartite graph.
    24   /// \c _graph have to be a reference to a graph of type \c Graph 
    25   /// and \c _s_false_t_true_map is an \c IterableBoolMap 
    26   /// reference containing the elements for the 
    27   /// color classes S and T. \c _graph is to be referred to an undirected 
    28   /// graph or a directed graph with edges oriented from S to T.
    29   ///
    30   /// \author Marton Makai
    31   template<typename Graph> 
    32   class BipartiteGraphWrapper : public GraphWrapper<Graph> {
    33   public:
    34     typedef IterableBoolMap< typename Graph::template NodeMap<int> > 
    35     SFalseTTrueMap;
    36   protected:
    37     SFalseTTrueMap* s_false_t_true_map;
    38 
    39     BipartiteGraphWrapper() : GraphWrapper<Graph>()/*, 
    40 						     S_CLASS(false), T_CLASS(true)*/ { }
    41     void setSFalseTTrueMap(SFalseTTrueMap& _s_false_t_true_map) { 
    42       s_false_t_true_map=&_s_false_t_true_map;
    43     }
    44 
    45   public:
    46     //marci
    47     //FIXME vhogy igy kellene, csak az en forditom nem eszi meg
    48     static const bool S_CLASS;
    49     static const bool T_CLASS;
    50 
    51     /// This method is to reach the iterable maps of the bipartite graph or 
    52     /// bipartite graph wrapper.
    53     const SFalseTTrueMap& sFalseTTrueMap() const { 
    54       return *s_false_t_true_map; 
    55     }
    56     
    57     //bool S_CLASS;
    58     //bool T_CLASS;
    59 
    60     BipartiteGraphWrapper(Graph& _graph, SFalseTTrueMap& _s_false_t_true_map) 
    61       : GraphWrapper<Graph>(_graph), 
    62 	s_false_t_true_map(&_s_false_t_true_map)/*, 
    63 						  S_CLASS(false), T_CLASS(true)*/ { }
    64     typedef typename GraphWrapper<Graph>::Node Node;
    65     //using GraphWrapper<Graph>::NodeIt;
    66     typedef typename GraphWrapper<Graph>::Edge Edge;
    67     //using GraphWrapper<Graph>::EdgeIt;
    68     class ClassNodeIt;
    69     friend class ClassNodeIt;
    70     class OutEdgeIt;
    71     friend class OutEdgeIt;
    72     class InEdgeIt;
    73     friend class InEdgeIt;
    74     class ClassNodeIt {
    75       friend class BipartiteGraphWrapper<Graph>;
    76     protected:
    77       Node n;
    78     public:
    79       ClassNodeIt() { }
    80       ClassNodeIt(const Invalid& i) : n(i) { }
    81       ClassNodeIt(const BipartiteGraphWrapper<Graph>& _G, bool _class) { 
    82 	_G.s_false_t_true_map->first(n, _class); 
    83       }
    84       //FIXME needed in new concept, important here
    85       ClassNodeIt(const Node& _n) : n(_n) { }
    86       operator Node() const { return n; }
    87     };
    88 //     class SNodeIt {
    89 //       Node n;
    90 //     public:
    91 //       SNodeIt() { }
    92 //       SNodeIt(const Invalid& i) : n(i) { }
    93 //       SNodeIt(const BipartiteGraphWrapper<Graph>& _G) { 
    94 // 	_G.s_false_t_true_map->first(n, false); 
    95 //       }
    96 //       operator Node() const { return n; }
    97 //     };
    98 //     class TNodeIt {
    99 //       Node n;
   100 //     public:
   101 //       TNodeIt() { }
   102 //       TNodeIt(const Invalid& i) : n(i) { }
   103 //       TNodeIt(const BipartiteGraphWrapper<Graph>& _G) { 
   104 // 	_G.s_false_t_true_map->first(n, true); 
   105 //       }
   106 //       operator Node() const { return n; }
   107 //     };
   108     class OutEdgeIt { 
   109       friend class BipartiteGraphWrapper<Graph>;
   110     protected:
   111       typename Graph::OutEdgeIt e;
   112     public:
   113       OutEdgeIt() { }
   114       OutEdgeIt(const Invalid& i) : e(i) { }
   115       OutEdgeIt(const BipartiteGraphWrapper<Graph>& _G, const Node& _n) {
   116 	if (!(*(_G.s_false_t_true_map))[_n]) 
   117 	  e=typename Graph::OutEdgeIt(*(_G.graph), typename Graph::Node(_n));
   118 	else 
   119 	  e=INVALID;
   120       }
   121       operator Edge() const { return Edge(typename Graph::Edge(e)); }
   122     };
   123     class InEdgeIt { 
   124       friend class BipartiteGraphWrapper<Graph>;
   125     protected:
   126       typename Graph::InEdgeIt e;
   127     public:
   128       InEdgeIt() { }
   129       InEdgeIt(const Invalid& i) : e(i) { }
   130       InEdgeIt(const BipartiteGraphWrapper<Graph>& _G, const Node& _n) {
   131 	if ((*(_G.s_false_t_true_map))[_n]) 
   132 	  e=typename Graph::InEdgeIt(*(_G.graph), typename Graph::Node(_n));
   133 	else 
   134 	  e=INVALID;
   135       }
   136       operator Edge() const { return Edge(typename Graph::Edge(e)); }
   137     };
   138 
   139     using GraphWrapper<Graph>::first;
   140     ClassNodeIt& first(ClassNodeIt& n, bool _class) const { 
   141       n=ClassNodeIt(*this, _class) ; return n; }
   142 //    SNodeIt& first(SNodeIt& n) const { n=SNodeIt(*this); return n; }
   143 //    TNodeIt& first(TNodeIt& n) const { n=TNodeIt(*this); return n; }
   144     OutEdgeIt& first(OutEdgeIt& i, const Node& p) const { 
   145       i=OutEdgeIt(*this, p); return i;
   146     }
   147     InEdgeIt& first(InEdgeIt& i, const Node& p) const { 
   148       i=InEdgeIt(*this, p); return i;
   149     }
   150 
   151     using GraphWrapper<Graph>::next;
   152     ClassNodeIt& next(ClassNodeIt& n) const { 
   153       this->s_false_t_true_map->next(n.n); return n; 
   154     }
   155 //     SNodeIt& next(SNodeIt& n) const { 
   156 //       this->s_false_t_true_map->next(n); return n; 
   157 //     }
   158 //     TNodeIt& next(TNodeIt& n) const { 
   159 //       this->s_false_t_true_map->next(n); return n; 
   160 //     }
   161     OutEdgeIt& next(OutEdgeIt& i) const { this->graph->next(i.e); return i; }
   162     InEdgeIt& next(InEdgeIt& i) const { this->graph->next(i.e); return i; }
   163 
   164     Node tail(const Edge& e) { 
   165       if (!(*(this->s_false_t_true_map))[this->graph->tail(e)]) 
   166 	return Node(this->graph->tail(e));
   167       else
   168 	return Node(this->graph->head(e));	
   169     }
   170     Node head(const Edge& e) { 
   171       if (!(*(this->s_false_t_true_map))[this->graph->tail(e)]) 
   172 	return Node(this->graph->head(e));
   173       else
   174 	return Node(this->graph->tail(e));	
   175     }
   176 
   177     Node aNode(const OutEdgeIt& e) const { 
   178       return Node(this->graph->aNode(e.e)); 
   179     }
   180     Node aNode(const InEdgeIt& e) const { 
   181       return Node(this->graph->aNode(e.e)); 
   182     }
   183     Node bNode(const OutEdgeIt& e) const { 
   184       return Node(this->graph->bNode(e.e)); 
   185     }
   186     Node bNode(const InEdgeIt& e) const { 
   187       return Node(this->graph->bNode(e.e)); 
   188     }
   189 
   190     /// Returns true iff \c n is in S.
   191     bool inSClass(const Node& n) const {
   192       return !(*(this->s_false_t_true_map))[n];
   193     }
   194 
   195     /// Returns true iff \c n is in T.
   196     bool inTClass(const Node& n) const {
   197       return (*(this->s_false_t_true_map))[n];
   198     }
   199   };
   200 
   201 
   202   template<typename G>
   203   const bool BipartiteGraphWrapper<G>::S_CLASS=false;
   204   template<typename G>
   205   const bool BipartiteGraphWrapper<G>::T_CLASS=true;
   206 
   207   /// \brief A bipartite graph template class
   208   ///
   209   /// This class composes a bipartite graph over a directed or undirected 
   210   /// graph structure of type \c Graph.
   211   /// \c _graph have to be a reference to a graph of type \c Graph 
   212   /// and \c _s_false_t_true_map is an \c IterableBoolMap 
   213   /// reference containing the elements for the 
   214   /// color classes S and T. \c _graph is to be referred to an undirected 
   215   /// graph or a directed graph with edges oriented from S to T.
   216   ///
   217   ///\bug experimental. Do not use this while the bipartitemap augmentation 
   218   /// does not work well.
   219   template<typename Graph>
   220   class BipartiteGraph : public BipartiteGraphWrapper<Graph> {
   221 //     typedef IterableBoolMap< typename Graph::template NodeMap<int> > 
   222 //     SFalseTTrueMap;
   223     typedef BipartiteGraphWrapper<Graph> Parent;
   224   protected:
   225     Graph gr;
   226     typename Graph::template NodeMap<int> bipartite_map;
   227     typename Parent::SFalseTTrueMap s_false_t_true_map;
   228   public:
   229     typedef typename Parent::Node Node;
   230     typedef typename Parent::Edge Edge;
   231     BipartiteGraph() : BipartiteGraphWrapper<Graph>(), 
   232 		       gr(), bipartite_map(gr, -1), 
   233 		       s_false_t_true_map(bipartite_map) { 
   234       Parent::setGraph(gr); 
   235       Parent::setSFalseTTrueMap(s_false_t_true_map);
   236     }
   237 
   238     /// the \c bool parameter which can be \c S_Class or \c T_Class shows 
   239     /// the color class where the new node is to be inserted.
   240     Node addNode(bool b) {
   241       Node n=Parent::graph->addNode();
   242       bipartite_map.update();
   243       //bipartite_map.set(n, -1);
   244       s_false_t_true_map.insert(n, b);
   245       return n;
   246     }
   247 
   248     /// A new edge is inserted.
   249     ///\pre \c tail have to be in \c S_Class and \c head in \c T_Class.
   250     Edge addEdge(const Node& tail, const Node& head) {
   251       return Parent::graph->addEdge(tail, head);
   252     }
   253 
   254     void erase(const Node& n) {
   255       s_false_t_true_map.remove(n);
   256       Parent::graph->erase(n);
   257     }
   258     void erase(const Edge& e) {
   259       Parent::graph->erase(e);
   260     }
   261     
   262     void clear() {
   263       FOR_EACH_LOC(typename Parent::EdgeIt, e, *this) erase(e);
   264       FOR_EACH_LOC(typename Parent::NodeIt, n, *this) erase(n);
   265     }
   266   };
   267 
   268   template<typename Graph, typename sIterableMap, typename tIterableMap>
   269   class stGraphWrapper;
   270 
   271   /// Easier stuff for bipartite graphs.
   272   template<typename Graph>
   273   class stBipartiteGraphWrapper : public 
   274   stGraphWrapper<Graph, typename Graph::SFalseTTrueMap, 
   275 		 typename Graph::SFalseTTrueMap> {
   276   public:
   277     typedef stGraphWrapper<Graph, typename Graph::SFalseTTrueMap, 
   278 			   typename Graph::SFalseTTrueMap> Parent;
   279     stBipartiteGraphWrapper(Graph& _graph) : 
   280       Parent(_graph, _graph.sFalseTTrueMap(), _graph.sFalseTTrueMap()) { }
   281   };
   282 
   283 //   template<typename Graph> 
   284 //   std::ostream& 
   285 //   operator<<(std::ostream& os, const typename stGraphWrapper<Graph>::Node& i) { 
   286 //     os << "(node: " << typename Graph::Node(i) << " spec: " << i.spec <<")"; 
   287 //     return os; 
   288 //   }
   289 //   template<typename Graph> 
   290 //   std::ostream& 
   291 //   operator<<(std::ostream& os, const typename stGraphWrapper<Graph>::Edge& i) { 
   292 //     os << "(edge: " << typename Graph::Edge(i) << " spec: " << i.spec << 
   293 //       " node: " << i.n << ")"; 
   294 //     return os; 
   295 //   }
   296 
   297   /// \brief A wrapper for adding extra nodes s and t to a bipartite graph
   298   /// and edges from s to each node of S and form each node of T to t.
   299   /// 
   300   /// A wrapper for adding extra nodes s and t to a bipartite graph
   301   /// and edges from s to each node of S and form each node of T to t.
   302   /// This class is very useful to reduce some matching or more
   303   /// generally, capacitataed b-matching problem to a flow problem.
   304   /// According to the bipartite graph concepts the bipartite 
   305   /// graph have to be oriented from S to T.
   306   ///
   307   /// \author Marton Makai
   308   template<typename Graph, typename sIterableMap, typename tIterableMap>
   309   class stGraphWrapper : public GraphWrapper<Graph> {
   310   protected:    
   311     const sIterableMap* s_iterable_map;
   312     const tIterableMap* t_iterable_map;
   313   public:
   314     class Node; 
   315     friend class Node;
   316 //GN, int
   317 //0 normalis, 1 s, 2 t, ez az iteralasi sorrend, 
   318 //es a vege a false azaz (invalid, 3)    
   319     class NodeIt;
   320     friend class NodeIt;
   321 //GNI, int
   322     class Edge;
   323     friend class Edge;
   324 //GE, int, GN
   325 //0 normalis, 1 s->vmi, 2 vmi->t, ez a sorrend,
   326 //invalid: (invalid, 3, invalid)
   327     class OutEdgeIt;
   328     friend class OutEdgeIt;
   329 //GO, int, GNI
   330 //normalis pontbol (first, 0, invalid), ..., (invalid, 2, vmi), ... (invalid, 3, invalid)
   331 //s-bol (invalid, 1, first), ... (invalid, 3, invalid)
   332 //t-bol (invalid, 3, invalid)
   333     class InEdgeIt;
   334     friend class InEdgeIt;
   335 //GI, int, GNI
   336 //normalis pontbol (first, 0, invalid), ..., (invalid, 1, vmi), ... (invalid, 3, invalid)
   337 //s-be (invalid, 3, invalid)
   338 //t-be (invalid, 2, first), ... (invalid, 3, invalid)
   339     class EdgeIt;
   340     friend class EdgeIt;
   341 //(first, 0, invalid) ...
   342 //(invalid, 1, vmi)
   343 //(invalid, 2, vmi)
   344 //invalid, 3, invalid)
   345     template <typename T> class NodeMap;
   346     template <typename T> class EdgeMap;
   347 
   348 //    template <typename T> friend class NodeMap;
   349 //    template <typename T> friend class EdgeMap;
   350 
   351     ///\todo FIXME ezt majd static-ra kell javitani
   352     const Node S_NODE;
   353     const Node T_NODE;
   354 
   355     static const bool S_CLASS=false;
   356     static const bool T_CLASS=true;
   357 
   358     // \bug not too nice constructor.
   359     stGraphWrapper(Graph& _graph, 
   360 		   const sIterableMap& _s_iterable_map, 
   361 		   const tIterableMap& _t_iterable_map) : 
   362       GraphWrapper<Graph>(_graph), 
   363       s_iterable_map(&_s_iterable_map), 
   364       t_iterable_map(&_t_iterable_map), 
   365       S_NODE(INVALID, 1), 
   366       T_NODE(INVALID, 2) { }
   367 
   368     
   369 //    std::ostream& 
   370 //    operator<<(std::ostream& os, const /*typename stGraphWrapper<Graph>::*/Node& i);
   371 //    friend std::ostream& 
   372 //    operator<<(std::ostream& os, const /*typename stGraphWrapper<Graph>::*/Node& i);
   373 //    friend std::ostream& 
   374 //    operator<<(std::ostream& os, const /*typename stGraphWrapper<Graph>::*/Edge& i);
   375 
   376     class Node : public Graph::Node {
   377     protected:
   378       friend class GraphWrapper<Graph>;
   379       friend class stGraphWrapper<Graph, sIterableMap, tIterableMap>;
   380       template <typename T> friend class NodeMap;
   381       friend class Edge;
   382       friend class OutEdgeIt;
   383       friend class InEdgeIt;
   384       friend class EdgeIt;
   385       int spec; 
   386     public:
   387       Node() { }
   388       Node(const typename Graph::Node& _n, int _spec=0) : 
   389 	Graph::Node(_n), spec(_spec) { }
   390       Node(const Invalid& i) : Graph::Node(i), spec(3) { }
   391       friend bool operator==(const Node& u, const Node& v) { 
   392 	return (u.spec==v.spec && 
   393 		static_cast<typename Graph::Node>(u)==
   394 		static_cast<typename Graph::Node>(v));
   395       } 
   396       friend bool operator!=(const Node& u, const Node& v) { 
   397 	return (v.spec!=u.spec || 
   398 		static_cast<typename Graph::Node>(u)!=
   399 		static_cast<typename Graph::Node>(v));
   400       }
   401 //      template<typename G> 
   402 //      friend std::ostream& 
   403 //      operator<<(std::ostream& os, const typename stGraphWrapper<G>::Node& i); 
   404       friend std::ostream& operator<< (std::ostream& os, const Node& i);
   405       int getSpec() const { return spec; }
   406     };
   407 
   408     class NodeIt { 
   409       friend class GraphWrapper<Graph>;
   410       friend class stGraphWrapper<Graph, sIterableMap, tIterableMap>;
   411       typename Graph::NodeIt n;
   412       int spec; 
   413      public:
   414       NodeIt() { }
   415       NodeIt(const typename Graph::NodeIt& _n, int _spec) : 
   416 	n(_n), spec(_spec) { }
   417       NodeIt(const Invalid& i) : n(i), spec(3) { }
   418       NodeIt(const stGraphWrapper<Graph, sIterableMap, tIterableMap>& _G) 
   419 	: n(*(_G.graph)), spec(0) { 
   420 	if (!_G.graph->valid(n)) spec=1;
   421       }
   422       operator Node() const { return Node(n, spec); }
   423     };
   424 
   425     class Edge : public Graph::Edge {
   426       friend class GraphWrapper<Graph>;
   427       friend class stGraphWrapper<Graph, sIterableMap, tIterableMap>;
   428       template <typename T> friend class EdgeMap;
   429       int spec;
   430       typename Graph::Node n;
   431     public:
   432       Edge() { }
   433       Edge(const typename Graph::Edge& _e, int _spec, 
   434 	   const typename Graph::Node& _n) : 
   435 	Graph::Edge(_e), spec(_spec), n(_n) { 
   436       }
   437       Edge(const Invalid& i) : Graph::Edge(i), spec(3), n(i) { }
   438       friend bool operator==(const Edge& u, const Edge& v) { 
   439 	return (u.spec==v.spec && 
   440 		static_cast<typename Graph::Edge>(u)==
   441 		static_cast<typename Graph::Edge>(v) && 
   442 		u.n==v.n);
   443       } 
   444       friend bool operator!=(const Edge& u, const Edge& v) { 
   445 	return (v.spec!=u.spec || 
   446 		static_cast<typename Graph::Edge>(u)!=
   447 		static_cast<typename Graph::Edge>(v) || 
   448 		u.n!=v.n);
   449       } 
   450 //      template<typename G> 
   451 //      friend std::ostream& 
   452 //      operator<<(std::ostream& os, const typename stGraphWrapper<G>::Edge& i); 
   453       friend std::ostream& operator<< (std::ostream& os, const Edge& i);
   454       int getSpec() const { return spec; }
   455       typename Graph::Node getNode() const { return n; }
   456     };
   457 
   458     class OutEdgeIt { 
   459       friend class GraphWrapper<Graph>;
   460       friend class stGraphWrapper<Graph, sIterableMap, tIterableMap>;
   461       typename Graph::OutEdgeIt e;
   462       int spec;
   463       typename Graph::ClassNodeIt n;
   464     public:
   465       OutEdgeIt() { }
   466       OutEdgeIt(const typename Graph::OutEdgeIt& _e, int _spec, 
   467 		const typename Graph::ClassNodeIt& _n) : 
   468 	e(_e), spec(_spec), n(_n) { 
   469       }
   470       OutEdgeIt(const Invalid& i) : e(i), spec(3), n(i) { }
   471       OutEdgeIt(const stGraphWrapper<Graph, sIterableMap, tIterableMap>& _G, 
   472 		const Node& _n) {
   473 	switch (_n.spec) {
   474 	  case 0 : 
   475 	    if (_G.graph->inSClass(_n)) { //S, van normalis kiel 
   476 	      e=typename Graph::OutEdgeIt(*(_G.graph), 
   477 					  typename Graph::Node(_n)); 
   478 	      spec=0;
   479 	      n=INVALID;
   480 	      if (!_G.graph->valid(e)) spec=3;
   481 	    } else { //T, specko kiel van
   482 	      e=INVALID;
   483 	      spec=2;
   484 	      n=_n;
   485 	    }
   486 	    break;
   487 	  case 1:
   488 	    e=INVALID;
   489 	    spec=1;
   490 	    _G.graph->first(n, S_CLASS); //s->vmi;
   491 	    if (!_G.graph->valid(n)) spec=3; //Ha S ures
   492 	    break;
   493 	  case 2:
   494 	    e=INVALID;
   495 	    spec=3;
   496 	    n=INVALID;
   497 	    break;
   498 	}
   499       }
   500       operator Edge() const { return Edge(e, spec, n); }
   501     };
   502 
   503     class InEdgeIt { 
   504       friend class GraphWrapper<Graph>;
   505       friend class stGraphWrapper<Graph, sIterableMap, tIterableMap>;
   506       typename Graph::InEdgeIt e;
   507       int spec;
   508       typename Graph::ClassNodeIt n;
   509     public:
   510       InEdgeIt() { }
   511       InEdgeIt(const typename Graph::InEdgeIt& _e, int _spec, 
   512 	       const typename Graph::ClassNodeIt& _n) : 
   513 	e(_e), spec(_spec), n(_n) { 
   514       }
   515       InEdgeIt(const Invalid& i) : e(i), spec(3), n(i) { }
   516       InEdgeIt(const stGraphWrapper<Graph, sIterableMap, tIterableMap>& _G, 
   517 	       const Node& _n) {
   518 	switch (_n.spec) {
   519 	  case 0 : 
   520 	    if (_G.graph->inTClass(_n)) { //T, van normalis beel 
   521 	      e=typename Graph::InEdgeIt(*(_G.graph), 
   522 					 typename Graph::Node(_n)); 
   523 	      spec=0;
   524 	      n=INVALID;
   525 	      if (!_G.graph->valid(e)) spec=3;
   526 	    } else { //S, specko beel van
   527 	      e=INVALID;
   528 	      spec=1;
   529 	      n=_n;
   530 	    }
   531 	    break;
   532 	  case 1:
   533 	    e=INVALID;
   534 	    spec=3;
   535 	    n=INVALID;
   536 	    break;
   537 	  case 2:
   538 	    e=INVALID;
   539 	    spec=2;
   540 	    _G.graph->first(n, T_CLASS); //vmi->t;
   541 	    if (!_G.graph->valid(n)) spec=3; //Ha T ures
   542 	    break;
   543 	}
   544       }
   545       operator Edge() const { return Edge(e, spec, n); }
   546     };
   547 
   548     class EdgeIt { 
   549       friend class GraphWrapper<Graph>;
   550       friend class stGraphWrapper<Graph, sIterableMap, tIterableMap>;
   551       typename Graph::EdgeIt e;
   552       int spec;
   553       typename Graph::ClassNodeIt n;
   554     public:
   555       EdgeIt() { }
   556       EdgeIt(const typename Graph::EdgeIt& _e, int _spec, 
   557 	     const typename Graph::ClassNodeIt& _n) : 
   558 	e(_e), spec(_spec), n(_n) { }
   559       EdgeIt(const Invalid& i) : e(i), spec(3), n(i) { }
   560       EdgeIt(const stGraphWrapper<Graph, sIterableMap, tIterableMap>& _G) : 
   561 	e(*(_G.graph)), spec(0), n(INVALID) { 
   562 	if (!_G.graph->valid(e)) {
   563 	  spec=1;
   564 	  _G.graph->first(n, S_CLASS);
   565 	  if (!_G.graph->valid(n)) { //Ha S ures
   566 	    spec=2;
   567 	    _G.graph->first(n, T_CLASS);
   568 	    if (!_G.graph->valid(n)) { //Ha T ures
   569 	      spec=3;
   570 	    }
   571 	  }
   572 	}
   573       }
   574       operator Edge() const { return Edge(e, spec, n); }
   575     };
   576    
   577     NodeIt& first(NodeIt& i) const { 
   578       i=NodeIt(*this); return i;
   579     }
   580     OutEdgeIt& first(OutEdgeIt& i, const Node& p) const { 
   581       i=OutEdgeIt(*this, p); return i;
   582     }
   583     InEdgeIt& first(InEdgeIt& i, const Node& p) const { 
   584       i=InEdgeIt(*this, p); return i;
   585     }
   586     EdgeIt& first(EdgeIt& i) const { 
   587       i=EdgeIt(*this); return i;
   588     }
   589 
   590     NodeIt& next(NodeIt& i) const { 
   591       switch (i.spec) {
   592 	case 0:
   593 	  this->graph->next(i.n);
   594 	  if (!this->graph->valid(i.n)) {
   595 	    i.spec=1;
   596 	  }
   597 	  break;
   598 	case 1:
   599 	  i.spec=2;
   600 	  break;
   601 	case 2:
   602 	  i.spec=3;
   603 	  break;
   604       }
   605       return i; 
   606     }
   607     OutEdgeIt& next(OutEdgeIt& i) const { 
   608       typename Graph::Node v;
   609       switch (i.spec) {
   610 	case 0: //normal edge
   611 	  v=this->graph->aNode(i.e);
   612 	  this->graph->next(i.e);
   613 	  if (!this->graph->valid(i.e)) { //Az igazi elek vegere ertunk
   614 	    if (this->graph->inSClass(v)) { //S, nincs kiel
   615 	      i.spec=3;
   616 	      i.n=INVALID;
   617 	    } else { //T, van kiel
   618 	      i.spec=2; 
   619 	      i.n=v;
   620 	    }
   621 	  }
   622 	  break;
   623 	case 1: //s->vmi
   624 	  this->graph->next(i.n);
   625 	  if (!this->graph->valid(i.n)) i.spec=3;
   626 	  break;
   627 	case 2: //vmi->t
   628 	  i.spec=3;
   629 	  i.n=INVALID;
   630 	  break;
   631       }
   632       return i; 
   633     }
   634     InEdgeIt& next(InEdgeIt& i) const { 
   635       typename Graph::Node v;
   636       switch (i.spec) {
   637 	case 0: //normal edge
   638 	  v=this->graph->aNode(i.e);
   639 	  this->graph->next(i.e);
   640 	  if (!this->graph->valid(i.e)) { //Az igazi elek vegere ertunk
   641 	    if (this->graph->inTClass(v)) { //S, nincs beel
   642 	      i.spec=3;
   643 	      i.n=INVALID;
   644 	    } else { //S, van beel
   645 	      i.spec=1; 
   646 	      i.n=v;
   647 	    }
   648 	  }
   649 	  break;
   650 	case 1: //s->vmi
   651 	  i.spec=3;
   652 	  i.n=INVALID;
   653 	  break;
   654 	case 2: //vmi->t
   655 	  this->graph->next(i.n);
   656 	  if (!this->graph->valid(i.n)) i.spec=3;
   657 	  break;
   658       }
   659       return i; 
   660     }
   661 
   662     EdgeIt& next(EdgeIt& i) const { 
   663       switch (i.spec) {
   664 	case 0:
   665 	  this->graph->next(i.e);
   666 	  if (!this->graph->valid(i.e)) { 
   667 	    i.spec=1;
   668 	    this->graph->first(i.n, S_CLASS);
   669 	    if (!this->graph->valid(i.n)) {
   670 	      i.spec=2;
   671 	      this->graph->first(i.n, T_CLASS);
   672 	      if (!this->graph->valid(i.n)) i.spec=3;
   673 	    }
   674 	  }
   675 	  break;
   676 	case 1:
   677 	  this->graph->next(i.n);
   678 	  if (!this->graph->valid(i.n)) {
   679 	    i.spec=2;
   680 	    this->graph->first(i.n, T_CLASS);
   681 	    if (!this->graph->valid(i.n)) i.spec=3;
   682 	  }
   683 	  break;
   684 	case 2:
   685 	  this->graph->next(i.n);
   686 	  if (!this->graph->valid(i.n)) i.spec=3;
   687 	  break;
   688       }
   689       return i; 
   690     }    
   691 
   692     Node tail(const Edge& e) const { 
   693       switch (e.spec) {
   694       case 0: 
   695 	return Node(this->graph->tail(e));
   696 	break;
   697       case 1:
   698 	return S_NODE;
   699 	break;
   700       case 2:
   701       default:
   702 	return Node(e.n);
   703 	break;
   704       }
   705     }
   706     Node head(const Edge& e) const { 
   707       switch (e.spec) {
   708       case 0: 
   709 	return Node(this->graph->head(e));
   710 	break;
   711       case 1:
   712 	return Node(e.n);
   713 	break;
   714       case 2:
   715       default:
   716 	return T_NODE;
   717 	break;
   718       }
   719     }
   720 
   721     bool valid(const Node& n) const { return (n.spec<3); }
   722     bool valid(const Edge& e) const { return (e.spec<3); }
   723 
   724     int nodeNum() const { return this->graph->nodeNum()+2; }
   725     int edgeNum() const { 
   726       return this->graph->edgeNum()+this->graph->nodeNum(); 
   727     }
   728   
   729     Node aNode(const OutEdgeIt& e) const { return tail(e); }
   730     Node aNode(const InEdgeIt& e) const { return head(e); }
   731     Node bNode(const OutEdgeIt& e) const { return head(e); }
   732     Node bNode(const InEdgeIt& e) const { return tail(e); }
   733 
   734     void addNode() const { }
   735     void addEdge() const { }
   736     
   737 //    Node addNode() const { return Node(this->graph->addNode()); }
   738 //    Edge addEdge(const Node& tail, const Node& head) const { 
   739 //      return Edge(this->graph->addEdge(tail, head)); }
   740 
   741 //    void erase(const Node& i) const { this->graph->erase(i); }
   742 //    void erase(const Edge& i) const { this->graph->erase(i); }
   743   
   744 //    void clear() const { this->graph->clear(); }
   745     
   746     template<typename T> class NodeMap : public GraphWrapper<Graph>::template NodeMap<T> { 
   747       typedef typename GraphWrapper<Graph>::template NodeMap<T> Parent;
   748     protected:
   749       T s_value, t_value;
   750     public:
   751       NodeMap(const stGraphWrapper<Graph, sIterableMap, tIterableMap>& _G) : 
   752 	Parent(_G), 
   753 	s_value(), 
   754 	t_value() { }
   755       NodeMap(const stGraphWrapper<Graph, sIterableMap, tIterableMap>& _G, T a) 
   756 	: Parent(_G, a), 
   757 	  s_value(a), 
   758 	  t_value(a) { }
   759       T operator[](const Node& n) const { 
   760 	switch (n.spec) {
   761 	case 0: 
   762 	  return Parent::operator[](n);
   763 	case 1:
   764 	  return s_value;
   765 	case 2: 
   766 	default:
   767 	  return t_value;
   768 	}
   769       }
   770       void set(const Node& n, T t) { 
   771 	switch (n.spec) {
   772 	case 0: 
   773 	  GraphWrapper<Graph>::template NodeMap<T>::set(n, t);
   774 	  break;
   775 	case 1:
   776 	  s_value=t;
   777 	  break;
   778 	case 2:
   779 	default:
   780 	  t_value=t;
   781 	  break;
   782 	}
   783       }
   784     };
   785 
   786     /// This class is to wrap a node-map of \c Graph and two variables 
   787     /// storing values for \c S_NODE and \c T_NODE to a node-map of 
   788     /// stGraphWrapper<Graph, sIterableMap, tIterableMap>.
   789     template<typename NM> class NodeMapWrapper { 
   790     public:
   791       typedef Node KeyType;
   792       typedef typename NM::ValueType ValueType;
   793     protected:
   794       NM* nm;
   795       ValueType* s_value, t_value;
   796     public:
   797       NodeMapWrapper(NM& _nm, ValueType& _s_value, ValueType& _t_value) : 
   798 	nm(&_nm), s_value(&_s_value), t_value(&_t_value) { }
   799       ValueType operator[](const Node& n) const { 
   800 	switch (n.getSpec()) {
   801 	case 0: 
   802 	  return (*nm)[n];
   803 	case 1:
   804 	  return *s_value;
   805 	case 2: 
   806 	default:
   807 	  return *t_value;
   808 	}
   809       }
   810       void set(const Node& n, ValueType t) { 
   811 	switch (n.getSpec()) {
   812 	case 0: 
   813 	  nm->set(n, t);
   814 	  break;
   815 	case 1:
   816 	  *s_value=t;
   817 	  break;
   818 	case 2:
   819 	default:
   820 	  *t_value=t;
   821 	  break;
   822 	}
   823       }
   824     };
   825 
   826     template<typename T> 
   827     class EdgeMap : public GraphWrapper<Graph>::template EdgeMap<T> { 
   828       typedef typename GraphWrapper<Graph>::template EdgeMap<T> Parent;
   829     protected:
   830       typename GraphWrapper<Graph>::template NodeMap<T> node_value;
   831     public:
   832       EdgeMap(const stGraphWrapper<Graph, sIterableMap, tIterableMap>& _G) 
   833 	: Parent(_G), 
   834 	  node_value(_G) { }
   835       EdgeMap(const stGraphWrapper<Graph, sIterableMap, tIterableMap>& _G, T a) 
   836 	: Parent(_G, a), 
   837 	  node_value(_G, a) { }
   838       T operator[](const Edge& e) const { 
   839 	switch (e.spec) {
   840 	case 0: 
   841 	  return Parent::operator[](e);
   842 	case 1:
   843 	  return node_value[e.n];
   844 	case 2:
   845 	default:
   846 	  return node_value[e.n];
   847 	}
   848       }
   849       void set(const Edge& e, T t) { 
   850 	switch (e.spec) {
   851 	case 0: 
   852 	  Parent::set(e, t);
   853 	  break;
   854 	case 1:
   855 	  node_value.set(e.n, t);
   856 	  break;
   857 	case 2:
   858 	default:
   859 	  node_value.set(e.n, t);
   860 	  break;
   861 	}
   862       }
   863     };
   864 
   865     /// This class is to wrap an edge-map and a node-map of \c Graph 
   866     /// to an edge-map of stGraphWrapper<Graph, sIterableMap, tIterableMap>.
   867     template<typename EM, typename NM> 
   868     class EdgeMapWrapper {
   869     public: 
   870       typedef Edge KeyType;
   871       typedef typename EM::ValueType ValueType;
   872     protected:
   873       EM* em;
   874       NM* nm;
   875     public:
   876       EdgeMapWrapper(EM& _em, NM& _nm) : em(&_em), nm(&_nm) { }
   877       ValueType operator[](const Edge& e) const { 
   878 	switch (e.getSpec()) {
   879 	case 0: 
   880 	  return (*em)[e];
   881 	case 1:
   882 	  return (*nm)[e.getNode()];
   883 	case 2:
   884 	default:
   885 	  return (*nm)[e.getNode()];
   886 	}
   887       }
   888       void set(const Edge& e, ValueType t) { 
   889 	switch (e.getSpec()) {
   890 	case 0: 
   891 	  em->set(e, t);
   892 	  break;
   893 	case 1:
   894 	  nm->set(e.getNode(), t);
   895 	  break;
   896 	case 2:
   897 	default:
   898 	  nm->set(e.getNode(), t);
   899 	  break;
   900 	}
   901       }
   902     };
   903 
   904 
   905 //  template<typename G> 
   906     friend std::ostream& 
   907     operator<<(std::ostream& os, const /*typename stGraphWrapper<Graph>::*/Node& i) { 
   908       os << "(node: " << typename Graph::Node(i) << " spec: " << i.spec <<")"; 
   909       return os; 
   910     }
   911 //  template<typename G> 
   912     friend std::ostream& 
   913     operator<<(std::ostream& os, const /*typename stGraphWrapper<Graph>::*/Edge& i) { 
   914       os << "(edge: " << typename Graph::Edge(i) << " spec: " << i.spec << 
   915 	" node: " << i.n << ")"; 
   916       return os; 
   917     }
   918 
   919   };
   920 
   921   ///@}
   922 
   923 } //namespace hugo
   924 
   925 
   926 #endif //HUGO_BIPARTITE_GRAPH_WRAPPER_H
   927