sl@0: //======================================================================= sl@0: // Copyright 2001 University of Notre Dame. sl@0: // Author: Jeremy G. Siek sl@0: // sl@0: // Distributed under the Boost Software License, Version 1.0. (See sl@0: // accompanying file LICENSE_1_0.txt or copy at sl@0: // http://www.boost.org/LICENSE_1_0.txt) sl@0: //======================================================================= sl@0: /* sl@0: * © Portions copyright (c) 2006-2007 Nokia Corporation. All rights reserved. sl@0: */ sl@0: sl@0: #include sl@0: #include sl@0: #include sl@0: sl@0: #include sl@0: #include sl@0: #include sl@0: #include sl@0: #include sl@0: sl@0: #include sl@0: #ifdef __SYMBIAN32__ sl@0: #include "std_log_result.h" sl@0: #define LOG_FILENAME_LINE __FILE__, __LINE__ sl@0: #endif sl@0: template sl@0: class dfs_test_visitor { sl@0: typedef typename boost::property_traits::value_type ColorValue; sl@0: typedef typename boost::color_traits Color; sl@0: public: sl@0: dfs_test_visitor(ColorMap color, ParentMap p, DiscoverTimeMap d, sl@0: FinishTimeMap f) sl@0: : m_color(color), m_parent(p), sl@0: m_discover_time(d), m_finish_time(f), m_time(0) { } sl@0: sl@0: template sl@0: void initialize_vertex(Vertex u, Graph& g) { sl@0: BOOST_CHECK( boost::get(m_color, u) == Color::white() ); sl@0: } sl@0: template sl@0: void start_vertex(Vertex u, Graph& g) { sl@0: BOOST_CHECK( boost::get(m_color, u) == Color::white() ); sl@0: } sl@0: template sl@0: void discover_vertex(Vertex u, Graph& g) { sl@0: using namespace boost; sl@0: BOOST_CHECK( get(m_color, u) == Color::gray() ); sl@0: BOOST_CHECK( get(m_color, get(m_parent, u)) == Color::gray() ); sl@0: sl@0: put(m_discover_time, u, m_time++); sl@0: } sl@0: template sl@0: void examine_edge(Edge e, Graph& g) { sl@0: using namespace boost; sl@0: BOOST_CHECK( get(m_color, source(e, g)) == Color::gray() ); sl@0: } sl@0: template sl@0: void tree_edge(Edge e, Graph& g) { sl@0: using namespace boost; sl@0: BOOST_CHECK( get(m_color, target(e, g)) == Color::white() ); sl@0: sl@0: put(m_parent, target(e, g), source(e, g)); sl@0: } sl@0: template sl@0: void back_edge(Edge e, Graph& g) { sl@0: using namespace boost; sl@0: BOOST_CHECK( get(m_color, target(e, g)) == Color::gray() ); sl@0: } sl@0: template sl@0: void forward_or_cross_edge(Edge e, Graph& g) { sl@0: using namespace boost; sl@0: BOOST_CHECK( get(m_color, target(e, g)) == Color::black() ); sl@0: } sl@0: template sl@0: void finish_vertex(Vertex u, Graph& g) { sl@0: using namespace boost; sl@0: BOOST_CHECK( get(m_color, u) == Color::black() ); sl@0: sl@0: put(m_finish_time, u, m_time++); sl@0: } sl@0: private: sl@0: ColorMap m_color; sl@0: ParentMap m_parent; sl@0: DiscoverTimeMap m_discover_time; sl@0: FinishTimeMap m_finish_time; sl@0: typename boost::property_traits::value_type m_time; sl@0: }; sl@0: sl@0: template sl@0: struct dfs_test sl@0: { sl@0: typedef boost::graph_traits Traits; sl@0: typedef typename Traits::vertices_size_type sl@0: vertices_size_type; sl@0: sl@0: static void go(vertices_size_type max_V) { sl@0: using namespace boost; sl@0: typedef typename Traits::vertex_descriptor vertex_descriptor; sl@0: typedef typename boost::property_map::type ColorMap; sl@0: typedef typename boost::property_traits::value_type ColorValue; sl@0: typedef typename boost::color_traits Color; sl@0: sl@0: vertices_size_type i, k; sl@0: typename Traits::edges_size_type j; sl@0: typename Traits::vertex_iterator vi, vi_end, ui, ui_end; sl@0: sl@0: boost::mt19937 gen; sl@0: sl@0: for (i = 0; i < max_V; ++i) sl@0: for (j = 0; j < i*i; ++j) { sl@0: Graph g; sl@0: generate_random_graph(g, i, j, gen); sl@0: sl@0: ColorMap color = get(boost::vertex_color, g); sl@0: std::vector parent(num_vertices(g)); sl@0: for (k = 0; k < num_vertices(g); ++k) sl@0: parent[k] = k; sl@0: std::vector discover_time(num_vertices(g)), sl@0: finish_time(num_vertices(g)); sl@0: sl@0: dfs_test_visitor vis(color, &parent[0], sl@0: &discover_time[0], &finish_time[0]); sl@0: sl@0: boost::depth_first_search(g, visitor(vis).color_map(color)); sl@0: sl@0: // all vertices should be black sl@0: for (boost::tie(vi, vi_end) = vertices(g); vi != vi_end; ++vi) sl@0: BOOST_CHECK(get(color, *vi) == Color::black()); sl@0: sl@0: // check parenthesis structure of discover/finish times sl@0: // See CLR p.480 sl@0: for (boost::tie(ui, ui_end) = vertices(g); ui != ui_end; ++ui) sl@0: for (boost::tie(vi, vi_end) = vertices(g); vi != vi_end; ++vi) { sl@0: vertex_descriptor u = *ui, v = *vi; sl@0: if (u != v) { sl@0: BOOST_CHECK( finish_time[u] < discover_time[v] sl@0: || finish_time[v] < discover_time[u] sl@0: || (discover_time[v] < discover_time[u] sl@0: && finish_time[u] < finish_time[v] sl@0: && boost::is_descendant(u, v, &parent[0])) sl@0: || (discover_time[u] < discover_time[v] sl@0: && finish_time[v] < finish_time[u] sl@0: && boost::is_descendant(v, u, &parent[0])) sl@0: ); sl@0: } sl@0: } sl@0: } sl@0: sl@0: } sl@0: }; sl@0: sl@0: sl@0: // usage: dfs.exe [max-vertices=15] sl@0: sl@0: int test_main(int argc, char* argv[]) sl@0: { sl@0: int max_V = 7; sl@0: if (argc > 1) sl@0: max_V = atoi(argv[1]); sl@0: sl@0: // Test directed graphs. sl@0: dfs_test< boost::adjacency_list > sl@0: >::go(max_V); sl@0: // Test undirected graphs. sl@0: dfs_test< boost::adjacency_list > sl@0: >::go(max_V); sl@0: sl@0: #ifdef __SYMBIAN32__ sl@0: std_log(LOG_FILENAME_LINE,"[End Test Case ]"); sl@0: sl@0: testResultXml("dfs"); sl@0: close_log_file(); sl@0: #endif sl@0: return 0; sl@0: } sl@0: