annotate DEPENDENCIES/generic/include/boost/graph/loop_erased_random_walk.hpp @ 133:4acb5d8d80b6 tip

Don't fail environmental check if README.md exists (but .txt and no-suffix don't)
author Chris Cannam
date Tue, 30 Jul 2019 12:25:44 +0100
parents 2665513ce2d3
children
rev   line source
Chris@16 1 // Copyright 2010 The Trustees of Indiana University.
Chris@16 2
Chris@16 3 // Distributed under the Boost Software License, Version 1.0.
Chris@16 4 // (See accompanying file LICENSE_1_0.txt or copy at
Chris@16 5 // http://www.boost.org/LICENSE_1_0.txt)
Chris@16 6
Chris@16 7 // Authors: Jeremiah Willcock
Chris@16 8 // Andrew Lumsdaine
Chris@16 9
Chris@16 10 #ifndef BOOST_GRAPH_LOOP_ERASED_RANDOM_WALK_HPP
Chris@16 11 #define BOOST_GRAPH_LOOP_ERASED_RANDOM_WALK_HPP
Chris@16 12
Chris@16 13 #include <boost/graph/graph_traits.hpp>
Chris@16 14 #include <boost/graph/properties.hpp>
Chris@16 15 #include <boost/graph/random.hpp>
Chris@16 16 #include <boost/next_prior.hpp>
Chris@16 17 #include <vector>
Chris@16 18 #include <boost/assert.hpp>
Chris@16 19
Chris@16 20 namespace boost {
Chris@16 21
Chris@16 22 struct loop_erased_random_walk_stuck : public std::exception {
Chris@16 23 virtual ~loop_erased_random_walk_stuck() throw() {}
Chris@16 24 inline virtual const char* what() const throw() {
Chris@16 25 return "Loop-erased random walk found a vertex with no out-edges";
Chris@16 26 }
Chris@16 27 };
Chris@16 28
Chris@16 29 // Do a loop-erased random walk from vertex s to any vertex colored black (or
Chris@16 30 // actually any color other than white or gray) in the color map. The color
Chris@16 31 // white is for vertices that are not part of the path, while gray is for
Chris@16 32 // those that are on the path (for cycle detection). The vector path is used
Chris@16 33 // for temporary storage and as the result of the algorithm; while all
Chris@16 34 // elements of the path except the last have their colors set to gray upon
Chris@16 35 // return. Vertex s must start off colored white.
Chris@16 36 //
Chris@16 37 // Useful references:
Chris@16 38 // http://everything2.com/title/loop-erased+random+walk
Chris@16 39 // Wikipedia page on "Loop-Erased Random Walk"
Chris@16 40
Chris@16 41 template <typename Graph, typename ColorMap, typename NextEdge>
Chris@16 42 void loop_erased_random_walk(
Chris@16 43 const Graph& g,
Chris@16 44 typename boost::graph_traits<Graph>::vertex_descriptor s,
Chris@16 45 NextEdge next_edge,
Chris@16 46 ColorMap color,
Chris@16 47 std::vector<typename boost::graph_traits<Graph>::vertex_descriptor>& path
Chris@16 48 ) {
Chris@16 49 typedef typename boost::graph_traits<Graph>::vertex_descriptor vertex_descriptor;
Chris@16 50 typedef typename boost::graph_traits<Graph>::edge_descriptor edge_descriptor;
Chris@16 51 typedef typename boost::property_traits<ColorMap>::value_type color_t;
Chris@16 52 typedef boost::color_traits<color_t> color_gen;
Chris@16 53
Chris@16 54 BOOST_ASSERT (get(color, s) == color_gen::white());
Chris@16 55 path.clear();
Chris@16 56 path.push_back(s);
Chris@16 57 put(color, s, color_gen::gray());
Chris@16 58 while (true) {
Chris@16 59 edge_descriptor e = next_edge(s, g);
Chris@16 60 vertex_descriptor t = target(e, g);
Chris@16 61 color_t t_color = get(color, t);
Chris@16 62 if (t_color == color_gen::white()) {
Chris@16 63 path.push_back(t);
Chris@16 64 put(color, t, color_gen::gray());
Chris@16 65 s = t;
Chris@16 66 } else if (t_color == color_gen::gray()) {
Chris@16 67 // Found a loop; delete from path from the first occurrence of t to the
Chris@16 68 // end, coloring vertices white.
Chris@16 69 typename std::vector<vertex_descriptor>::iterator it = std::find(path.begin(), path.end(), t);
Chris@16 70 BOOST_ASSERT (it != path.end());
Chris@16 71 ++it;
Chris@16 72 for (typename std::vector<vertex_descriptor>::iterator j = it; j != path.end(); ++j) {
Chris@16 73 put(color, *j, color_gen::white());
Chris@16 74 }
Chris@16 75 path.erase(it, path.end());
Chris@16 76 s = t;
Chris@16 77 } else {
Chris@16 78 // Done
Chris@16 79 path.push_back(t);
Chris@16 80 break;
Chris@16 81 }
Chris@16 82 }
Chris@16 83 }
Chris@16 84
Chris@16 85 template <typename Graph, typename Gen>
Chris@16 86 class unweighted_random_out_edge_gen {
Chris@16 87 Gen& gen;
Chris@16 88
Chris@16 89 typedef boost::graph_traits<Graph> gt;
Chris@16 90
Chris@16 91 public:
Chris@16 92 unweighted_random_out_edge_gen(Gen& gen): gen(gen) {}
Chris@16 93
Chris@16 94 typename gt::edge_descriptor
Chris@16 95 operator()(typename gt::vertex_descriptor src, const Graph& g) const {
Chris@16 96 if (out_degree(src, g) == 0) throw loop_erased_random_walk_stuck();
Chris@16 97 return boost::random_out_edge(g, src, gen);
Chris@16 98 }
Chris@16 99 };
Chris@16 100
Chris@16 101 template <typename Graph, typename WeightMap, typename Gen>
Chris@16 102 class weighted_random_out_edge_gen {
Chris@16 103 WeightMap weight;
Chris@16 104 Gen& gen;
Chris@16 105
Chris@16 106 typedef boost::graph_traits<Graph> gt;
Chris@16 107
Chris@16 108 public:
Chris@16 109 weighted_random_out_edge_gen(const WeightMap& weight, Gen& gen): weight(weight), gen(gen) {}
Chris@16 110
Chris@16 111 typename gt::edge_descriptor
Chris@16 112 operator()(typename gt::vertex_descriptor src, const Graph& g) const {
Chris@16 113 if (out_degree(src, g) == 0) throw loop_erased_random_walk_stuck();
Chris@16 114 return boost::weighted_random_out_edge(g, src, weight, gen);
Chris@16 115 }
Chris@16 116 };
Chris@16 117 }
Chris@16 118
Chris@16 119 #endif // BOOST_GRAPH_LOOP_ERASED_RANDOM_WALK_HPP