Boost logo

Boost-Commit :

From: asutton_at_[hidden]
Date: 2008-08-12 11:36:29


Author: asutton
Date: 2008-08-12 11:36:29 EDT (Tue, 12 Aug 2008)
New Revision: 48102
URL: http://svn.boost.org/trac/boost/changeset/48102

Log:
Added missing (but soon to disappear) depth-first algorithm.
Finished a couple of touches oni the advanced search (i.e., search_for).

Added:
   sandbox/SOC/2008/graphs/trunk/boost/graphs/algorithms/depth_first/algorithm.hpp (contents, props changed)
Text files modified:
   sandbox/SOC/2008/graphs/trunk/boost/graphs/algorithms/advanced_search.hpp | 305 +++++++++++++++++++++++++--------------
   1 files changed, 197 insertions(+), 108 deletions(-)

Modified: sandbox/SOC/2008/graphs/trunk/boost/graphs/algorithms/advanced_search.hpp
==============================================================================
--- sandbox/SOC/2008/graphs/trunk/boost/graphs/algorithms/advanced_search.hpp (original)
+++ sandbox/SOC/2008/graphs/trunk/boost/graphs/algorithms/advanced_search.hpp 2008-08-12 11:36:29 EDT (Tue, 12 Aug 2008)
@@ -1,6 +1,6 @@
 
-#ifndef SEARCH_HPP
-#define SEARCH_HPP
+#ifndef ADVANCED_SEARCH_HPP
+#define ADVANCED_SEARCH_HPP
 
 #include <stack>
 #include <queue>
@@ -12,10 +12,10 @@
 // TODO: One of the big TODO's here is improving the means of constructing
 // visitors. It would be nice to provide a set of functions that build and
 // aggregate visitors so we could do something like:
-// breadth_first_search(g,
+// breadth_first_search(g,
 // on_start_vertex(lambda).
 // on_discover_vertex(labmda));
-// Or something like this. This would probably have to aggregate visitor
+// Or something like this. This would probably have to aggregate visitor
 // functions through some kind visitor aggregator. Not really sure how to do
 // this yet.
 
@@ -24,7 +24,7 @@
  * to implement a number of various algorithms. Visitor functions can basically
  * be divided into two types:
  */
-struct search_visitor
+struct default_search_visitor
 {
     // Called when a search originates from a vertex. This is called once for
     // the root of each search tree.
@@ -86,38 +86,51 @@
     { }
 };
 
-// The default visit predicate always returns true, indicating that the target
-// vertex will be visited (discovered and pushed into the buffer).
-struct default_visit_predicate
-{
+// The default search strategy is the control counterpoint of the search
+// visitor. Specifically, it provides a number of functions that can be
+// implemented to control various aspects of the search. Note that strategies
+// work just like visitors - they are copied into eqch subsequent call.
+struct default_search_strategy
+{
+ // This control point is queried at the top of the search loop when the
+ // search buffer is not empty. Returning false will cause the search to
+ // end prematurely. This control point should not be called when the buffer
+ // is empty.
+ template <typename Graph>
+ inline bool continue_vertices(Graph const& g)
+ { return true; }
+
+ // This control point is queried for each incident of the the vertex v.
+ // The vertex here is the one that was most recently examined. Returning
+ // true will allow the search of edges to continue, returning false will
+ // cause the edge loop to end prematurely.
     template <typename Graph, typename Vertex>
- inline bool operator()(Graph const&, Vertex)
+ inline bool continue_edges(Graph const& g, Vertex v)
     { return true; }
-};
 
-// The default end predicate always returns false, indicating that the search
-// will continue.
-struct default_end_predicate
-{
- template <typename Graph>
- inline bool operator()(Graph const&)
- { return false; }
+ // This control point is when when a previousl undiscovered (white) vertex
+ // is found for the first time. Returning true allows the discovery of the
+ // vertex, returning false will prevent the search from proceeding along
+ // this edge.
+ template <typename Graph, typename Vertex>
+ inline bool allow_discovery(Graph const& g, Vertex v)
+ { return true; }
 };
 
 namespace detail
 {
- // TODO: We need a concept that abstracts stacks and queues into a in/out
+ // TODO: We need a concept that abstracts stacks and queues into a in/out
     // search buffer. Concept maps can easily provide default functions for
     // these things - or build a concept-class. For now, we're just sticking
     // a couple of overloads in this namespace.
 #if BOOST_HAS_CONCEPTS
-concept InOutSequence<typename Container>
+concept InOutBuffer<typename Container>
 {
     typename value_type;
-
+
     void push(Container& c, value_type const& x)
     { c.push(x); }
-
+
     void pop(Container& c)
     { c.pop(); }
 
@@ -125,24 +138,24 @@
 };
 
 template <typename T, typename Container>
-concept_map InOutSequence<std::stack<T, Container>>
+concept_map InOutBuffer<std::stack<T, Container>>
 {
     typedef std::stack<T, Container>::value_type value_type;
-
+
     value_type const& peek(std::stack<T, Container>& c)
     { return c.top(); }
 };
 
 template <typename T, typename Container>
-concept_map InOutSequence<std::queue<T, Container>>
+concept_map InOutBuffer<std::queue<T, Container>>
 {
     typedef std::queue<T, Container>::value_type value_type;
-
+
     value_type const& peek(std::queue<T, Container>& c)
     { return c.front(); }
 };
 #endif
-
+
     // Adapters for getting the current element of a buffer.
     template <typename T, typename Seq>
     inline T& peek(std::stack<T, Seq>& s)
@@ -157,34 +170,34 @@
  * Examine the edge e rooted at vertex u to determine the search action to be
  * taken (or not) for the opposite vertex.
  *
- * The visit predicate is called to determine if undiscovered (white) vertices
+ * The visit predicate is called to determine if undiscovered (white) vertices
  * should be visited. Default search actions will always visit white vertices,
  * but these visits can be constrained or deferred by providing a predicate
  * that examines the vertex and returns false.
  *
  * @requires ReadWritePropertyMap<ColorMap>
- * @requires InOutSequence<Buffer>
+ * @requires InOutBuffer<Buffer>
  * @requires Predicate<VisitPredicate, Graph, Vertex>
  *
  * @requires SameType<ColorMap::key_type, Vertex>
  * @requires SameType<Buffer::value_type, Vertex>
  */
 template <
- typename Graph,
- typename Vertex,
- typename Edge,
- typename Visitor,
+ typename Graph,
+ typename Vertex,
+ typename Edge,
     typename ColorMap,
     typename Buffer,
- typename VisitPredicate>
+ typename Visitor,
+ typename Strategy>
 void
-search_edge(Graph const& g,
- Vertex u,
- Edge e,
- Visitor vis,
- ColorMap color,
+search_edge(Graph const& g,
+ Vertex u,
+ Edge e,
+ ColorMap color,
             Buffer& buf,
- VisitPredicate visit)
+ Visitor vis,
+ Strategy strat)
 {
     typedef color_traits<typename ColorMap::value_type> ColorTraits;
 
@@ -195,7 +208,7 @@
     // Vertices are only visited if the visit() predicate returns true.
     Vertex v = e.target();
     typename ColorMap::value_type c = color(v);
- if(c == ColorTraits::white() && visit(g, v)) {
+ if(c == ColorTraits::white() && strat.allow_discovery(g, v)) {
         color(v, ColorTraits::gray());
         buf.push(v);
 
@@ -216,19 +229,19 @@
 }
 
 template <
- typename Graph,
- typename Vertex,
- typename Visitor,
- typename ColorMap,
+ typename Graph,
+ typename Vertex,
+ typename ColorMap,
     typename Buffer,
- typename VisitPredicate>
+ typename Visitor,
+ typename Strategy>
 void
-search_vertex(Graph const& g,
- Vertex u,
- Visitor vis,
- ColorMap color,
+search_vertex(Graph const& g,
+ Vertex u,
+ ColorMap color,
               Buffer& buf,
- VisitPredicate visit)
+ Visitor vis,
+ Strategy strat)
 {
     typedef color_traits<typename ColorMap::value_type> ColorTraits;
     typedef typename Graph::edge_descriptor Edge;
@@ -237,11 +250,12 @@
     // Examine the vertex.
     vis.examine_vertex(g, u);
 
- // Visit adjacent vertices
+ // Visit adjacent vertices.
     EdgeRange edges = g.incident_edges(u);
- for( ; edges.first != edges.second; ++edges.first) {
+ while(edges.first != edges.second && strat.continue_edges(g, u)) {
         directional_edge<Edge> e(*edges.first, u);
- search_edge(g, u, e, vis, color, buf, visit);
+ search_edge(g, u, e, color, buf, vis, strat);
+ ++edges.first;
     }
     color(u, ColorTraits::black());
     vis.finish_vertex(g, u);
@@ -252,7 +266,7 @@
  * over the vertices given in the queue. This is done by popping a vertex out
  * of the buffer, and searching its adjacent neighbors.
  *
- * The visit predicate is called to determine if undiscovered (white) vertices
+ * The visit predicate is called to determine if undiscovered (white) vertices
  * should be visited. Default search actions will always visit white vertices,
  * but these visits can be constrained or deferred by providing a predicate
  * that examines the vertex and returns false.
@@ -266,27 +280,25 @@
  * @requries Predicate<EndPredicate, Graph>
  */
 template <
- typename Graph,
- typename Visitor,
- typename ColorMap,
+ typename Graph,
+ typename ColorMap,
     typename Buffer,
- typename VisitPredicate,
- typename EndPredicate>
+ typename Visitor,
+ typename Strategy>
 void
-search_vertices(Graph const& g,
- Visitor vis,
- ColorMap color,
+search_vertices(Graph const& g,
+ ColorMap color,
                 Buffer& buf,
- VisitPredicate visit,
- EndPredicate end)
+ Visitor vis,
+ Strategy strat)
 {
     typedef typename Graph::vertex_descriptor Vertex;
 
     // Continue the search until we're done with the buf.
- while(!buf.empty() && !end(g)) {
+ while(!buf.empty() && strat.continue_vertices(g)) {
         Vertex u = detail::peek(buf);
         buf.pop();
- search_vertex(g, u, vis, color, buf, visit);
+ search_vertex(g, u, color, buf, vis, strat);
     }
 }
 
@@ -294,21 +306,19 @@
  * Search from the given vertex to all others connected to it.
  */
 template <
- typename Graph,
- typename Vertex,
- typename Visitor,
- typename ColorMap,
+ typename Graph,
+ typename Vertex,
+ typename ColorMap,
     typename Buffer,
- typename VisitPredicate,
- typename EndPredicate>
+ typename Visitor = default_search_visitor,
+ typename Strategy = default_search_strategy>
 void
-search_from_vertex(Graph const& g,
- Vertex start,
- Visitor vis,
- ColorMap color,
+search_from_vertex(Graph const& g,
+ Vertex start,
+ ColorMap color,
                    Buffer& buf,
- VisitPredicate visit = default_visit_predicate(),
- EndPredicate end = default_end_predicate())
+ Visitor vis = Visitor(),
+ Strategy strat = Strategy())
 {
     typedef color_traits<typename ColorMap::value_type> ColorTraits;
 
@@ -317,42 +327,40 @@
     buf.push(start);
     vis.start_vertex(g, start);
     vis.discover_vertex(g, start);
- search_vertices(g, vis, color, buf, visit, end);
+ search_vertices(g, color, buf, vis, strat);
 }
 
 /**
- * Perform a multi-root search from the vertices given in the range [f, l).
+ * Perform a multi-root search from the vertices given in the range [f, l).
  * This is done by seeding the search buffer with the given vertices prior
  * to executing a standard search.
  */
 template <
- typename Graph,
- typename Iter,
- typename Visitor,
- typename ColorMap,
- typename Buffer,
- typename VisitPredicate,
- typename EndPredicate>
+ typename Graph,
+ typename Iter,
+ typename Visitor,
+ typename ColorMap,
+ typename Buffer = default_search_visitor,
+ typename Strategy = default_search_strategy>
 void
-search_from_vertices(Graph const& g,
- Iter f, Iter l,
- Visitor vis,
- ColorMap color,
+search_from_vertices(Graph const& g,
+ Iter first, Iter last,
+ ColorMap color,
                      Buffer buf,
- VisitPredicate visit = default_visit_predicate(),
- EndPredicate end = default_end_predicate())
+ Visitor vis = Visitor(),
+ Strategy strat = Strategy())
 {
     typedef color_traits<typename ColorMap::value_type> ColorTraits;
     typedef typename Graph::vertex_descriptor Vertex;
 
- for( ; f != l; ++f) {
- Vertex v = *f;
+ for( ; first != last; ++first) {
+ Vertex v = *first;
         color(v, ColorTraits::gray());
         buf.push(v);
         vis.start_vertex(g, v);
         vis.discover_vertex(g, v);
     }
- search_vertices(g, vis, color, buf, visit, end);
+ search_vertices(g, color, buf, vis, strat);
 }
 
 /**
@@ -362,19 +370,17 @@
  * vertex set of the graph.
  */
 template <
- typename Graph,
- typename Visitor,
- typename Buffer,
+ typename Graph,
     typename ColorMap,
- typename VisitPredicate,
- typename EndPredicate>
+ typename Buffer,
+ typename Visitor = default_search_visitor,
+ typename Strategy = default_search_strategy>
 void
-search_graph(Graph const& g,
- Visitor vis,
- ColorMap color,
+search_graph(Graph const& g,
+ ColorMap color,
              Buffer& buf,
- VisitPredicate visit = default_visit_predicate(),
- EndPredicate end = default_end_predicate())
+ Visitor vis = Visitor(),
+ Strategy strat = Strategy())
 {
     typedef color_traits<typename ColorMap::value_type> ColorTraits;
     typedef typename Graph::vertex_descriptor Vertex;
@@ -388,9 +394,92 @@
             // out edges, but can be reached from some other vertex v'. Here,
             // v will not be part of the tree rooted by v' even though it is
             // reachable.
- search_from_vertex(g, v, vis, color, buf, visit, end);
+ search_from_vertex(g, v, color, buf, vis, strat);
         }
     }
 }
 
+// The search_for() functions use a specific search strategy that terminates
+// the search when a target vertex is located.
+
+// This strategy will continue the search until the target vertex has been
+// found. This strategy does not visit the target vertex.
+template <typename Graph, typename Vertex>
+struct search_for_strategy
+{
+ search_for_strategy(Vertex const& v, bool& f)
+ : target(v), found(f)
+ { }
+
+ // Return true if the target vertex has been found.
+ inline bool continue_vertices(Graph const& g)
+ { return !found; }
+
+ inline bool continue_edges(Graph const& g, Vertex v)
+ { return !found; }
+
+ // Set found to true if the target vertex has been found. Return
+ inline bool allow_discovery(Graph const& g, Vertex v)
+ {
+ if(v == target) found = true;
+ return !found;
+ }
+
+ Vertex const& target;
+ bool& found;
+};
+
+/**
+ * Search for the target vertex tgt starting from the source vertex src. This
+ * function returns true if the vertex is found, false otherwise.
+ *
+ * This works best as a BFS.
+ */
+template <
+ typename Graph,
+ typename Vertex,
+ typename ColorMap,
+ typename Buffer,
+ typename Visitor = default_search_visitor>
+bool
+search_for(Graph const& g,
+ Vertex src,
+ Vertex tgt,
+ ColorMap color,
+ Buffer& buf,
+ Visitor vis = Visitor())
+{
+ bool found = (src == tgt);
+ search_for_strategy<Graph, Vertex> strat(tgt, found);
+ search_from_vertex(g, src, color, buf, vis, strat);
+ return strat.found;
+}
+
+/**
+ * Search for the target vertex tgt starting from the vertices given in the
+ * range [first, last). Return true if the vertex is found, false otherwise.
+ *
+ * This works best as a BFS.
+ */
+template <
+ typename Graph,
+ typename Vertex,
+ typename Iter,
+ typename ColorMap,
+ typename Buffer,
+ typename Visitor = default_search_visitor>
+bool
+search_for(Graph const& g,
+ Iter first, Iter last,
+ Vertex tgt,
+ ColorMap color,
+ Buffer& buf,
+ Visitor vis = Visitor())
+{
+ bool found = (std::find(first, last, tgt) != last);
+ search_for_strategy<Graph, Vertex> strat(tgt, found);
+ search_from_vertices(g, first, last, color, buf, vis, strat);
+ return strat.found;
+}
+
 #endif

Added: sandbox/SOC/2008/graphs/trunk/boost/graphs/algorithms/depth_first/algorithm.hpp
==============================================================================
--- (empty file)
+++ sandbox/SOC/2008/graphs/trunk/boost/graphs/algorithms/depth_first/algorithm.hpp 2008-08-12 11:36:29 EDT (Tue, 12 Aug 2008)
@@ -0,0 +1,120 @@
+
+#ifndef DEPTH_FIRST_ALGORITHM_HPP
+#define DEPTH_FIRST_ALGORITHM_HPP
+
+#include <stack>
+
+template <typename Graph, typename Vertex, typename Edge, typename Visitor, typename ColorMap, typename Stack>
+void
+depth_first_visit_edge(Graph const& g, Vertex u, Edge e, Visitor vis, ColorMap color, Stack& stack)
+{
+ typedef color_traits<typename ColorMap::value_type> ColorTraits;
+
+ // Examine the edge before checking it.
+ vis.examine_edge(g, e);
+
+ // Look at the color of the target vertex and decide what to do with it.
+ Vertex v = e.target();
+ typename ColorMap::value_type c = color(v);
+ if(c == ColorTraits::white()) {
+ color(v) = ColorTraits::gray();
+ stack.push(v);
+
+ // Discover the vertex and claim that its a tree edge.
+ vis.discover_vertex(g, v);
+ vis.tree_edge(g, e);
+ }
+ else {
+ // Handle other cases - nontree edges, gray targets, black, etc.
+ if(c == ColorTraits::gray()) {
+ vis.back_edge(g, e);
+ }
+ else {
+ vis.cross_edge(g, e);
+ }
+ }
+}
+
+template <typename Graph, typename Vertex, typename Visitor, typename ColorMap, typename Stack>
+void
+depth_first_visit_vertex(Graph const& g, Vertex u, Visitor vis, ColorMap color, Stack& stack)
+{
+ typedef color_traits<typename ColorMap::value_type> ColorTraits;
+ typedef typename Graph::edge_descriptor Edge;
+ typedef typename Graph::incident_edge_range EdgeRange;
+
+ // Examine the vertex.
+ vis.examine_vertex(g, u);
+
+ // Visit adjacent vertices
+ EdgeRange edges = g.incident_edges(u);
+ for( ; edges.first != edges.second; ++edges.first) {
+ directional_edge<Edge> e(*edges.first, u);
+ depth_first_visit_edge(g, u, e, vis, color, stack);
+ }
+ color(u) = ColorTraits::black();
+ vis.finish_vertex(g, u);
+}
+
+template <typename Graph, typename Visitor, typename ColorMap, typename Stack>
+void
+depth_first_walk(Graph const& g, Visitor vis, ColorMap color, Stack& stack)
+{
+ typedef typename Graph::vertex_descriptor Vertex;
+
+ // Continue the search until we're done with the stack.
+ while(!stack.empty()) {
+ Vertex u = stack.top();
+ stack.pop();
+ depth_first_visit_vertex(g, u, vis, color, stack);
+ }
+}
+
+template <
+ typename Graph,
+ typename Vertex,
+ typename Visitor,
+ typename ColorMap = optional_vertex_map<Graph, color>,
+ typename Stack = std::stack<typename Graph::vertex_descriptor>>
+void
+depth_first_visit(Graph const& g, Vertex start, Visitor vis, ColorMap color = ColorMap(), Stack stack = Stack())
+{
+ typedef color_traits<typename ColorMap::value_type> ColorTraits;
+ typedef typename Graph::edge_descriptor Edge;
+ typedef typename Graph::incident_edge_range EdgeRange;
+
+ detail::optional_prop_init(g, color, ColorTraits::white());
+
+ // Initialize the start vertex and put it in the stack.
+ color(start) = ColorTraits::gray();
+ stack.push(start);
+ vis.discover_vertex(g, start);
+ depth_first_walk(g, vis, color, stack);
+}
+
+template <
+ typename Graph,
+ typename Iter,
+ typename Visitor,
+ typename ColorMap = optional_vertex_map<Graph, color>,
+ typename Stack = std::stack<typename Graph::vertex_descriptor>>
+void
+depth_first_visit(Graph const& g, Iter f, Iter l, Visitor vis, ColorMap color = ColorMap(), Stack stack = Stack())
+{
+ typedef color_traits<typename ColorMap::value_type> ColorTraits;
+ typedef typename Graph::vertex_descriptor Vertex;
+
+ detail::optional_prop_init(g, color, ColorTraits::white());
+
+ // Initialize the start vertices and put them into the stack.
+ for( ; f != l; ++f) {
+ Vertex v = *f;
+ color(v) = ColorTraits::gray();
+ stack.push(v);
+ vis.discover_vertex(g, *f);
+ }
+ depth_first_walk(g, vis, color, stack);
+}
+
+
+#endif


Boost-Commit list run by bdawes at acm.org, david.abrahams at rcn.com, gregod at cs.rpi.edu, cpdaniel at pacbell.net, john at johnmaddock.co.uk