src/work/alpar/bfs-named-param.cc
author klao
Wed, 10 Nov 2004 21:42:28 +0000
changeset 978 175cf8c3a994
parent 921 818510fa3d99
child 986 e997802b855c
permissions -rw-r--r--
"make check" pass under gcc-3.4.3
alpar@741
     1
// -*- mode:C++ -*-
alpar@741
     2
alpar@921
     3
#include <lemon/smart_graph.h>
alpar@921
     4
#include <lemon/maps.h>
alpar@741
     5
#include <vector>
alpar@743
     6
#include <iostream>
alpar@741
     7
alpar@921
     8
using namespace lemon;
alpar@741
     9
alpar@741
    10
struct _BFS_DEFAULT_VIS {};
alpar@741
    11
struct _BFS_CUSTOM_VIS {};
alpar@741
    12
alpar@741
    13
template<class GT,class VT,class DVT,class PNT,class PET,class PT >
alpar@741
    14
class _BFS 
alpar@741
    15
{
alpar@741
    16
 public:
alpar@741
    17
  typedef GT Graph;
alpar@741
    18
  typedef VT Visited;
alpar@741
    19
  typedef PNT PredNode;
alpar@741
    20
  typedef PET PredEdge;
alpar@741
    21
  typedef PT Priority;
alpar@741
    22
  //  typedef QDT QueueData;
alpar@741
    23
  
alpar@741
    24
  typedef typename Graph::Node Node;
alpar@741
    25
  typedef typename Graph::OutEdgeIt OutEdgeIt;
alpar@741
    26
alpar@741
    27
  typedef DVT DefaultVisitedTag;
alpar@741
    28
  
alpar@741
    29
  const Graph &_graph;
alpar@741
    30
alpar@741
    31
  Node _source;
alpar@741
    32
  
alpar@741
    33
  Visited *_visited;
alpar@741
    34
  PredNode _predNode;
alpar@741
    35
  PredEdge _predEdge;
alpar@741
    36
  Priority _priority;
alpar@741
    37
alpar@741
    38
  _BFS(const Graph &g,
alpar@741
    39
       Node s,
alpar@741
    40
       Visited *v,
alpar@741
    41
       PredNode &pn,
alpar@741
    42
       PredEdge &pe,
alpar@741
    43
       Priority &pr) :_graph(g), _source(s),
alpar@741
    44
		     _visited(v), 
alpar@741
    45
		     _predNode(pn), _predEdge(pe), _priority(pr) { }
alpar@741
    46
alpar@741
    47
  
alpar@741
    48
  int run(const _BFS_CUSTOM_VIS &) 
alpar@741
    49
  {
alpar@741
    50
    using namespace std;
alpar@741
    51
    
alpar@741
    52
    int N=_graph.nodeNum();
alpar@741
    53
    vector<Node> Q(N);
alpar@741
    54
    int Qh=0;
alpar@741
    55
    int Qt=0;
alpar@741
    56
    
alpar@945
    57
    for(typename Graph::NodeIt n(_graph);n!=INVALID;++n)
alpar@741
    58
      _visited->set(n,false);
alpar@741
    59
alpar@741
    60
    Q[Qh++]=_source;
alpar@741
    61
    _visited->set(_source,true);
alpar@741
    62
    do {
alpar@741
    63
      Node m;
alpar@741
    64
      Node n=Q[Qt++];
alpar@945
    65
      for(OutEdgeIt e(_graph,n);e!=INVALID;++e)
alpar@741
    66
	if(!(*_visited)[m=_graph.head(e)]) {
alpar@741
    67
	  Q[Qh++]=m;
alpar@741
    68
	  _visited->set(m,true);
alpar@741
    69
	  _predNode.set(m,n);
alpar@741
    70
	  _predEdge.set(m,e);	  
alpar@741
    71
	}
alpar@741
    72
    } while(Qt!=Qh);
alpar@741
    73
alpar@741
    74
    return 1; //Why return 1?
alpar@741
    75
  }
alpar@741
    76
  int run(const _BFS_DEFAULT_VIS &) 
alpar@741
    77
  {
alpar@741
    78
    _visited= new Visited(_graph);
alpar@741
    79
    int r = run(_BFS_CUSTOM_VIS());
alpar@741
    80
    delete _visited;
alpar@741
    81
    return r;
alpar@741
    82
  }
alpar@741
    83
  int run() { return run(DefaultVisitedTag());}
alpar@741
    84
alpar@741
    85
  template<class T> _BFS<Graph,T,_BFS_CUSTOM_VIS,PredNode,PredEdge,Priority>
alpar@741
    86
  setVisitMap(T &t)
alpar@741
    87
  {
alpar@741
    88
    return _BFS<Graph,T,_BFS_CUSTOM_VIS,PredNode,PredEdge,Priority>
alpar@741
    89
      (_graph,_source,&t,_predNode,_predEdge,_priority);
alpar@741
    90
  }
alpar@741
    91
alpar@741
    92
  template<class T>
alpar@743
    93
  _BFS<Graph,Visited,DefaultVisitedTag,T,PredEdge,Priority>
alpar@741
    94
  setPredNodeMap(T &t)
alpar@741
    95
  {
alpar@743
    96
    return _BFS<Graph,Visited,DefaultVisitedTag,T,PredEdge,Priority>
alpar@741
    97
      (_graph,_source,
alpar@741
    98
       _visited,
alpar@741
    99
       t,_predEdge,_priority);
alpar@741
   100
  }
alpar@741
   101
alpar@741
   102
  template<class T>
alpar@743
   103
  _BFS<Graph,Visited,DefaultVisitedTag,PredNode,T,Priority>
alpar@741
   104
  setPredEdgeMap(T &t)
alpar@741
   105
  {
alpar@743
   106
    return _BFS<Graph,Visited,DefaultVisitedTag,PredNode,T,Priority>
alpar@741
   107
      (_graph,_source,
alpar@741
   108
       _visited,
alpar@741
   109
      _predNode,t,_priority);
alpar@741
   110
  }
alpar@741
   111
alpar@743
   112
  _BFS<Graph,Visited,DefaultVisitedTag,PredNode,PredEdge,Priority>
alpar@741
   113
  setNothing()
alpar@741
   114
  {
alpar@743
   115
    return _BFS<Graph,Visited,DefaultVisitedTag,PredNode,PredEdge,Priority>
alpar@741
   116
      (_graph,_source,
alpar@741
   117
       _visited,
alpar@741
   118
       _predNode,_predEdge,_priority);
alpar@741
   119
  }
alpar@741
   120
};
alpar@741
   121
alpar@741
   122
alpar@741
   123
template<class G>
alpar@741
   124
_BFS<G,
alpar@741
   125
     typename G::template NodeMap<bool>,
alpar@741
   126
     _BFS_DEFAULT_VIS,
alpar@741
   127
     NullMap<typename G::Node,typename G::Node>,
alpar@741
   128
     NullMap<typename G::Node,typename G::Edge>,
alpar@741
   129
     NullMap<typename G::Node,int> >
alpar@741
   130
bfs(const G &g,typename G::Node s)
alpar@741
   131
{
alpar@741
   132
  //  typename G::template NodeMap<bool> v(g);
alpar@741
   133
alpar@741
   134
  return _BFS < G,
alpar@741
   135
    typename G::template NodeMap<bool>,
alpar@741
   136
    _BFS_DEFAULT_VIS,
alpar@741
   137
     NullMap<typename G::Node,typename G::Node>,
alpar@741
   138
     NullMap<typename G::Node,typename G::Edge>,
alpar@741
   139
    NullMap<typename G::Node,int> >
alpar@741
   140
    (g,s,
alpar@741
   141
     (typename G::template NodeMap<bool>*)(NULL),
alpar@741
   142
     *((NullMap<typename G::Node,typename G::Node>*)(NULL)),
alpar@741
   143
     *((NullMap<typename G::Node,typename G::Edge> *)(NULL)),
alpar@741
   144
     *((NullMap<typename G::Node,int> *)(NULL))
alpar@741
   145
     );
alpar@741
   146
}
alpar@741
   147
alpar@741
   148
alpar@743
   149
class MyVisitedMap : public SmartGraph::NodeMap<bool>
alpar@743
   150
{
alpar@743
   151
  const SmartGraph &_G;
alpar@743
   152
public:
alpar@743
   153
  MyVisitedMap(const SmartGraph &G) : SmartGraph::NodeMap<bool>(G), _G(G) {}
alpar@743
   154
  void set(SmartGraph::Node n,bool b)
alpar@743
   155
  {
alpar@743
   156
    SmartGraph::NodeMap<bool>::set(n,b);
alpar@743
   157
    if(b) std::cout << _G.id(n) << std::endl;
alpar@743
   158
  }
alpar@743
   159
};
alpar@743
   160
alpar@743
   161
alpar@741
   162
int main()
alpar@741
   163
{
alpar@741
   164
  SmartGraph G;
alpar@743
   165
  SmartGraph::Node s=G.addNode();
alpar@743
   166
  SmartGraph::Node n1=G.addNode();
alpar@743
   167
  SmartGraph::Node n2=G.addNode();
alpar@743
   168
  SmartGraph::Node n3=G.addNode();
alpar@743
   169
  SmartGraph::Node n4=G.addNode();
alpar@743
   170
  SmartGraph::Node n5=G.addNode();
alpar@743
   171
  SmartGraph::Node n6=G.addNode();
alpar@743
   172
  SmartGraph::Node n7=G.addNode();
alpar@743
   173
alpar@743
   174
  G.addEdge(s,n1);G.addEdge(s,n3);G.addEdge(n1,n2);G.addEdge(n1,n3);
alpar@743
   175
  G.addEdge(s,n4);G.addEdge(n4,n7);G.addEdge(n7,n6);G.addEdge(n4,n5);
alpar@743
   176
  G.addEdge(n7,n2);G.addEdge(n6,n3);G.addEdge(n4,s);G.addEdge(n1,s);
alpar@743
   177
alpar@743
   178
  
alpar@743
   179
  
alpar@741
   180
  SmartGraph::NodeMap<SmartGraph::Node> m(G);
alpar@741
   181
  SmartGraph::NodeMap<SmartGraph::Edge> em(G);
alpar@743
   182
alpar@743
   183
  MyVisitedMap vm(G);
alpar@743
   184
alpar@743
   185
alpar@744
   186
  //Runs BFS on graph 'G' from node 's'.
alpar@744
   187
  //(It practically does nothing, for it throws away its result.) 
alpar@744
   188
  bfs(G,s).run(); 
alpar@743
   189
alpar@744
   190
  //Runs BFS on graph 'G' from node 's'. Puts the predessor nodes to 'm'.
alpar@743
   191
  bfs(G,s).setPredNodeMap(m).run();
alpar@743
   192
alpar@744
   193
  //Runs BFS on graph 'G' from node 's'.
alpar@744
   194
  //Puts the predessor nodes to 'm' and the edges of the bfs tree to 'em'.
alpar@743
   195
  bfs(G,s).setPredNodeMap(m).setPredEdgeMap(em).run();
alpar@743
   196
alpar@744
   197
  //Runs BFS on graph 'G' from node 's'.
alpar@744
   198
  //It uses a scpecial 'visited map' that prints out the reached nodes.
alpar@743
   199
  bfs(G,s).setVisitMap(vm).run();
alpar@741
   200
alpar@741
   201
}