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