src/work/marci_bfs.hh
changeset 280 19f3943521ab
parent 19 3151a1026db9
equal deleted inserted replaced
3:7f9d257b7952 -1:000000000000
     1 #ifndef MARCI_BFS_HH
       
     2 #define MARCI_BFS_HH
       
     3 
       
     4 #include <queue>
       
     5 
       
     6 #include <marci_property_vector.hh>
       
     7 
       
     8 namespace hugo {
       
     9 
       
    10   template <typename graph_type>
       
    11   struct bfs {
       
    12     typedef typename graph_type::node_iterator node_iterator;
       
    13     typedef typename graph_type::edge_iterator edge_iterator;
       
    14     typedef typename graph_type::each_node_iterator each_node_iterator;
       
    15     typedef typename graph_type::out_edge_iterator out_edge_iterator;
       
    16     graph_type& G;
       
    17     node_iterator s;
       
    18     node_property_vector<graph_type, bool> reached;
       
    19     node_property_vector<graph_type, edge_iterator> pred;
       
    20     node_property_vector<graph_type, int> dist;
       
    21     std::queue<node_iterator> bfs_queue;
       
    22     bfs(graph_type& _G, node_iterator _s) : G(_G), s(_s), reached(_G), pred(_G), dist(_G) { 
       
    23       bfs_queue.push(s); 
       
    24       for(each_node_iterator i=G.first_node(); i.valid(); ++i) 
       
    25 	reached.put(i, false);
       
    26       reached.put(s, true);
       
    27       dist.put(s, 0); 
       
    28     }
       
    29     
       
    30     void run() {
       
    31       while (!bfs_queue.empty()) {
       
    32 	node_iterator v=bfs_queue.front();
       
    33 	out_edge_iterator e=G.first_out_edge(v);
       
    34 	bfs_queue.pop();
       
    35 	for( ; e.valid(); ++e) {
       
    36 	  node_iterator w=G.head(e);
       
    37 	  std::cout << "scan node " << G.id(w) << " from node " << G.id(v) << std::endl;
       
    38 	  if (!reached.get(w)) {
       
    39 	    std::cout << G.id(w) << " is newly reached :-)" << std::endl;
       
    40 	    bfs_queue.push(w);
       
    41 	    dist.put(w, dist.get(v)+1);
       
    42 	    pred.put(w, e);
       
    43 	    reached.put(w, true);
       
    44 	  } else {
       
    45 	    std::cout << G.id(w) << " is already reached" << std::endl;
       
    46 	  }
       
    47 	}
       
    48       }
       
    49     }
       
    50   };
       
    51 
       
    52   template <typename graph_type> 
       
    53   struct bfs_visitor {
       
    54     typedef typename graph_type::node_iterator node_iterator;
       
    55     typedef typename graph_type::edge_iterator edge_iterator;
       
    56     typedef typename graph_type::out_edge_iterator out_edge_iterator;
       
    57     graph_type& G;
       
    58     bfs_visitor(graph_type& _G) : G(_G) { }
       
    59     void at_previously_reached(out_edge_iterator& e) { 
       
    60       //node_iterator v=G.tail(e);
       
    61       node_iterator w=G.head(e);
       
    62       std::cout << G.id(w) << " is already reached" << std::endl;
       
    63    }
       
    64     void at_newly_reached(out_edge_iterator& e) { 
       
    65       //node_iterator v=G.tail(e);
       
    66       node_iterator w=G.head(e);
       
    67       std::cout << G.id(w) << " is newly reached :-)" << std::endl;
       
    68     }
       
    69   };
       
    70 
       
    71   template <typename graph_type, typename reached_type, typename visitor_type>
       
    72   struct bfs_iterator {
       
    73     typedef typename graph_type::node_iterator node_iterator;
       
    74     typedef typename graph_type::edge_iterator edge_iterator;
       
    75     typedef typename graph_type::out_edge_iterator out_edge_iterator;
       
    76     graph_type& G;
       
    77     std::queue<out_edge_iterator>& bfs_queue;
       
    78     reached_type& reached;
       
    79     visitor_type& visitor;
       
    80     void process() {
       
    81       while ( !bfs_queue.empty() && !bfs_queue.front().valid() ) { bfs_queue.pop(); } 
       
    82       if (bfs_queue.empty()) return;
       
    83       out_edge_iterator e=bfs_queue.front();
       
    84       //node_iterator v=G.tail(e);
       
    85       node_iterator w=G.head(e);
       
    86       if (!reached.get(w)) {
       
    87 	visitor.at_newly_reached(e);
       
    88 	bfs_queue.push(G.first_out_edge(w));
       
    89 	reached.put(w, true);
       
    90       } else {
       
    91 	visitor.at_previously_reached(e);
       
    92       }
       
    93     }
       
    94     bfs_iterator(graph_type& _G, std::queue<out_edge_iterator>& _bfs_queue, reached_type& _reached, visitor_type& _visitor) : G(_G), bfs_queue(_bfs_queue), reached(_reached), visitor(_visitor) { 
       
    95       //while ( !bfs_queue.empty() && !bfs_queue.front().valid() ) { bfs_queue.pop(); } 
       
    96       valid();
       
    97     }
       
    98     bfs_iterator<graph_type, reached_type, visitor_type>& operator++() { 
       
    99       //while ( !bfs_queue.empty() && !bfs_queue.front().valid() ) { bfs_queue.pop(); } 
       
   100       //if (bfs_queue.empty()) return *this;
       
   101       if (!valid()) return *this;
       
   102       ++(bfs_queue.front());
       
   103       //while ( !bfs_queue.empty() && !bfs_queue.front().valid() ) { bfs_queue.pop(); } 
       
   104       valid();
       
   105       return *this;
       
   106     }
       
   107     //void next() { 
       
   108     //  while ( !bfs_queue.empty() && !bfs_queue.front().valid() ) { bfs_queue.pop(); } 
       
   109     //  if (bfs_queue.empty()) return;
       
   110     //  ++(bfs_queue.front());
       
   111     //  while ( !bfs_queue.empty() && !bfs_queue.front().valid() ) { bfs_queue.pop(); } 
       
   112     //}
       
   113     bool valid() { 
       
   114       while ( !bfs_queue.empty() && !bfs_queue.front().valid() ) { bfs_queue.pop(); } 
       
   115       if (bfs_queue.empty()) return false; else return true;
       
   116     }
       
   117     //bool finished() { 
       
   118     //  while ( !bfs_queue.empty() && !bfs_queue.front().valid() ) { bfs_queue.pop(); } 
       
   119     //  if (bfs_queue.empty()) return true; else return false;
       
   120     //}
       
   121     operator edge_iterator () { return bfs_queue.front(); }
       
   122 
       
   123   };
       
   124 
       
   125   template <typename graph_type, typename reached_type>
       
   126   struct bfs_iterator1 {
       
   127     typedef typename graph_type::node_iterator node_iterator;
       
   128     typedef typename graph_type::edge_iterator edge_iterator;
       
   129     typedef typename graph_type::out_edge_iterator out_edge_iterator;
       
   130     graph_type& G;
       
   131     std::queue<out_edge_iterator>& bfs_queue;
       
   132     reached_type& reached;
       
   133     bool _newly_reached;
       
   134     bfs_iterator1(graph_type& _G, std::queue<out_edge_iterator>& _bfs_queue, reached_type& _reached) : G(_G), bfs_queue(_bfs_queue), reached(_reached) { 
       
   135       valid();
       
   136       if (!bfs_queue.empty() && bfs_queue.front().valid()) { 
       
   137 	out_edge_iterator e=bfs_queue.front();
       
   138 	node_iterator w=G.head(e);
       
   139 	if (!reached.get(w)) {
       
   140 	  bfs_queue.push(G.first_out_edge(w));
       
   141 	  reached.put(w, true);
       
   142 	  _newly_reached=true;
       
   143 	} else {
       
   144 	  _newly_reached=false;
       
   145 	}
       
   146       }
       
   147     }
       
   148     bfs_iterator1<graph_type, reached_type>& operator++() { 
       
   149       if (!valid()) return *this;
       
   150       ++(bfs_queue.front());
       
   151       valid();
       
   152       if (!bfs_queue.empty() && bfs_queue.front().valid()) { 
       
   153 	out_edge_iterator e=bfs_queue.front();
       
   154 	node_iterator w=G.head(e);
       
   155 	if (!reached.get(w)) {
       
   156 	  bfs_queue.push(G.first_out_edge(w));
       
   157 	  reached.put(w, true);
       
   158 	  _newly_reached=true;
       
   159 	} else {
       
   160 	  _newly_reached=false;
       
   161 	}
       
   162       }
       
   163       return *this;
       
   164     }
       
   165     bool valid() { 
       
   166       while ( !bfs_queue.empty() && !bfs_queue.front().valid() ) { bfs_queue.pop(); } 
       
   167       if (bfs_queue.empty()) return false; else return true;
       
   168     }
       
   169     operator edge_iterator () { return bfs_queue.front(); }
       
   170     bool newly_reached() { return _newly_reached; }
       
   171 
       
   172   };
       
   173 
       
   174 } // namespace hugo
       
   175 
       
   176 #endif //MARCI_BFS_HH