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 | #include <boost/config.hpp> |
---|
10 | #include <iostream> |
---|
11 | #include <iterator> |
---|
12 | #include <vector> |
---|
13 | #include <list> |
---|
14 | // Use boost::queue instead of std::queue because std::queue doesn't |
---|
15 | // model Buffer; it has to top() function. -Jeremy |
---|
16 | #include <boost/pending/queue.hpp> |
---|
17 | |
---|
18 | #include <boost/graph/adjacency_list.hpp> |
---|
19 | #include <boost/graph/visitors.hpp> |
---|
20 | #include <boost/graph/breadth_first_search.hpp> |
---|
21 | #include <boost/graph/dijkstra_shortest_paths.hpp> |
---|
22 | #include <boost/graph/graph_utility.hpp> |
---|
23 | |
---|
24 | using namespace std; |
---|
25 | using namespace boost; |
---|
26 | /* |
---|
27 | This example does a best-first-search (using dijkstra's) and |
---|
28 | simultaneously makes a copy of the graph (assuming the graph is |
---|
29 | connected). |
---|
30 | |
---|
31 | Example Graph: (p. 90 "Data Structures and Network Algorithms", Tarjan) |
---|
32 | |
---|
33 | g |
---|
34 | 3+ +2 |
---|
35 | / 1 \ |
---|
36 | e+----f |
---|
37 | |+0 5++ |
---|
38 | | \ / | |
---|
39 | 10| d |12 |
---|
40 | |8++\7| |
---|
41 | +/ | +| |
---|
42 | b 4| c |
---|
43 | \ | + |
---|
44 | 6+|/3 |
---|
45 | a |
---|
46 | |
---|
47 | Sample Output: |
---|
48 | a --> c d |
---|
49 | b --> a d |
---|
50 | c --> f |
---|
51 | d --> c e f |
---|
52 | e --> b g |
---|
53 | f --> e g |
---|
54 | g --> |
---|
55 | Starting graph: |
---|
56 | a(32767); c d |
---|
57 | c(32767); f |
---|
58 | d(32767); c e f |
---|
59 | f(32767); e g |
---|
60 | e(32767); b g |
---|
61 | g(32767); |
---|
62 | b(32767); a d |
---|
63 | Result: |
---|
64 | a(0); d c |
---|
65 | d(4); f e c |
---|
66 | c(3); f |
---|
67 | f(9); g e |
---|
68 | e(4); g b |
---|
69 | g(7); |
---|
70 | b(14); d a |
---|
71 | |
---|
72 | */ |
---|
73 | |
---|
74 | typedef property<vertex_color_t, default_color_type, |
---|
75 | property<vertex_distance_t,int> > VProperty; |
---|
76 | typedef int weight_t; |
---|
77 | typedef property<edge_weight_t,weight_t> EProperty; |
---|
78 | |
---|
79 | typedef adjacency_list<vecS, vecS, directedS, VProperty, EProperty > Graph; |
---|
80 | |
---|
81 | |
---|
82 | |
---|
83 | template <class Tag> |
---|
84 | struct endl_printer |
---|
85 | : public boost::base_visitor< endl_printer<Tag> > |
---|
86 | { |
---|
87 | typedef Tag event_filter; |
---|
88 | endl_printer(std::ostream& os) : m_os(os) { } |
---|
89 | template <class T, class Graph> |
---|
90 | void operator()(T, Graph&) { m_os << std::endl; } |
---|
91 | std::ostream& m_os; |
---|
92 | }; |
---|
93 | template <class Tag> |
---|
94 | endl_printer<Tag> print_endl(std::ostream& os, Tag) { |
---|
95 | return endl_printer<Tag>(os); |
---|
96 | } |
---|
97 | |
---|
98 | template <class PA, class Tag> |
---|
99 | struct edge_printer |
---|
100 | : public boost::base_visitor< edge_printer<PA, Tag> > |
---|
101 | { |
---|
102 | typedef Tag event_filter; |
---|
103 | |
---|
104 | edge_printer(PA pa, std::ostream& os) : m_pa(pa), m_os(os) { } |
---|
105 | |
---|
106 | template <class T, class Graph> |
---|
107 | void operator()(T x, Graph& g) { |
---|
108 | m_os << "(" << get(m_pa, source(x, g)) << "," |
---|
109 | << get(m_pa, target(x, g)) << ") "; |
---|
110 | } |
---|
111 | PA m_pa; |
---|
112 | std::ostream& m_os; |
---|
113 | }; |
---|
114 | template <class PA, class Tag> |
---|
115 | edge_printer<PA, Tag> |
---|
116 | print_edge(PA pa, std::ostream& os, Tag) { |
---|
117 | return edge_printer<PA, Tag>(pa, os); |
---|
118 | } |
---|
119 | |
---|
120 | |
---|
121 | template <class NewGraph, class Tag> |
---|
122 | struct graph_copier |
---|
123 | : public boost::base_visitor<graph_copier<NewGraph, Tag> > |
---|
124 | { |
---|
125 | typedef Tag event_filter; |
---|
126 | |
---|
127 | graph_copier(NewGraph& graph) : new_g(graph) { } |
---|
128 | |
---|
129 | template <class Edge, class Graph> |
---|
130 | void operator()(Edge e, Graph& g) { |
---|
131 | add_edge(source(e, g), target(e, g), new_g); |
---|
132 | } |
---|
133 | private: |
---|
134 | NewGraph& new_g; |
---|
135 | }; |
---|
136 | template <class NewGraph, class Tag> |
---|
137 | inline graph_copier<NewGraph, Tag> |
---|
138 | copy_graph(NewGraph& g, Tag) { |
---|
139 | return graph_copier<NewGraph, Tag>(g); |
---|
140 | } |
---|
141 | |
---|
142 | template <class Graph, class Name> |
---|
143 | void print(Graph& G, Name name) |
---|
144 | { |
---|
145 | typename boost::graph_traits<Graph>::vertex_iterator ui, uiend; |
---|
146 | for (boost::tie(ui, uiend) = vertices(G); ui != uiend; ++ui) { |
---|
147 | cout << name[*ui] << " --> "; |
---|
148 | typename boost::graph_traits<Graph>::adjacency_iterator vi, viend; |
---|
149 | for(boost::tie(vi, viend) = adjacent_vertices(*ui, G); vi != viend; ++vi) |
---|
150 | cout << name[*vi] << " "; |
---|
151 | cout << endl; |
---|
152 | } |
---|
153 | |
---|
154 | } |
---|
155 | |
---|
156 | |
---|
157 | int |
---|
158 | main(int , char* []) |
---|
159 | { |
---|
160 | // Name and ID numbers for the vertices |
---|
161 | char name[] = "abcdefg"; |
---|
162 | enum { a, b, c, d, e, f, g, N}; |
---|
163 | |
---|
164 | Graph G(N); |
---|
165 | boost::property_map<Graph, vertex_index_t>::type |
---|
166 | vertex_id = get(vertex_index, G); |
---|
167 | |
---|
168 | std::vector<weight_t> distance(N, (numeric_limits<weight_t>::max)()); |
---|
169 | typedef boost::graph_traits<Graph>::vertex_descriptor Vertex; |
---|
170 | std::vector<Vertex> parent(N); |
---|
171 | |
---|
172 | typedef std::pair<int,int> E; |
---|
173 | |
---|
174 | E edges[] = { E(a,c), E(a,d), |
---|
175 | E(b,a), E(b,d), |
---|
176 | E(c,f), |
---|
177 | E(d,c), E(d,e), E(d,f), |
---|
178 | E(e,b), E(e,g), |
---|
179 | E(f,e), E(f,g) }; |
---|
180 | |
---|
181 | int weight[] = { 3, 4, |
---|
182 | 6, 8, |
---|
183 | 12, |
---|
184 | 7, 0, 5, |
---|
185 | 10, 3, |
---|
186 | 1, 2 }; |
---|
187 | |
---|
188 | for (int i = 0; i < 12; ++i) |
---|
189 | add_edge(edges[i].first, edges[i].second, weight[i], G); |
---|
190 | |
---|
191 | print(G, name); |
---|
192 | |
---|
193 | adjacency_list<listS, vecS, directedS, |
---|
194 | property<vertex_color_t, default_color_type> > G_copy(N); |
---|
195 | |
---|
196 | cout << "Starting graph:" << endl; |
---|
197 | |
---|
198 | std::ostream_iterator<int> cout_int(std::cout, " "); |
---|
199 | std::ostream_iterator<char> cout_char(std::cout, " "); |
---|
200 | |
---|
201 | boost::queue<Vertex> Q; |
---|
202 | boost::breadth_first_search |
---|
203 | (G, vertex(a, G), Q, |
---|
204 | make_bfs_visitor( |
---|
205 | boost::make_list |
---|
206 | (write_property(make_iterator_property_map(name, vertex_id, |
---|
207 | name[0]), |
---|
208 | cout_char, on_examine_vertex()), |
---|
209 | write_property(make_iterator_property_map(distance.begin(), |
---|
210 | vertex_id, |
---|
211 | distance[0]), |
---|
212 | cout_int, on_examine_vertex()), |
---|
213 | print_edge(make_iterator_property_map(name, vertex_id, |
---|
214 | name[0]), |
---|
215 | std::cout, on_examine_edge()), |
---|
216 | print_endl(std::cout, on_finish_vertex()))), |
---|
217 | get(vertex_color, G)); |
---|
218 | |
---|
219 | std::cout << "about to call dijkstra's" << std::endl; |
---|
220 | |
---|
221 | parent[vertex(a, G)] = vertex(a, G); |
---|
222 | boost::dijkstra_shortest_paths |
---|
223 | (G, vertex(a, G), |
---|
224 | distance_map(make_iterator_property_map(distance.begin(), vertex_id, |
---|
225 | distance[0])). |
---|
226 | predecessor_map(make_iterator_property_map(parent.begin(), vertex_id, |
---|
227 | parent[0])). |
---|
228 | visitor(make_dijkstra_visitor(copy_graph(G_copy, on_examine_edge())))); |
---|
229 | |
---|
230 | cout << endl; |
---|
231 | cout << "Result:" << endl; |
---|
232 | boost::breadth_first_search |
---|
233 | (G, vertex(a, G), |
---|
234 | visitor(make_bfs_visitor( |
---|
235 | boost::make_list |
---|
236 | (write_property(make_iterator_property_map(name, vertex_id, |
---|
237 | name[0]), |
---|
238 | cout_char, on_examine_vertex()), |
---|
239 | write_property(make_iterator_property_map(distance.begin(), |
---|
240 | vertex_id, |
---|
241 | distance[0]), |
---|
242 | cout_int, on_examine_vertex()), |
---|
243 | print_edge(make_iterator_property_map(name, vertex_id, |
---|
244 | name[0]), |
---|
245 | std::cout, on_examine_edge()), |
---|
246 | print_endl(std::cout, on_finish_vertex()))))); |
---|
247 | |
---|
248 | return 0; |
---|
249 | } |
---|