src/work/marci/oldies/bfs_iterator.hh
author alpar
Thu, 31 Mar 2005 14:04:13 +0000
changeset 1284 b941d044f87b
permissions -rw-r--r--
SmartGraph can also split() a node!
marci@280
     1
#ifndef BFS_ITERATOR_HH
marci@280
     2
#define BFS_ITERATOR_HH
marci@280
     3
marci@280
     4
#include <queue>
marci@280
     5
#include <stack>
marci@280
     6
#include <utility>
marci@280
     7
#include <graph_wrapper.h>
marci@280
     8
marci@280
     9
namespace hugo {
marci@280
    10
marci@280
    11
  template <typename Graph>
marci@280
    12
  struct bfs {
marci@280
    13
    typedef typename Graph::NodeIt NodeIt;
marci@280
    14
    typedef typename Graph::EdgeIt EdgeIt;
marci@280
    15
    typedef typename Graph::EachNodeIt EachNodeIt;
marci@280
    16
    typedef typename Graph::OutEdgeIt OutEdgeIt;
marci@280
    17
    Graph& G;
marci@280
    18
    NodeIt s;
marci@280
    19
    typename Graph::NodeMap<bool> reached;
marci@280
    20
    typename Graph::NodeMap<EdgeIt> pred;
marci@280
    21
    typename Graph::NodeMap<int> dist;
marci@280
    22
    std::queue<NodeIt> bfs_queue;
marci@280
    23
    bfs(Graph& _G, NodeIt _s) : G(_G), s(_s), reached(_G), pred(_G), dist(_G) { 
marci@280
    24
      bfs_queue.push(s); 
marci@280
    25
      for(EachNodeIt i=G.template first<EachNodeIt>(); i.valid(); ++i) 
marci@280
    26
	reached.set(i, false);
marci@280
    27
      reached.set(s, true);
marci@280
    28
      dist.set(s, 0); 
marci@280
    29
    }
marci@280
    30
    
marci@280
    31
    void run() {
marci@280
    32
      while (!bfs_queue.empty()) {
marci@280
    33
	NodeIt v=bfs_queue.front();
marci@280
    34
	OutEdgeIt e=G.template first<OutEdgeIt>(v);
marci@280
    35
	bfs_queue.pop();
marci@280
    36
	for( ; e.valid(); ++e) {
marci@280
    37
	  NodeIt w=G.bNode(e);
marci@280
    38
	  std::cout << "scan node " << G.id(w) << " from node " << G.id(v) << std::endl;
marci@280
    39
	  if (!reached.get(w)) {
marci@280
    40
	    std::cout << G.id(w) << " is newly reached :-)" << std::endl;
marci@280
    41
	    bfs_queue.push(w);
marci@280
    42
	    dist.set(w, dist.get(v)+1);
marci@280
    43
	    pred.set(w, e);
marci@280
    44
	    reached.set(w, true);
marci@280
    45
	  } else {
marci@280
    46
	    std::cout << G.id(w) << " is already reached" << std::endl;
marci@280
    47
	  }
marci@280
    48
	}
marci@280
    49
      }
marci@280
    50
    }
marci@280
    51
  };
marci@280
    52
marci@280
    53
  template <typename Graph> 
marci@280
    54
  struct bfs_visitor {
marci@280
    55
    typedef typename Graph::NodeIt NodeIt;
marci@280
    56
    typedef typename Graph::EdgeIt EdgeIt;
marci@280
    57
    typedef typename Graph::OutEdgeIt OutEdgeIt;
marci@280
    58
    Graph& G;
marci@280
    59
    bfs_visitor(Graph& _G) : G(_G) { }
marci@280
    60
    void at_previously_reached(OutEdgeIt& e) { 
marci@280
    61
      //NodeIt v=G.aNode(e);
marci@280
    62
      NodeIt w=G.bNode(e);
marci@280
    63
      std::cout << G.id(w) << " is already reached" << std::endl;
marci@280
    64
   }
marci@280
    65
    void at_newly_reached(OutEdgeIt& e) { 
marci@280
    66
      //NodeIt v=G.aNode(e);
marci@280
    67
      NodeIt w=G.bNode(e);
marci@280
    68
      std::cout << G.id(w) << " is newly reached :-)" << std::endl;
marci@280
    69
    }
marci@280
    70
  };
marci@280
    71
marci@280
    72
  template <typename Graph, typename ReachedMap, typename visitor_type>
marci@280
    73
  struct bfs_iterator {
marci@280
    74
    typedef typename Graph::NodeIt NodeIt;
marci@280
    75
    typedef typename Graph::EdgeIt EdgeIt;
marci@280
    76
    typedef typename Graph::OutEdgeIt OutEdgeIt;
marci@280
    77
    Graph& G;
marci@280
    78
    std::queue<OutEdgeIt>& bfs_queue;
marci@280
    79
    ReachedMap& reached;
marci@280
    80
    visitor_type& visitor;
marci@280
    81
    void process() {
marci@280
    82
      while ( !bfs_queue.empty() && !bfs_queue.front().valid() ) { bfs_queue.pop(); } 
marci@280
    83
      if (bfs_queue.empty()) return;
marci@280
    84
      OutEdgeIt e=bfs_queue.front();
marci@280
    85
      //NodeIt v=G.aNode(e);
marci@280
    86
      NodeIt w=G.bNode(e);
marci@280
    87
      if (!reached.get(w)) {
marci@280
    88
	visitor.at_newly_reached(e);
marci@280
    89
	bfs_queue.push(G.template first<OutEdgeIt>(w));
marci@280
    90
	reached.set(w, true);
marci@280
    91
      } else {
marci@280
    92
	visitor.at_previously_reached(e);
marci@280
    93
      }
marci@280
    94
    }
marci@280
    95
    bfs_iterator(Graph& _G, std::queue<OutEdgeIt>& _bfs_queue, ReachedMap& _reached, visitor_type& _visitor) : G(_G), bfs_queue(_bfs_queue), reached(_reached), visitor(_visitor) { 
marci@280
    96
      //while ( !bfs_queue.empty() && !bfs_queue.front().valid() ) { bfs_queue.pop(); } 
marci@280
    97
      valid();
marci@280
    98
    }
marci@280
    99
    bfs_iterator<Graph, ReachedMap, visitor_type>& operator++() { 
marci@280
   100
      //while ( !bfs_queue.empty() && !bfs_queue.front().valid() ) { bfs_queue.pop(); } 
marci@280
   101
      //if (bfs_queue.empty()) return *this;
marci@280
   102
      if (!valid()) return *this;
marci@280
   103
      ++(bfs_queue.front());
marci@280
   104
      //while ( !bfs_queue.empty() && !bfs_queue.front().valid() ) { bfs_queue.pop(); } 
marci@280
   105
      valid();
marci@280
   106
      return *this;
marci@280
   107
    }
marci@280
   108
    //void next() { 
marci@280
   109
    //  while ( !bfs_queue.empty() && !bfs_queue.front().valid() ) { bfs_queue.pop(); } 
marci@280
   110
    //  if (bfs_queue.empty()) return;
marci@280
   111
    //  ++(bfs_queue.front());
marci@280
   112
    //  while ( !bfs_queue.empty() && !bfs_queue.front().valid() ) { bfs_queue.pop(); } 
marci@280
   113
    //}
marci@280
   114
    bool valid() { 
marci@280
   115
      while ( !bfs_queue.empty() && !bfs_queue.front().valid() ) { bfs_queue.pop(); } 
marci@280
   116
      if (bfs_queue.empty()) return false; else return true;
marci@280
   117
    }
marci@280
   118
    //bool finished() { 
marci@280
   119
    //  while ( !bfs_queue.empty() && !bfs_queue.front().valid() ) { bfs_queue.pop(); } 
marci@280
   120
    //  if (bfs_queue.empty()) return true; else return false;
marci@280
   121
    //}
marci@280
   122
    operator EdgeIt () { return bfs_queue.front(); }
marci@280
   123
marci@280
   124
  };
marci@280
   125
marci@280
   126
  template <typename Graph, typename ReachedMap>
marci@280
   127
  struct bfs_iterator1 {
marci@280
   128
    typedef typename Graph::NodeIt NodeIt;
marci@280
   129
    typedef typename Graph::EdgeIt EdgeIt;
marci@280
   130
    typedef typename Graph::OutEdgeIt OutEdgeIt;
marci@280
   131
    Graph& G;
marci@280
   132
    std::queue<OutEdgeIt>& bfs_queue;
marci@280
   133
    ReachedMap& reached;
marci@280
   134
    bool _newly_reached;
marci@280
   135
    bfs_iterator1(Graph& _G, std::queue<OutEdgeIt>& _bfs_queue, ReachedMap& _reached) : G(_G), bfs_queue(_bfs_queue), reached(_reached) { 
marci@280
   136
      valid();
marci@280
   137
      if (!bfs_queue.empty() && bfs_queue.front().valid()) { 
marci@280
   138
	OutEdgeIt e=bfs_queue.front();
marci@280
   139
	NodeIt w=G.bNode(e);
marci@280
   140
	if (!reached.get(w)) {
marci@280
   141
	  bfs_queue.push(G.template first<OutEdgeIt>(w));
marci@280
   142
	  reached.set(w, true);
marci@280
   143
	  _newly_reached=true;
marci@280
   144
	} else {
marci@280
   145
	  _newly_reached=false;
marci@280
   146
	}
marci@280
   147
      }
marci@280
   148
    }
marci@280
   149
    bfs_iterator1<Graph, ReachedMap>& operator++() { 
marci@280
   150
      if (!valid()) return *this;
marci@280
   151
      ++(bfs_queue.front());
marci@280
   152
      valid();
marci@280
   153
      if (!bfs_queue.empty() && bfs_queue.front().valid()) { 
marci@280
   154
	OutEdgeIt e=bfs_queue.front();
marci@280
   155
	NodeIt w=G.bNode(e);
marci@280
   156
	if (!reached.get(w)) {
marci@280
   157
	  bfs_queue.push(G.template first<OutEdgeIt>(w));
marci@280
   158
	  reached.set(w, true);
marci@280
   159
	  _newly_reached=true;
marci@280
   160
	} else {
marci@280
   161
	  _newly_reached=false;
marci@280
   162
	}
marci@280
   163
      }
marci@280
   164
      return *this;
marci@280
   165
    }
marci@280
   166
    bool valid() { 
marci@280
   167
      while ( !bfs_queue.empty() && !bfs_queue.front().valid() ) { bfs_queue.pop(); } 
marci@280
   168
      if (bfs_queue.empty()) return false; else return true;
marci@280
   169
    }
marci@280
   170
    operator OutEdgeIt() { return bfs_queue.front(); }
marci@280
   171
    //ize
marci@280
   172
    bool newly_reached() { return _newly_reached; }
marci@280
   173
marci@280
   174
  };
marci@280
   175
marci@280
   176
  template <typename Graph, typename OutEdgeIt, typename ReachedMap>
marci@280
   177
  struct BfsIterator {
marci@280
   178
    typedef typename Graph::NodeIt NodeIt;
marci@280
   179
    Graph& G;
marci@280
   180
    std::queue<OutEdgeIt>& bfs_queue;
marci@280
   181
    ReachedMap& reached;
marci@280
   182
    bool b_node_newly_reached;
marci@280
   183
    OutEdgeIt actual_edge;
marci@280
   184
    BfsIterator(Graph& _G, 
marci@280
   185
		std::queue<OutEdgeIt>& _bfs_queue, 
marci@280
   186
		ReachedMap& _reached) : 
marci@280
   187
      G(_G), bfs_queue(_bfs_queue), reached(_reached) { 
marci@280
   188
      actual_edge=bfs_queue.front();
marci@280
   189
      if (actual_edge.valid()) { 
marci@280
   190
	NodeIt w=G.bNode(actual_edge);
marci@280
   191
	if (!reached.get(w)) {
marci@280
   192
	  bfs_queue.push(G.firstOutEdge(w));
marci@280
   193
	  reached.set(w, true);
marci@280
   194
	  b_node_newly_reached=true;
marci@280
   195
	} else {
marci@280
   196
	  b_node_newly_reached=false;
marci@280
   197
	}
marci@280
   198
      }
marci@280
   199
    }
marci@280
   200
    BfsIterator<Graph, OutEdgeIt, ReachedMap>& 
marci@280
   201
    operator++() { 
marci@280
   202
      if (bfs_queue.front().valid()) { 
marci@280
   203
	++(bfs_queue.front());
marci@280
   204
	actual_edge=bfs_queue.front();
marci@280
   205
	if (actual_edge.valid()) {
marci@280
   206
	  NodeIt w=G.bNode(actual_edge);
marci@280
   207
	  if (!reached.get(w)) {
marci@280
   208
	    bfs_queue.push(G.firstOutEdge(w));
marci@280
   209
	    reached.set(w, true);
marci@280
   210
	    b_node_newly_reached=true;
marci@280
   211
	  } else {
marci@280
   212
	    b_node_newly_reached=false;
marci@280
   213
	  }
marci@280
   214
	}
marci@280
   215
      } else {
marci@280
   216
	bfs_queue.pop(); 
marci@280
   217
	actual_edge=bfs_queue.front();
marci@280
   218
	if (actual_edge.valid()) {
marci@280
   219
	  NodeIt w=G.bNode(actual_edge);
marci@280
   220
	  if (!reached.get(w)) {
marci@280
   221
	    bfs_queue.push(G.firstOutEdge(w));
marci@280
   222
	    reached.set(w, true);
marci@280
   223
	    b_node_newly_reached=true;
marci@280
   224
	  } else {
marci@280
   225
	    b_node_newly_reached=false;
marci@280
   226
	  }
marci@280
   227
	}
marci@280
   228
      }
marci@280
   229
      return *this;
marci@280
   230
    }
marci@280
   231
    bool finished() { return bfs_queue.empty(); }
marci@280
   232
    operator OutEdgeIt () { return actual_edge; }
marci@280
   233
    bool bNodeIsNewlyReached() { return b_node_newly_reached; }
marci@280
   234
    bool aNodeIsExamined() { return !(actual_edge.valid()); }
marci@280
   235
  };
marci@280
   236
marci@280
   237
marci@280
   238
  template <typename Graph, typename OutEdgeIt, typename ReachedMap>
marci@280
   239
  struct DfsIterator {
marci@280
   240
    typedef typename Graph::NodeIt NodeIt;
marci@280
   241
    Graph& G;
marci@280
   242
    std::stack<OutEdgeIt>& bfs_queue;
marci@280
   243
    ReachedMap& reached;
marci@280
   244
    bool b_node_newly_reached;
marci@280
   245
    OutEdgeIt actual_edge;
marci@280
   246
    DfsIterator(Graph& _G, 
marci@280
   247
		std::stack<OutEdgeIt>& _bfs_queue, 
marci@280
   248
		ReachedMap& _reached) : 
marci@280
   249
      G(_G), bfs_queue(_bfs_queue), reached(_reached) { 
marci@280
   250
      actual_edge=bfs_queue.top();
marci@280
   251
      if (actual_edge.valid()) { 
marci@280
   252
	NodeIt w=G.bNode(actual_edge);
marci@280
   253
	if (!reached.get(w)) {
marci@280
   254
	  bfs_queue.push(G.firstOutEdge(w));
marci@280
   255
	  reached.set(w, true);
marci@280
   256
	  b_node_newly_reached=true;
marci@280
   257
	} else {
marci@280
   258
	  ++(bfs_queue.top());
marci@280
   259
	  b_node_newly_reached=false;
marci@280
   260
	}
marci@280
   261
      } else {
marci@280
   262
	bfs_queue.pop();
marci@280
   263
      }
marci@280
   264
    }
marci@280
   265
    DfsIterator<Graph, OutEdgeIt, ReachedMap>& 
marci@280
   266
    operator++() { 
marci@280
   267
      actual_edge=bfs_queue.top();
marci@280
   268
      if (actual_edge.valid()) { 
marci@280
   269
	NodeIt w=G.bNode(actual_edge);
marci@280
   270
	if (!reached.get(w)) {
marci@280
   271
	  bfs_queue.push(G.firstOutEdge(w));
marci@280
   272
	  reached.set(w, true);
marci@280
   273
	  b_node_newly_reached=true;
marci@280
   274
	} else {
marci@280
   275
	  ++(bfs_queue.top());
marci@280
   276
	  b_node_newly_reached=false;
marci@280
   277
	}
marci@280
   278
      } else {
marci@280
   279
	bfs_queue.pop();
marci@280
   280
      }
marci@280
   281
      return *this;
marci@280
   282
    }
marci@280
   283
    bool finished() { return bfs_queue.empty(); }
marci@280
   284
    operator OutEdgeIt () { return actual_edge; }
marci@280
   285
    bool bNodeIsNewlyReached() { return b_node_newly_reached; }
marci@280
   286
    bool aNodeIsExamined() { return !(actual_edge.valid()); }
marci@280
   287
  };
marci@280
   288
marci@280
   289
  template <typename Graph, typename OutEdgeIt, typename ReachedMap>
marci@280
   290
  struct BfsIterator1 {
marci@280
   291
    typedef typename Graph::NodeIt NodeIt;
marci@280
   292
    Graph& G;
marci@280
   293
    std::queue<OutEdgeIt>& bfs_queue;
marci@280
   294
    ReachedMap& reached;
marci@280
   295
    bool b_node_newly_reached;
marci@280
   296
    OutEdgeIt actual_edge;
marci@280
   297
    BfsIterator1(Graph& _G, 
marci@280
   298
		std::queue<OutEdgeIt>& _bfs_queue, 
marci@280
   299
		ReachedMap& _reached) : 
marci@280
   300
      G(_G), bfs_queue(_bfs_queue), reached(_reached) { 
marci@280
   301
      actual_edge=bfs_queue.front();
marci@280
   302
      if (actual_edge.valid()) { 
marci@280
   303
      	NodeIt w=G.bNode(actual_edge);
marci@280
   304
	if (!reached.get(w)) {
marci@280
   305
	  bfs_queue.push(OutEdgeIt(G, w));
marci@280
   306
	  reached.set(w, true);
marci@280
   307
	  b_node_newly_reached=true;
marci@280
   308
	} else {
marci@280
   309
	  b_node_newly_reached=false;
marci@280
   310
	}
marci@280
   311
      }
marci@280
   312
    }
marci@280
   313
    void next() { 
marci@280
   314
      if (bfs_queue.front().valid()) { 
marci@280
   315
	++(bfs_queue.front());
marci@280
   316
	actual_edge=bfs_queue.front();
marci@280
   317
	if (actual_edge.valid()) {
marci@280
   318
	  NodeIt w=G.bNode(actual_edge);
marci@280
   319
	  if (!reached.get(w)) {
marci@280
   320
	    bfs_queue.push(OutEdgeIt(G, w));
marci@280
   321
	    reached.set(w, true);
marci@280
   322
	    b_node_newly_reached=true;
marci@280
   323
	  } else {
marci@280
   324
	    b_node_newly_reached=false;
marci@280
   325
	  }
marci@280
   326
	}
marci@280
   327
      } else {
marci@280
   328
	bfs_queue.pop(); 
marci@280
   329
	actual_edge=bfs_queue.front();
marci@280
   330
	if (actual_edge.valid()) {
marci@280
   331
	  NodeIt w=G.bNode(actual_edge);
marci@280
   332
	  if (!reached.get(w)) {
marci@280
   333
	    bfs_queue.push(OutEdgeIt(G, w));
marci@280
   334
	    reached.set(w, true);
marci@280
   335
	    b_node_newly_reached=true;
marci@280
   336
	  } else {
marci@280
   337
	    b_node_newly_reached=false;
marci@280
   338
	  }
marci@280
   339
	}
marci@280
   340
      }
marci@280
   341
      //return *this;
marci@280
   342
    }
marci@280
   343
    bool finished() { return bfs_queue.empty(); }
marci@280
   344
    operator OutEdgeIt () { return actual_edge; }
marci@280
   345
    bool bNodeIsNewlyReached() { return b_node_newly_reached; }
marci@280
   346
    bool aNodeIsExamined() { return !(actual_edge.valid()); }
marci@280
   347
  };
marci@280
   348
marci@280
   349
marci@280
   350
  template <typename Graph, typename OutEdgeIt, typename ReachedMap>
marci@280
   351
  struct DfsIterator1 {
marci@280
   352
    typedef typename Graph::NodeIt NodeIt;
marci@280
   353
    Graph& G;
marci@280
   354
    std::stack<OutEdgeIt>& bfs_queue;
marci@280
   355
    ReachedMap& reached;
marci@280
   356
    bool b_node_newly_reached;
marci@280
   357
    OutEdgeIt actual_edge;
marci@280
   358
    DfsIterator1(Graph& _G, 
marci@280
   359
		std::stack<OutEdgeIt>& _bfs_queue, 
marci@280
   360
		ReachedMap& _reached) : 
marci@280
   361
      G(_G), bfs_queue(_bfs_queue), reached(_reached) { 
marci@280
   362
      //actual_edge=bfs_queue.top();
marci@280
   363
      //if (actual_edge.valid()) { 
marci@280
   364
      //	NodeIt w=G.bNode(actual_edge);
marci@280
   365
      //if (!reached.get(w)) {
marci@280
   366
      //  bfs_queue.push(OutEdgeIt(G, w));
marci@280
   367
      //  reached.set(w, true);
marci@280
   368
      //  b_node_newly_reached=true;
marci@280
   369
      //} else {
marci@280
   370
      //  ++(bfs_queue.top());
marci@280
   371
      //  b_node_newly_reached=false;
marci@280
   372
      //}
marci@280
   373
      //} else {
marci@280
   374
      //	bfs_queue.pop();
marci@280
   375
      //}
marci@280
   376
    }
marci@280
   377
    void next() { 
marci@280
   378
      actual_edge=bfs_queue.top();
marci@280
   379
      if (actual_edge.valid()) { 
marci@280
   380
	NodeIt w=G.bNode(actual_edge);
marci@280
   381
	if (!reached.get(w)) {
marci@280
   382
	  bfs_queue.push(OutEdgeIt(G, w));
marci@280
   383
	  reached.set(w, true);
marci@280
   384
	  b_node_newly_reached=true;
marci@280
   385
	} else {
marci@280
   386
	  ++(bfs_queue.top());
marci@280
   387
	  b_node_newly_reached=false;
marci@280
   388
	}
marci@280
   389
      } else {
marci@280
   390
	bfs_queue.pop();
marci@280
   391
      }
marci@280
   392
      //return *this;
marci@280
   393
    }
marci@280
   394
    bool finished() { return bfs_queue.empty(); }
marci@280
   395
    operator OutEdgeIt () { return actual_edge; }
marci@280
   396
    bool bNodeIsNewlyReached() { return b_node_newly_reached; }
marci@280
   397
    bool aNodeIsLeaved() { return !(actual_edge.valid()); }
marci@280
   398
  };
marci@280
   399
marci@280
   400
  template <typename Graph, typename OutEdgeIt, typename ReachedMap>
marci@280
   401
  class BfsIterator2 {
marci@280
   402
    typedef typename Graph::NodeIt NodeIt;
marci@280
   403
    const Graph& G;
marci@280
   404
    std::queue<OutEdgeIt> bfs_queue;
marci@280
   405
    ReachedMap reached;
marci@280
   406
    bool b_node_newly_reached;
marci@280
   407
    OutEdgeIt actual_edge;
marci@280
   408
  public:
marci@280
   409
    BfsIterator2(const Graph& _G) : G(_G), reached(G, false) { }
marci@280
   410
    void pushAndSetReached(NodeIt s) { 
marci@280
   411
      reached.set(s, true);
marci@280
   412
      if (bfs_queue.empty()) {
marci@280
   413
	bfs_queue.push(G.template first<OutEdgeIt>(s));
marci@280
   414
	actual_edge=bfs_queue.front();
marci@280
   415
	if (actual_edge.valid()) { 
marci@280
   416
	  NodeIt w=G.bNode(actual_edge);
marci@280
   417
	  if (!reached.get(w)) {
marci@280
   418
	    bfs_queue.push(G.template first<OutEdgeIt>(w));
marci@280
   419
	    reached.set(w, true);
marci@280
   420
	    b_node_newly_reached=true;
marci@280
   421
	  } else {
marci@280
   422
	    b_node_newly_reached=false;
marci@280
   423
	  }
marci@280
   424
	} //else {
marci@280
   425
	//}
marci@280
   426
      } else {
marci@280
   427
	bfs_queue.push(G.template first<OutEdgeIt>(s));
marci@280
   428
      }
marci@280
   429
    }
marci@280
   430
    BfsIterator2<Graph, OutEdgeIt, ReachedMap>& 
marci@280
   431
    operator++() { 
marci@280
   432
      if (bfs_queue.front().valid()) { 
marci@280
   433
	++(bfs_queue.front());
marci@280
   434
	actual_edge=bfs_queue.front();
marci@280
   435
	if (actual_edge.valid()) {
marci@280
   436
	  NodeIt w=G.bNode(actual_edge);
marci@280
   437
	  if (!reached.get(w)) {
marci@280
   438
	    bfs_queue.push(G.template first<OutEdgeIt>(w));
marci@280
   439
	    reached.set(w, true);
marci@280
   440
	    b_node_newly_reached=true;
marci@280
   441
	  } else {
marci@280
   442
	    b_node_newly_reached=false;
marci@280
   443
	  }
marci@280
   444
	}
marci@280
   445
      } else {
marci@280
   446
	bfs_queue.pop(); 
marci@280
   447
	if (!bfs_queue.empty()) {
marci@280
   448
	  actual_edge=bfs_queue.front();
marci@280
   449
	  if (actual_edge.valid()) {
marci@280
   450
	    NodeIt w=G.bNode(actual_edge);
marci@280
   451
	    if (!reached.get(w)) {
marci@280
   452
	      bfs_queue.push(G.template first<OutEdgeIt>(w));
marci@280
   453
	      reached.set(w, true);
marci@280
   454
	      b_node_newly_reached=true;
marci@280
   455
	    } else {
marci@280
   456
	      b_node_newly_reached=false;
marci@280
   457
	    }
marci@280
   458
	  }
marci@280
   459
	}
marci@280
   460
      }
marci@280
   461
      return *this;
marci@280
   462
    }
marci@280
   463
    bool finished() const { return bfs_queue.empty(); }
marci@280
   464
    operator OutEdgeIt () const { return actual_edge; }
marci@280
   465
    bool isBNodeNewlyReached() const { return b_node_newly_reached; }
marci@280
   466
    bool isANodeExamined() const { return !(actual_edge.valid()); }
marci@280
   467
    const ReachedMap& getReachedMap() const { return reached; }
marci@280
   468
    const std::queue<OutEdgeIt>& getBfsQueue() const { return bfs_queue; }
marci@280
   469
 };
marci@280
   470
marci@280
   471
marci@280
   472
  template <typename Graph, typename OutEdgeIt, typename ReachedMap>
marci@280
   473
  class BfsIterator3 {
marci@280
   474
    typedef typename Graph::NodeIt NodeIt;
marci@280
   475
    const Graph& G;
marci@280
   476
    std::queue< std::pair<NodeIt, OutEdgeIt> > bfs_queue;
marci@280
   477
    ReachedMap reached;
marci@280
   478
    bool b_node_newly_reached;
marci@280
   479
    OutEdgeIt actual_edge;
marci@280
   480
  public:
marci@280
   481
    BfsIterator3(const Graph& _G) : G(_G), reached(G, false) { }
marci@280
   482
    void pushAndSetReached(NodeIt s) { 
marci@280
   483
      reached.set(s, true);
marci@280
   484
      if (bfs_queue.empty()) {
marci@280
   485
	bfs_queue.push(std::pair<NodeIt, OutEdgeIt>(s, G.template first<OutEdgeIt>(s)));
marci@280
   486
	actual_edge=bfs_queue.front().second;
marci@280
   487
	if (actual_edge.valid()) { 
marci@280
   488
	  NodeIt w=G.bNode(actual_edge);
marci@280
   489
	  if (!reached.get(w)) {
marci@280
   490
	    bfs_queue.push(std::pair<NodeIt, OutEdgeIt>(w, G.template first<OutEdgeIt>(w)));
marci@280
   491
	    reached.set(w, true);
marci@280
   492
	    b_node_newly_reached=true;
marci@280
   493
	  } else {
marci@280
   494
	    b_node_newly_reached=false;
marci@280
   495
	  }
marci@280
   496
	} //else {
marci@280
   497
	//}
marci@280
   498
      } else {
marci@280
   499
	bfs_queue.push(std::pair<NodeIt, OutEdgeIt>(s, G.template first<OutEdgeIt>(s)));
marci@280
   500
      }
marci@280
   501
    }
marci@280
   502
    BfsIterator3<Graph, OutEdgeIt, ReachedMap>& 
marci@280
   503
    operator++() { 
marci@280
   504
      if (bfs_queue.front().second.valid()) { 
marci@280
   505
	++(bfs_queue.front().second);
marci@280
   506
	actual_edge=bfs_queue.front().second;
marci@280
   507
	if (actual_edge.valid()) {
marci@280
   508
	  NodeIt w=G.bNode(actual_edge);
marci@280
   509
	  if (!reached.get(w)) {
marci@280
   510
	    bfs_queue.push(std::pair<NodeIt, OutEdgeIt>(w, G.template first<OutEdgeIt>(w)));
marci@280
   511
	    reached.set(w, true);
marci@280
   512
	    b_node_newly_reached=true;
marci@280
   513
	  } else {
marci@280
   514
	    b_node_newly_reached=false;
marci@280
   515
	  }
marci@280
   516
	}
marci@280
   517
      } else {
marci@280
   518
	bfs_queue.pop(); 
marci@280
   519
	if (!bfs_queue.empty()) {
marci@280
   520
	  actual_edge=bfs_queue.front().second;
marci@280
   521
	  if (actual_edge.valid()) {
marci@280
   522
	    NodeIt w=G.bNode(actual_edge);
marci@280
   523
	    if (!reached.get(w)) {
marci@280
   524
	      bfs_queue.push(std::pair<NodeIt, OutEdgeIt>(w, G.template first<OutEdgeIt>(w)));
marci@280
   525
	      reached.set(w, true);
marci@280
   526
	      b_node_newly_reached=true;
marci@280
   527
	    } else {
marci@280
   528
	      b_node_newly_reached=false;
marci@280
   529
	    }
marci@280
   530
	  }
marci@280
   531
	}
marci@280
   532
      }
marci@280
   533
      return *this;
marci@280
   534
    }
marci@280
   535
    bool finished() const { return bfs_queue.empty(); }
marci@280
   536
    operator OutEdgeIt () const { return actual_edge; }
marci@280
   537
    bool isBNodeNewlyReached() const { return b_node_newly_reached; }
marci@280
   538
    bool isANodeExamined() const { return !(actual_edge.valid()); }
marci@280
   539
    NodeIt aNode() const { return bfs_queue.front().first; }
marci@280
   540
    NodeIt bNode() const { return G.bNode(actual_edge); }
marci@280
   541
    const ReachedMap& getReachedMap() const { return reached; }
marci@280
   542
    //const std::queue< std::pair<NodeIt, OutEdgeIt> >& getBfsQueue() const { return bfs_queue; }
marci@280
   543
 };
marci@280
   544
marci@280
   545
marci@280
   546
  template <typename Graph, typename OutEdgeIt, 
marci@280
   547
	    typename ReachedMap/*=typename Graph::NodeMap<bool>*/ >
marci@280
   548
  class BfsIterator4 {
marci@280
   549
    typedef typename Graph::NodeIt NodeIt;
marci@280
   550
    const Graph& G;
marci@280
   551
    std::queue<NodeIt> bfs_queue;
marci@280
   552
    ReachedMap& reached;
marci@280
   553
    bool b_node_newly_reached;
marci@280
   554
    OutEdgeIt actual_edge;
marci@280
   555
    bool own_reached_map;
marci@280
   556
  public:
marci@280
   557
    BfsIterator4(const Graph& _G, ReachedMap& _reached) : 
marci@280
   558
      G(_G), reached(_reached), 
marci@280
   559
      own_reached_map(false) { }
marci@280
   560
    BfsIterator4(const Graph& _G) : 
marci@280
   561
      G(_G), reached(*(new ReachedMap(G /*, false*/))), 
marci@280
   562
      own_reached_map(true) { }
marci@280
   563
    ~BfsIterator4() { if (own_reached_map) delete &reached; }
marci@280
   564
    void pushAndSetReached(NodeIt s) { 
marci@280
   565
      //std::cout << "mimi" << &reached << std::endl;
marci@280
   566
      reached.set(s, true);
marci@280
   567
      //std::cout << "mumus" << std::endl;
marci@280
   568
      if (bfs_queue.empty()) {
marci@280
   569
	//std::cout << "bibi1" << std::endl;
marci@280
   570
	bfs_queue.push(s);
marci@280
   571
	//std::cout << "zizi" << std::endl;
marci@280
   572
	G.getFirst(actual_edge, s);
marci@280
   573
	//std::cout << "kiki" << std::endl;
marci@280
   574
	if (G.valid(actual_edge)/*.valid()*/) { 
marci@280
   575
	  NodeIt w=G.bNode(actual_edge);
marci@280
   576
	  if (!reached.get(w)) {
marci@280
   577
	    bfs_queue.push(w);
marci@280
   578
	    reached.set(w, true);
marci@280
   579
	    b_node_newly_reached=true;
marci@280
   580
	  } else {
marci@280
   581
	    b_node_newly_reached=false;
marci@280
   582
	  }
marci@280
   583
	} 
marci@280
   584
      } else {
marci@280
   585
	//std::cout << "bibi2" << std::endl;
marci@280
   586
	bfs_queue.push(s);
marci@280
   587
      }
marci@280
   588
    }
marci@280
   589
    BfsIterator4<Graph, OutEdgeIt, ReachedMap>& 
marci@280
   590
    operator++() { 
marci@280
   591
      if (G.valid(actual_edge)/*.valid()*/) { 
marci@280
   592
	/*++*/G.next(actual_edge);
marci@280
   593
	if (G.valid(actual_edge)/*.valid()*/) {
marci@280
   594
	  NodeIt w=G.bNode(actual_edge);
marci@280
   595
	  if (!reached.get(w)) {
marci@280
   596
	    bfs_queue.push(w);
marci@280
   597
	    reached.set(w, true);
marci@280
   598
	    b_node_newly_reached=true;
marci@280
   599
	  } else {
marci@280
   600
	    b_node_newly_reached=false;
marci@280
   601
	  }
marci@280
   602
	}
marci@280
   603
      } else {
marci@280
   604
	bfs_queue.pop(); 
marci@280
   605
	if (!bfs_queue.empty()) {
marci@280
   606
	  G.getFirst(actual_edge, bfs_queue.front());
marci@280
   607
	  if (G.valid(actual_edge)/*.valid()*/) {
marci@280
   608
	    NodeIt w=G.bNode(actual_edge);
marci@280
   609
	    if (!reached.get(w)) {
marci@280
   610
	      bfs_queue.push(w);
marci@280
   611
	      reached.set(w, true);
marci@280
   612
	      b_node_newly_reached=true;
marci@280
   613
	    } else {
marci@280
   614
	      b_node_newly_reached=false;
marci@280
   615
	    }
marci@280
   616
	  }
marci@280
   617
	}
marci@280
   618
      }
marci@280
   619
      return *this;
marci@280
   620
    }
marci@280
   621
    bool finished() const { return bfs_queue.empty(); }
marci@280
   622
    operator OutEdgeIt () const { return actual_edge; }
marci@280
   623
    bool isBNodeNewlyReached() const { return b_node_newly_reached; }
marci@280
   624
    bool isANodeExamined() const { return !(G.valid(actual_edge)/*.valid()*/); }
marci@280
   625
    NodeIt aNode() const { return bfs_queue.front(); }
marci@280
   626
    NodeIt bNode() const { return G.bNode(actual_edge); }
marci@280
   627
    const ReachedMap& getReachedMap() const { return reached; }
marci@280
   628
    const std::queue<NodeIt>& getBfsQueue() const { return bfs_queue; }
marci@280
   629
 };  
marci@280
   630
marci@280
   631
marci@280
   632
  template <typename GraphWrapper, /*typename OutEdgeIt,*/ 
marci@280
   633
	    typename ReachedMap/*=typename GraphWrapper::NodeMap<bool>*/ >
marci@280
   634
  class BfsIterator5 {
marci@280
   635
    typedef typename GraphWrapper::NodeIt NodeIt;
marci@280
   636
    typedef typename GraphWrapper::OutEdgeIt OutEdgeIt;
marci@280
   637
    GraphWrapper G;
marci@280
   638
    std::queue<NodeIt> bfs_queue;
marci@280
   639
    ReachedMap& reached;
marci@280
   640
    bool b_node_newly_reached;
marci@280
   641
    OutEdgeIt actual_edge;
marci@280
   642
    bool own_reached_map;
marci@280
   643
  public:
marci@280
   644
    BfsIterator5(const GraphWrapper& _G, ReachedMap& _reached) : 
marci@280
   645
      G(_G), reached(_reached), 
marci@280
   646
      own_reached_map(false) { }
marci@280
   647
    BfsIterator5(const GraphWrapper& _G) : 
marci@280
   648
      G(_G), reached(*(new ReachedMap(G /*, false*/))), 
marci@280
   649
      own_reached_map(true) { }
marci@280
   650
//     BfsIterator5(const typename GraphWrapper::BaseGraph& _G, 
marci@280
   651
// 		 ReachedMap& _reached) : 
marci@280
   652
//       G(_G), reached(_reached), 
marci@280
   653
//       own_reached_map(false) { }
marci@280
   654
//     BfsIterator5(const typename GraphWrapper::BaseGraph& _G) : 
marci@280
   655
//       G(_G), reached(*(new ReachedMap(G /*, false*/))), 
marci@280
   656
//       own_reached_map(true) { }
marci@280
   657
    ~BfsIterator5() { if (own_reached_map) delete &reached; }
marci@280
   658
    void pushAndSetReached(NodeIt s) { 
marci@280
   659
      reached.set(s, true);
marci@280
   660
      if (bfs_queue.empty()) {
marci@280
   661
	bfs_queue.push(s);
marci@280
   662
	G.getFirst(actual_edge, s);
marci@280
   663
	if (G.valid(actual_edge)/*.valid()*/) { 
marci@280
   664
	  NodeIt w=G.bNode(actual_edge);
marci@280
   665
	  if (!reached.get(w)) {
marci@280
   666
	    bfs_queue.push(w);
marci@280
   667
	    reached.set(w, true);
marci@280
   668
	    b_node_newly_reached=true;
marci@280
   669
	  } else {
marci@280
   670
	    b_node_newly_reached=false;
marci@280
   671
	  }
marci@280
   672
	} 
marci@280
   673
      } else {
marci@280
   674
	bfs_queue.push(s);
marci@280
   675
      }
marci@280
   676
    }
marci@280
   677
    BfsIterator5<GraphWrapper, /*OutEdgeIt,*/ ReachedMap>& 
marci@280
   678
    operator++() { 
marci@280
   679
      if (G.valid(actual_edge)/*.valid()*/) { 
marci@280
   680
	/*++*/G.next(actual_edge);
marci@280
   681
	if (G.valid(actual_edge)/*.valid()*/) {
marci@280
   682
	  NodeIt w=G.bNode(actual_edge);
marci@280
   683
	  if (!reached.get(w)) {
marci@280
   684
	    bfs_queue.push(w);
marci@280
   685
	    reached.set(w, true);
marci@280
   686
	    b_node_newly_reached=true;
marci@280
   687
	  } else {
marci@280
   688
	    b_node_newly_reached=false;
marci@280
   689
	  }
marci@280
   690
	}
marci@280
   691
      } else {
marci@280
   692
	bfs_queue.pop(); 
marci@280
   693
	if (!bfs_queue.empty()) {
marci@280
   694
	  G.getFirst(actual_edge, bfs_queue.front());
marci@280
   695
	  if (G.valid(actual_edge)/*.valid()*/) {
marci@280
   696
	    NodeIt w=G.bNode(actual_edge);
marci@280
   697
	    if (!reached.get(w)) {
marci@280
   698
	      bfs_queue.push(w);
marci@280
   699
	      reached.set(w, true);
marci@280
   700
	      b_node_newly_reached=true;
marci@280
   701
	    } else {
marci@280
   702
	      b_node_newly_reached=false;
marci@280
   703
	    }
marci@280
   704
	  }
marci@280
   705
	}
marci@280
   706
      }
marci@280
   707
      return *this;
marci@280
   708
    }
marci@280
   709
    bool finished() const { return bfs_queue.empty(); }
marci@280
   710
    operator OutEdgeIt () const { return actual_edge; }
marci@280
   711
    bool isBNodeNewlyReached() const { return b_node_newly_reached; }
marci@280
   712
    bool isANodeExamined() const { return !(G.valid(actual_edge)/*.valid()*/); }
marci@280
   713
    NodeIt aNode() const { return bfs_queue.front(); }
marci@280
   714
    NodeIt bNode() const { return G.bNode(actual_edge); }
marci@280
   715
    const ReachedMap& getReachedMap() const { return reached; }
marci@280
   716
    const std::queue<NodeIt>& getBfsQueue() const { return bfs_queue; }
marci@280
   717
  };  
marci@280
   718
marci@280
   719
  template <typename Graph, typename OutEdgeIt, 
marci@280
   720
	    typename ReachedMap/*=typename Graph::NodeMap<bool>*/ >
marci@280
   721
  class DfsIterator4 {
marci@280
   722
    typedef typename Graph::NodeIt NodeIt;
marci@280
   723
    const Graph& G;
marci@280
   724
    std::stack<OutEdgeIt> dfs_stack;
marci@280
   725
    bool b_node_newly_reached;
marci@280
   726
    OutEdgeIt actual_edge;
marci@280
   727
    NodeIt actual_node;
marci@280
   728
    ReachedMap& reached;
marci@280
   729
    bool own_reached_map;
marci@280
   730
  public:
marci@280
   731
    DfsIterator4(const Graph& _G, ReachedMap& _reached) : 
marci@280
   732
      G(_G), reached(_reached), 
marci@280
   733
      own_reached_map(false) { }
marci@280
   734
    DfsIterator4(const Graph& _G) : 
marci@280
   735
      G(_G), reached(*(new ReachedMap(G /*, false*/))), 
marci@280
   736
      own_reached_map(true) { }
marci@280
   737
    ~DfsIterator4() { if (own_reached_map) delete &reached; }
marci@280
   738
    void pushAndSetReached(NodeIt s) { 
marci@280
   739
      actual_node=s;
marci@280
   740
      reached.set(s, true);
marci@280
   741
      dfs_stack.push(G.template first<OutEdgeIt>(s)); 
marci@280
   742
    }
marci@280
   743
    DfsIterator4<Graph, OutEdgeIt, ReachedMap>& 
marci@280
   744
    operator++() { 
marci@280
   745
      actual_edge=dfs_stack.top();
marci@280
   746
      //actual_node=G.aNode(actual_edge);
marci@280
   747
      if (G.valid(actual_edge)/*.valid()*/) { 
marci@280
   748
	NodeIt w=G.bNode(actual_edge);
marci@280
   749
	actual_node=w;
marci@280
   750
	if (!reached.get(w)) {
marci@280
   751
	  dfs_stack.push(G.template first<OutEdgeIt>(w));
marci@280
   752
	  reached.set(w, true);
marci@280
   753
	  b_node_newly_reached=true;
marci@280
   754
	} else {
marci@280
   755
	  actual_node=G.aNode(actual_edge);
marci@280
   756
	  /*++*/G.next(dfs_stack.top());
marci@280
   757
	  b_node_newly_reached=false;
marci@280
   758
	}
marci@280
   759
      } else {
marci@280
   760
	//actual_node=G.aNode(dfs_stack.top());
marci@280
   761
	dfs_stack.pop();
marci@280
   762
      }
marci@280
   763
      return *this;
marci@280
   764
    }
marci@280
   765
    bool finished() const { return dfs_stack.empty(); }
marci@280
   766
    operator OutEdgeIt () const { return actual_edge; }
marci@280
   767
    bool isBNodeNewlyReached() const { return b_node_newly_reached; }
marci@280
   768
    bool isANodeExamined() const { return !(G.valid(actual_edge)/*.valid()*/); }
marci@280
   769
    NodeIt aNode() const { return actual_node; /*FIXME*/}
marci@280
   770
    NodeIt bNode() const { return G.bNode(actual_edge); }
marci@280
   771
    const ReachedMap& getReachedMap() const { return reached; }
marci@280
   772
    const std::stack<OutEdgeIt>& getDfsStack() const { return dfs_stack; }
marci@280
   773
  };
marci@280
   774
marci@280
   775
  template <typename GraphWrapper, /*typename OutEdgeIt,*/ 
marci@280
   776
	    typename ReachedMap/*=typename GraphWrapper::NodeMap<bool>*/ >
marci@280
   777
  class DfsIterator5 {
marci@280
   778
    typedef typename GraphWrapper::NodeIt NodeIt;
marci@280
   779
    typedef typename GraphWrapper::OutEdgeIt OutEdgeIt;
marci@280
   780
    GraphWrapper G;
marci@280
   781
    std::stack<OutEdgeIt> dfs_stack;
marci@280
   782
    bool b_node_newly_reached;
marci@280
   783
    OutEdgeIt actual_edge;
marci@280
   784
    NodeIt actual_node;
marci@280
   785
    ReachedMap& reached;
marci@280
   786
    bool own_reached_map;
marci@280
   787
  public:
marci@280
   788
    DfsIterator5(const GraphWrapper& _G, ReachedMap& _reached) : 
marci@280
   789
      G(_G), reached(_reached), 
marci@280
   790
      own_reached_map(false) { }
marci@280
   791
    DfsIterator5(const GraphWrapper& _G) : 
marci@280
   792
      G(_G), reached(*(new ReachedMap(G /*, false*/))), 
marci@280
   793
      own_reached_map(true) { }
marci@280
   794
    ~DfsIterator5() { if (own_reached_map) delete &reached; }
marci@280
   795
    void pushAndSetReached(NodeIt s) { 
marci@280
   796
      actual_node=s;
marci@280
   797
      reached.set(s, true);
marci@280
   798
      dfs_stack.push(G.template first<OutEdgeIt>(s)); 
marci@280
   799
    }
marci@280
   800
    DfsIterator5<GraphWrapper, /*OutEdgeIt,*/ ReachedMap>& 
marci@280
   801
    operator++() { 
marci@280
   802
      actual_edge=dfs_stack.top();
marci@280
   803
      //actual_node=G.aNode(actual_edge);
marci@280
   804
      if (G.valid(actual_edge)/*.valid()*/) { 
marci@280
   805
	NodeIt w=G.bNode(actual_edge);
marci@280
   806
	actual_node=w;
marci@280
   807
	if (!reached.get(w)) {
marci@280
   808
	  dfs_stack.push(G.template first<OutEdgeIt>(w));
marci@280
   809
	  reached.set(w, true);
marci@280
   810
	  b_node_newly_reached=true;
marci@280
   811
	} else {
marci@280
   812
	  actual_node=G.aNode(actual_edge);
marci@280
   813
	  /*++*/G.next(dfs_stack.top());
marci@280
   814
	  b_node_newly_reached=false;
marci@280
   815
	}
marci@280
   816
      } else {
marci@280
   817
	//actual_node=G.aNode(dfs_stack.top());
marci@280
   818
	dfs_stack.pop();
marci@280
   819
      }
marci@280
   820
      return *this;
marci@280
   821
    }
marci@280
   822
    bool finished() const { return dfs_stack.empty(); }
marci@280
   823
    operator OutEdgeIt () const { return actual_edge; }
marci@280
   824
    bool isBNodeNewlyReached() const { return b_node_newly_reached; }
marci@280
   825
    bool isANodeExamined() const { return !(G.valid(actual_edge)/*.valid()*/); }
marci@280
   826
    NodeIt aNode() const { return actual_node; /*FIXME*/}
marci@280
   827
    NodeIt bNode() const { return G.bNode(actual_edge); }
marci@280
   828
    const ReachedMap& getReachedMap() const { return reached; }
marci@280
   829
    const std::stack<OutEdgeIt>& getDfsStack() const { return dfs_stack; }
marci@280
   830
  };
marci@280
   831
marci@280
   832
marci@280
   833
marci@280
   834
} // namespace hugo
marci@280
   835
marci@280
   836
#endif //BFS_ITERATOR_HH