|
1 //======================================================================= |
|
2 // Copyright 2001 University of Notre Dame. |
|
3 // Author: 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 * © Portions copyright (c) 2006-2007 Nokia Corporation. All rights reserved. |
|
11 */ |
|
12 |
|
13 #include <boost/config.hpp> |
|
14 #include <boost/test/minimal.hpp> |
|
15 #include <stdlib.h> |
|
16 |
|
17 #include <boost/graph/depth_first_search.hpp> |
|
18 #include <boost/graph/adjacency_list.hpp> |
|
19 #include <boost/graph/graph_archetypes.hpp> |
|
20 #include <boost/graph/graph_utility.hpp> |
|
21 #include <boost/graph/random.hpp> |
|
22 |
|
23 #include <boost/random/mersenne_twister.hpp> |
|
24 #ifdef __SYMBIAN32__ |
|
25 #include "std_log_result.h" |
|
26 #define LOG_FILENAME_LINE __FILE__, __LINE__ |
|
27 #endif |
|
28 template <typename ColorMap, typename ParentMap, |
|
29 typename DiscoverTimeMap, typename FinishTimeMap> |
|
30 class dfs_test_visitor { |
|
31 typedef typename boost::property_traits<ColorMap>::value_type ColorValue; |
|
32 typedef typename boost::color_traits<ColorValue> Color; |
|
33 public: |
|
34 dfs_test_visitor(ColorMap color, ParentMap p, DiscoverTimeMap d, |
|
35 FinishTimeMap f) |
|
36 : m_color(color), m_parent(p), |
|
37 m_discover_time(d), m_finish_time(f), m_time(0) { } |
|
38 |
|
39 template <class Vertex, class Graph> |
|
40 void initialize_vertex(Vertex u, Graph& g) { |
|
41 BOOST_CHECK( boost::get(m_color, u) == Color::white() ); |
|
42 } |
|
43 template <class Vertex, class Graph> |
|
44 void start_vertex(Vertex u, Graph& g) { |
|
45 BOOST_CHECK( boost::get(m_color, u) == Color::white() ); |
|
46 } |
|
47 template <class Vertex, class Graph> |
|
48 void discover_vertex(Vertex u, Graph& g) { |
|
49 using namespace boost; |
|
50 BOOST_CHECK( get(m_color, u) == Color::gray() ); |
|
51 BOOST_CHECK( get(m_color, get(m_parent, u)) == Color::gray() ); |
|
52 |
|
53 put(m_discover_time, u, m_time++); |
|
54 } |
|
55 template <class Edge, class Graph> |
|
56 void examine_edge(Edge e, Graph& g) { |
|
57 using namespace boost; |
|
58 BOOST_CHECK( get(m_color, source(e, g)) == Color::gray() ); |
|
59 } |
|
60 template <class Edge, class Graph> |
|
61 void tree_edge(Edge e, Graph& g) { |
|
62 using namespace boost; |
|
63 BOOST_CHECK( get(m_color, target(e, g)) == Color::white() ); |
|
64 |
|
65 put(m_parent, target(e, g), source(e, g)); |
|
66 } |
|
67 template <class Edge, class Graph> |
|
68 void back_edge(Edge e, Graph& g) { |
|
69 using namespace boost; |
|
70 BOOST_CHECK( get(m_color, target(e, g)) == Color::gray() ); |
|
71 } |
|
72 template <class Edge, class Graph> |
|
73 void forward_or_cross_edge(Edge e, Graph& g) { |
|
74 using namespace boost; |
|
75 BOOST_CHECK( get(m_color, target(e, g)) == Color::black() ); |
|
76 } |
|
77 template <class Vertex, class Graph> |
|
78 void finish_vertex(Vertex u, Graph& g) { |
|
79 using namespace boost; |
|
80 BOOST_CHECK( get(m_color, u) == Color::black() ); |
|
81 |
|
82 put(m_finish_time, u, m_time++); |
|
83 } |
|
84 private: |
|
85 ColorMap m_color; |
|
86 ParentMap m_parent; |
|
87 DiscoverTimeMap m_discover_time; |
|
88 FinishTimeMap m_finish_time; |
|
89 typename boost::property_traits<DiscoverTimeMap>::value_type m_time; |
|
90 }; |
|
91 |
|
92 template <typename Graph> |
|
93 struct dfs_test |
|
94 { |
|
95 typedef boost::graph_traits<Graph> Traits; |
|
96 typedef typename Traits::vertices_size_type |
|
97 vertices_size_type; |
|
98 |
|
99 static void go(vertices_size_type max_V) { |
|
100 using namespace boost; |
|
101 typedef typename Traits::vertex_descriptor vertex_descriptor; |
|
102 typedef typename boost::property_map<Graph, |
|
103 boost::vertex_color_t>::type ColorMap; |
|
104 typedef typename boost::property_traits<ColorMap>::value_type ColorValue; |
|
105 typedef typename boost::color_traits<ColorValue> Color; |
|
106 |
|
107 vertices_size_type i, k; |
|
108 typename Traits::edges_size_type j; |
|
109 typename Traits::vertex_iterator vi, vi_end, ui, ui_end; |
|
110 |
|
111 boost::mt19937 gen; |
|
112 |
|
113 for (i = 0; i < max_V; ++i) |
|
114 for (j = 0; j < i*i; ++j) { |
|
115 Graph g; |
|
116 generate_random_graph(g, i, j, gen); |
|
117 |
|
118 ColorMap color = get(boost::vertex_color, g); |
|
119 std::vector<vertex_descriptor> parent(num_vertices(g)); |
|
120 for (k = 0; k < num_vertices(g); ++k) |
|
121 parent[k] = k; |
|
122 std::vector<int> discover_time(num_vertices(g)), |
|
123 finish_time(num_vertices(g)); |
|
124 |
|
125 dfs_test_visitor<ColorMap, vertex_descriptor*, |
|
126 int*, int*> vis(color, &parent[0], |
|
127 &discover_time[0], &finish_time[0]); |
|
128 |
|
129 boost::depth_first_search(g, visitor(vis).color_map(color)); |
|
130 |
|
131 // all vertices should be black |
|
132 for (boost::tie(vi, vi_end) = vertices(g); vi != vi_end; ++vi) |
|
133 BOOST_CHECK(get(color, *vi) == Color::black()); |
|
134 |
|
135 // check parenthesis structure of discover/finish times |
|
136 // See CLR p.480 |
|
137 for (boost::tie(ui, ui_end) = vertices(g); ui != ui_end; ++ui) |
|
138 for (boost::tie(vi, vi_end) = vertices(g); vi != vi_end; ++vi) { |
|
139 vertex_descriptor u = *ui, v = *vi; |
|
140 if (u != v) { |
|
141 BOOST_CHECK( finish_time[u] < discover_time[v] |
|
142 || finish_time[v] < discover_time[u] |
|
143 || (discover_time[v] < discover_time[u] |
|
144 && finish_time[u] < finish_time[v] |
|
145 && boost::is_descendant(u, v, &parent[0])) |
|
146 || (discover_time[u] < discover_time[v] |
|
147 && finish_time[v] < finish_time[u] |
|
148 && boost::is_descendant(v, u, &parent[0])) |
|
149 ); |
|
150 } |
|
151 } |
|
152 } |
|
153 |
|
154 } |
|
155 }; |
|
156 |
|
157 |
|
158 // usage: dfs.exe [max-vertices=15] |
|
159 |
|
160 int test_main(int argc, char* argv[]) |
|
161 { |
|
162 int max_V = 7; |
|
163 if (argc > 1) |
|
164 max_V = atoi(argv[1]); |
|
165 |
|
166 // Test directed graphs. |
|
167 dfs_test< boost::adjacency_list<boost::vecS, boost::vecS, boost::directedS, |
|
168 boost::property<boost::vertex_color_t, boost::default_color_type> > |
|
169 >::go(max_V); |
|
170 // Test undirected graphs. |
|
171 dfs_test< boost::adjacency_list<boost::vecS, boost::vecS, boost::undirectedS, |
|
172 boost::property<boost::vertex_color_t, boost::default_color_type> > |
|
173 >::go(max_V); |
|
174 |
|
175 #ifdef __SYMBIAN32__ |
|
176 std_log(LOG_FILENAME_LINE,"[End Test Case ]"); |
|
177 |
|
178 testResultXml("dfs"); |
|
179 close_log_file(); |
|
180 #endif |
|
181 return 0; |
|
182 } |
|
183 |