# HG changeset patch # User marci # Date 1075474086 0 # Node ID 3ee2187d6342231d41d9d9e655d0f8d93f8daa87 # Parent 67f73b15855d163177803f63bb9365f61e8be0ce marci_bfs.hh in the new, upper-case concept, and som further improvements diff -r 67f73b15855d -r 3ee2187d6342 src/work/bfs_iterator.hh --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/work/bfs_iterator.hh Fri Jan 30 14:48:06 2004 +0000 @@ -0,0 +1,400 @@ +#ifndef MARCI_BFS_HH +#define MARCI_BFS_HH + +#include +#include + +namespace marci { + + template + struct bfs { + typedef typename Graph::NodeIt NodeIt; + typedef typename Graph::EdgeIt EdgeIt; + typedef typename Graph::EachNodeIt EachNodeIt; + typedef typename Graph::OutEdgeIt OutEdgeIt; + Graph& G; + NodeIt s; + typename Graph::NodeMap reached; + typename Graph::NodeMap pred; + typename Graph::NodeMap dist; + std::queue bfs_queue; + bfs(Graph& _G, NodeIt _s) : G(_G), s(_s), reached(_G), pred(_G), dist(_G) { + bfs_queue.push(s); + for(EachNodeIt i=G.template first(); i.valid(); ++i) + reached.set(i, false); + reached.set(s, true); + dist.set(s, 0); + } + + void run() { + while (!bfs_queue.empty()) { + NodeIt v=bfs_queue.front(); + OutEdgeIt e=G.template first(v); + bfs_queue.pop(); + for( ; e.valid(); ++e) { + NodeIt w=G.bNode(e); + std::cout << "scan node " << G.id(w) << " from node " << G.id(v) << std::endl; + if (!reached.get(w)) { + std::cout << G.id(w) << " is newly reached :-)" << std::endl; + bfs_queue.push(w); + dist.set(w, dist.get(v)+1); + pred.set(w, e); + reached.set(w, true); + } else { + std::cout << G.id(w) << " is already reached" << std::endl; + } + } + } + } + }; + + template + struct bfs_visitor { + typedef typename Graph::NodeIt NodeIt; + typedef typename Graph::EdgeIt EdgeIt; + typedef typename Graph::OutEdgeIt OutEdgeIt; + Graph& G; + bfs_visitor(Graph& _G) : G(_G) { } + void at_previously_reached(OutEdgeIt& e) { + //NodeIt v=G.aNode(e); + NodeIt w=G.bNode(e); + std::cout << G.id(w) << " is already reached" << std::endl; + } + void at_newly_reached(OutEdgeIt& e) { + //NodeIt v=G.aNode(e); + NodeIt w=G.bNode(e); + std::cout << G.id(w) << " is newly reached :-)" << std::endl; + } + }; + + template + struct bfs_iterator { + typedef typename Graph::NodeIt NodeIt; + typedef typename Graph::EdgeIt EdgeIt; + typedef typename Graph::OutEdgeIt OutEdgeIt; + Graph& G; + std::queue& bfs_queue; + ReachedMap& reached; + visitor_type& visitor; + void process() { + while ( !bfs_queue.empty() && !bfs_queue.front().valid() ) { bfs_queue.pop(); } + if (bfs_queue.empty()) return; + OutEdgeIt e=bfs_queue.front(); + //NodeIt v=G.aNode(e); + NodeIt w=G.bNode(e); + if (!reached.get(w)) { + visitor.at_newly_reached(e); + bfs_queue.push(G.template first(w)); + reached.set(w, true); + } else { + visitor.at_previously_reached(e); + } + } + bfs_iterator(Graph& _G, std::queue& _bfs_queue, ReachedMap& _reached, visitor_type& _visitor) : G(_G), bfs_queue(_bfs_queue), reached(_reached), visitor(_visitor) { + //while ( !bfs_queue.empty() && !bfs_queue.front().valid() ) { bfs_queue.pop(); } + valid(); + } + bfs_iterator& operator++() { + //while ( !bfs_queue.empty() && !bfs_queue.front().valid() ) { bfs_queue.pop(); } + //if (bfs_queue.empty()) return *this; + if (!valid()) return *this; + ++(bfs_queue.front()); + //while ( !bfs_queue.empty() && !bfs_queue.front().valid() ) { bfs_queue.pop(); } + valid(); + return *this; + } + //void next() { + // while ( !bfs_queue.empty() && !bfs_queue.front().valid() ) { bfs_queue.pop(); } + // if (bfs_queue.empty()) return; + // ++(bfs_queue.front()); + // while ( !bfs_queue.empty() && !bfs_queue.front().valid() ) { bfs_queue.pop(); } + //} + bool valid() { + while ( !bfs_queue.empty() && !bfs_queue.front().valid() ) { bfs_queue.pop(); } + if (bfs_queue.empty()) return false; else return true; + } + //bool finished() { + // while ( !bfs_queue.empty() && !bfs_queue.front().valid() ) { bfs_queue.pop(); } + // if (bfs_queue.empty()) return true; else return false; + //} + operator EdgeIt () { return bfs_queue.front(); } + + }; + + template + struct bfs_iterator1 { + typedef typename Graph::NodeIt NodeIt; + typedef typename Graph::EdgeIt EdgeIt; + typedef typename Graph::OutEdgeIt OutEdgeIt; + Graph& G; + std::queue& bfs_queue; + ReachedMap& reached; + bool _newly_reached; + bfs_iterator1(Graph& _G, std::queue& _bfs_queue, ReachedMap& _reached) : G(_G), bfs_queue(_bfs_queue), reached(_reached) { + valid(); + if (!bfs_queue.empty() && bfs_queue.front().valid()) { + OutEdgeIt e=bfs_queue.front(); + NodeIt w=G.bNode(e); + if (!reached.get(w)) { + bfs_queue.push(G.template first(w)); + reached.set(w, true); + _newly_reached=true; + } else { + _newly_reached=false; + } + } + } + bfs_iterator1& operator++() { + if (!valid()) return *this; + ++(bfs_queue.front()); + valid(); + if (!bfs_queue.empty() && bfs_queue.front().valid()) { + OutEdgeIt e=bfs_queue.front(); + NodeIt w=G.bNode(e); + if (!reached.get(w)) { + bfs_queue.push(G.template first(w)); + reached.set(w, true); + _newly_reached=true; + } else { + _newly_reached=false; + } + } + return *this; + } + bool valid() { + while ( !bfs_queue.empty() && !bfs_queue.front().valid() ) { bfs_queue.pop(); } + if (bfs_queue.empty()) return false; else return true; + } + operator OutEdgeIt() { return bfs_queue.front(); } + //ize + bool newly_reached() { return _newly_reached; } + + }; + + template + struct BfsIterator { + typedef typename Graph::NodeIt NodeIt; + Graph& G; + std::queue& bfs_queue; + ReachedMap& reached; + bool b_node_newly_reached; + OutEdgeIt actual_edge; + BfsIterator(Graph& _G, + std::queue& _bfs_queue, + ReachedMap& _reached) : + G(_G), bfs_queue(_bfs_queue), reached(_reached) { + actual_edge=bfs_queue.front(); + if (actual_edge.valid()) { + NodeIt w=G.bNode(actual_edge); + if (!reached.get(w)) { + bfs_queue.push(G.firstOutEdge(w)); + reached.set(w, true); + b_node_newly_reached=true; + } else { + b_node_newly_reached=false; + } + } + } + BfsIterator& + operator++() { + if (bfs_queue.front().valid()) { + ++(bfs_queue.front()); + actual_edge=bfs_queue.front(); + if (actual_edge.valid()) { + NodeIt w=G.bNode(actual_edge); + if (!reached.get(w)) { + bfs_queue.push(G.firstOutEdge(w)); + reached.set(w, true); + b_node_newly_reached=true; + } else { + b_node_newly_reached=false; + } + } + } else { + bfs_queue.pop(); + actual_edge=bfs_queue.front(); + if (actual_edge.valid()) { + NodeIt w=G.bNode(actual_edge); + if (!reached.get(w)) { + bfs_queue.push(G.firstOutEdge(w)); + reached.set(w, true); + b_node_newly_reached=true; + } else { + b_node_newly_reached=false; + } + } + } + return *this; + } + bool finished() { return bfs_queue.empty(); } + operator OutEdgeIt () { return actual_edge; } + bool bNodeIsNewlyReached() { return b_node_newly_reached; } + bool aNodeIsExamined() { return !(actual_edge.valid()); } + }; + + + template + struct DfsIterator { + typedef typename Graph::NodeIt NodeIt; + Graph& G; + std::stack& bfs_queue; + ReachedMap& reached; + bool b_node_newly_reached; + OutEdgeIt actual_edge; + DfsIterator(Graph& _G, + std::stack& _bfs_queue, + ReachedMap& _reached) : + G(_G), bfs_queue(_bfs_queue), reached(_reached) { + actual_edge=bfs_queue.top(); + if (actual_edge.valid()) { + NodeIt w=G.bNode(actual_edge); + if (!reached.get(w)) { + bfs_queue.push(G.firstOutEdge(w)); + reached.set(w, true); + b_node_newly_reached=true; + } else { + ++(bfs_queue.top()); + b_node_newly_reached=false; + } + } else { + bfs_queue.pop(); + } + } + DfsIterator& + operator++() { + actual_edge=bfs_queue.top(); + if (actual_edge.valid()) { + NodeIt w=G.bNode(actual_edge); + if (!reached.get(w)) { + bfs_queue.push(G.firstOutEdge(w)); + reached.set(w, true); + b_node_newly_reached=true; + } else { + ++(bfs_queue.top()); + b_node_newly_reached=false; + } + } else { + bfs_queue.pop(); + } + return *this; + } + bool finished() { return bfs_queue.empty(); } + operator OutEdgeIt () { return actual_edge; } + bool bNodeIsNewlyReached() { return b_node_newly_reached; } + bool aNodeIsLeaved() { return !(actual_edge.valid()); } + }; + + template + struct BfsIterator1 { + typedef typename Graph::NodeIt NodeIt; + Graph& G; + std::queue& bfs_queue; + ReachedMap& reached; + bool b_node_newly_reached; + OutEdgeIt actual_edge; + BfsIterator1(Graph& _G, + std::queue& _bfs_queue, + ReachedMap& _reached) : + G(_G), bfs_queue(_bfs_queue), reached(_reached) { + actual_edge=bfs_queue.front(); + if (actual_edge.valid()) { + NodeIt w=G.bNode(actual_edge); + if (!reached.get(w)) { + bfs_queue.push(OutEdgeIt(G, w)); + reached.set(w, true); + b_node_newly_reached=true; + } else { + b_node_newly_reached=false; + } + } + } + void next() { + if (bfs_queue.front().valid()) { + ++(bfs_queue.front()); + actual_edge=bfs_queue.front(); + if (actual_edge.valid()) { + NodeIt w=G.bNode(actual_edge); + if (!reached.get(w)) { + bfs_queue.push(OutEdgeIt(G, w)); + reached.set(w, true); + b_node_newly_reached=true; + } else { + b_node_newly_reached=false; + } + } + } else { + bfs_queue.pop(); + actual_edge=bfs_queue.front(); + if (actual_edge.valid()) { + NodeIt w=G.bNode(actual_edge); + if (!reached.get(w)) { + bfs_queue.push(OutEdgeIt(G, w)); + reached.set(w, true); + b_node_newly_reached=true; + } else { + b_node_newly_reached=false; + } + } + } + //return *this; + } + bool finished() { return bfs_queue.empty(); } + operator OutEdgeIt () { return actual_edge; } + bool bNodeIsNewlyReached() { return b_node_newly_reached; } + bool aNodeIsExamined() { return !(actual_edge.valid()); } + }; + + + template + struct DfsIterator1 { + typedef typename Graph::NodeIt NodeIt; + Graph& G; + std::stack& bfs_queue; + ReachedMap& reached; + bool b_node_newly_reached; + OutEdgeIt actual_edge; + DfsIterator1(Graph& _G, + std::stack& _bfs_queue, + ReachedMap& _reached) : + G(_G), bfs_queue(_bfs_queue), reached(_reached) { + //actual_edge=bfs_queue.top(); + //if (actual_edge.valid()) { + // NodeIt w=G.bNode(actual_edge); + //if (!reached.get(w)) { + // bfs_queue.push(OutEdgeIt(G, w)); + // reached.set(w, true); + // b_node_newly_reached=true; + //} else { + // ++(bfs_queue.top()); + // b_node_newly_reached=false; + //} + //} else { + // bfs_queue.pop(); + //} + } + void next() { + actual_edge=bfs_queue.top(); + if (actual_edge.valid()) { + NodeIt w=G.bNode(actual_edge); + if (!reached.get(w)) { + bfs_queue.push(OutEdgeIt(G, w)); + reached.set(w, true); + b_node_newly_reached=true; + } else { + ++(bfs_queue.top()); + b_node_newly_reached=false; + } + } else { + bfs_queue.pop(); + } + //return *this; + } + bool finished() { return bfs_queue.empty(); } + operator OutEdgeIt () { return actual_edge; } + bool bNodeIsNewlyReached() { return b_node_newly_reached; } + bool aNodeIsLeaved() { return !(actual_edge.valid()); } + }; + +} // namespace marci + +#endif //MARCI_BFS_HH