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