• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 //=======================================================================
2 // Copyright 1997, 1998, 1999, 2000 University of Notre Dame.
3 // Authors: Andrew Lumsdaine, Lie-Quan Lee, Jeremy G. Siek
4 //
5 // Distributed under the Boost Software License, Version 1.0. (See
6 // accompanying file LICENSE_1_0.txt or copy at
7 // http://www.boost.org/LICENSE_1_0.txt)
8 //=======================================================================
9 
10 #include <boost/config.hpp>
11 
12 #include <algorithm>
13 #include <vector>
14 #include <utility>
15 #include <iostream>
16 
17 #include <boost/graph/visitors.hpp>
18 #include <boost/graph/adjacency_list.hpp>
19 #include <boost/graph/breadth_first_search.hpp>
20 #include <boost/property_map/property_map.hpp>
21 #include <boost/graph/graph_utility.hpp>
22 
23 /*
24 
25   This examples shows how to use the breadth_first_search() GGCL
26   algorithm, specifically the 3 argument variant of bfs that assumes
27   the graph has a color property (property) stored internally.
28 
29   Two pre-defined visitors are used to record the distance of each
30   vertex from the source vertex, and also to record the parent of each
31   vertex. Any number of visitors can be layered and passed to a GGCL
32   algorithm.
33 
34   The call to vertices(G) returns an STL-compatible container which
35   contains all of the vertices in the graph.  In this example we use
36   the vertices container in the STL for_each() function.
37 
38   Sample Output:
39 
40   0 --> 2
41   1 --> 1 3 4
42   2 --> 1 3 4
43   3 --> 1 4
44   4 --> 0 1
45   0 --> 2
46   1 --> 1 3 4
47   2 --> 1 3 4
48   3 --> 1 4
49   4 --> 0 1
50   distances: 0 2 1 2 2
51   parent[0] = 0
52   parent[1] = 2
53   parent[2] = 0
54   parent[3] = 2
55   parent[4] = 2
56 
57 */
58 
59 template < class ParentDecorator > struct print_parent
60 {
print_parentprint_parent61     print_parent(const ParentDecorator& p_) : p(p_) {}
operator ()print_parent62     template < class Vertex > void operator()(const Vertex& v) const
63     {
64         std::cout << "parent[" << v << "] = " << p[v] << std::endl;
65     }
66     ParentDecorator p;
67 };
68 
69 template < class NewGraph, class Tag >
70 struct graph_copier
71 : public boost::base_visitor< graph_copier< NewGraph, Tag > >
72 {
73     typedef Tag event_filter;
74 
graph_copiergraph_copier75     graph_copier(NewGraph& graph) : new_g(graph) {}
76 
operator ()graph_copier77     template < class Edge, class Graph > void operator()(Edge e, Graph& g)
78     {
79         boost::add_edge(boost::source(e, g), boost::target(e, g), new_g);
80     }
81 
82 private:
83     NewGraph& new_g;
84 };
85 
86 template < class NewGraph, class Tag >
copy_graph(NewGraph & g,Tag)87 inline graph_copier< NewGraph, Tag > copy_graph(NewGraph& g, Tag)
88 {
89     return graph_copier< NewGraph, Tag >(g);
90 }
91 
main(int,char * [])92 int main(int, char*[])
93 {
94     typedef boost::adjacency_list< boost::mapS, boost::vecS,
95         boost::bidirectionalS,
96         boost::property< boost::vertex_color_t, boost::default_color_type,
97             boost::property< boost::vertex_degree_t, int,
98                 boost::property< boost::vertex_in_degree_t, int,
99                     boost::property< boost::vertex_out_degree_t, int > > > > >
100         Graph;
101 
102     Graph G(5);
103     boost::add_edge(0, 2, G);
104     boost::add_edge(1, 1, G);
105     boost::add_edge(1, 3, G);
106     boost::add_edge(1, 4, G);
107     boost::add_edge(2, 1, G);
108     boost::add_edge(2, 3, G);
109     boost::add_edge(2, 4, G);
110     boost::add_edge(3, 1, G);
111     boost::add_edge(3, 4, G);
112     boost::add_edge(4, 0, G);
113     boost::add_edge(4, 1, G);
114 
115     typedef Graph::vertex_descriptor Vertex;
116 
117     Graph G_copy(5);
118     // Array to store predecessor (parent) of each vertex. This will be
119     // used as a Decorator (actually, its iterator will be).
120     std::vector< Vertex > p(boost::num_vertices(G));
121     // VC++ version of std::vector has no ::pointer, so
122     // I use ::value_type* instead.
123     typedef std::vector< Vertex >::value_type* Piter;
124 
125     // Array to store distances from the source to each vertex .  We use
126     // a built-in array here just for variety. This will also be used as
127     // a Decorator.
128     boost::graph_traits< Graph >::vertices_size_type d[5];
129     std::fill_n(d, 5, 0);
130 
131     // The source vertex
132     Vertex s = *(boost::vertices(G).first);
133     p[s] = s;
134     boost::breadth_first_search(G, s,
135         boost::visitor(boost::make_bfs_visitor(
136             std::make_pair(boost::record_distances(d, boost::on_tree_edge()),
137                 std::make_pair(
138                     boost::record_predecessors(&p[0], boost::on_tree_edge()),
139                     copy_graph(G_copy, boost::on_examine_edge()))))));
140 
141     boost::print_graph(G);
142     boost::print_graph(G_copy);
143 
144     if (boost::num_vertices(G) < 11)
145     {
146         std::cout << "distances: ";
147 #ifdef BOOST_OLD_STREAM_ITERATORS
148         std::copy(d, d + 5, std::ostream_iterator< int, char >(std::cout, " "));
149 #else
150         std::copy(d, d + 5, std::ostream_iterator< int >(std::cout, " "));
151 #endif
152         std::cout << std::endl;
153 
154         std::for_each(boost::vertices(G).first, boost::vertices(G).second,
155             print_parent< Piter >(&p[0]));
156     }
157 
158     return 0;
159 }
160