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