stdcpp/tsrc/Boost_test/graph/src/bfs.cpp
changeset 0 e4d67989cc36
equal deleted inserted replaced
-1:000000000000 0:e4d67989cc36
       
     1 //=======================================================================
       
     2 // Copyright 2001 University of Notre Dame.
       
     3 // Author: Andrew Janiszewski, 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/test/minimal.hpp>
       
    11 #include <boost/graph/adjacency_list.hpp>
       
    12 #include <boost/graph/random.hpp>
       
    13 #include <boost/graph/graph_utility.hpp>
       
    14 #include <boost/graph/graph_archetypes.hpp>
       
    15 #include <boost/graph/breadth_first_search.hpp>
       
    16 
       
    17 #include <boost/random/mersenne_twister.hpp>
       
    18 #ifdef __SYMBIAN32__
       
    19 #include "std_log_result.h"
       
    20 #define LOG_FILENAME_LINE __FILE__, __LINE__
       
    21 #endif
       
    22 #ifdef BOOST_NO_ARGUMENT_DEPENDENT_LOOKUP
       
    23 using namespace boost;
       
    24 #endif
       
    25 
       
    26 template <typename DistanceMap, typename ParentMap,
       
    27           typename Graph, typename ColorMap>
       
    28 class bfs_testing_visitor
       
    29 {
       
    30   typedef typename boost::graph_traits<Graph>::vertex_descriptor Vertex;
       
    31   typedef typename boost::graph_traits<Graph>::edge_descriptor Edge;
       
    32   typedef typename boost::color_traits<
       
    33     typename boost::property_traits<ColorMap>::value_type
       
    34   > Color;
       
    35 public:
       
    36 
       
    37   bfs_testing_visitor(Vertex s, DistanceMap d, ParentMap p, ColorMap c)
       
    38     : current_distance(0), distance(d), parent(p), color(c), src(s) { }
       
    39 
       
    40   void initialize_vertex(const Vertex& u, const Graph& ) const {
       
    41     BOOST_CHECK(get(color, u) == Color::white());
       
    42   }
       
    43   void examine_vertex(const Vertex& u, const Graph& ) const {
       
    44     current_vertex = u;
       
    45     // Ensure that the distances monotonically increase.
       
    46     BOOST_CHECK( distance[u] == current_distance
       
    47                        || distance[u] == current_distance + 1 );
       
    48     if (distance[u] == current_distance + 1) // new level
       
    49       ++current_distance;
       
    50   }
       
    51   void discover_vertex(const Vertex& u, const Graph& ) const {
       
    52     BOOST_CHECK( get(color, u) == Color::gray() );
       
    53     if (u == src) {
       
    54       current_vertex = src;
       
    55     } else {
       
    56       BOOST_CHECK( parent[u] == current_vertex );
       
    57       BOOST_CHECK( distance[u] == current_distance + 1 );
       
    58       BOOST_CHECK( distance[u] == distance[parent[u]] + 1 );
       
    59     }
       
    60   }
       
    61   void examine_edge(const Edge& e, const Graph& g) const {
       
    62     BOOST_CHECK( source(e, g) == current_vertex );
       
    63   }
       
    64   void tree_edge(const Edge& e, const Graph& g) const {
       
    65     BOOST_CHECK( get(color, target(e, g)) == Color::white() );
       
    66     Vertex u = source(e, g), v = target(e, g);
       
    67     BOOST_CHECK( distance[u] == current_distance );
       
    68     parent[v] = u;
       
    69     distance[v] = distance[u] + 1;
       
    70   }
       
    71   void non_tree_edge(const Edge& e, const Graph& g) const {
       
    72     BOOST_CHECK( color[target(e, g)] != Color::white() );
       
    73 
       
    74     if (boost::is_directed(g))
       
    75       // cross or back edge
       
    76       BOOST_CHECK(distance[target(e, g)] <= distance[source(e, g)] + 1);
       
    77     else {
       
    78       // cross edge (or going backwards on a tree edge)
       
    79       BOOST_CHECK(distance[target(e, g)] == distance[source(e, g)]
       
    80                         || distance[target(e, g)] == distance[source(e, g)] + 1
       
    81                         || distance[target(e, g)] == distance[source(e, g)] - 1
       
    82                         );
       
    83     }
       
    84   }
       
    85 
       
    86   void gray_target(const Edge& e, const Graph& g) const {
       
    87     BOOST_CHECK( color[target(e, g)] == Color::gray() );
       
    88   }
       
    89 
       
    90   void black_target(const Edge& e, const Graph& g) const {
       
    91     BOOST_CHECK( color[target(e, g)] == Color::black() );
       
    92 
       
    93     // All vertices adjacent to a black vertex must already be discovered
       
    94     typename boost::graph_traits<Graph>::adjacency_iterator ai, ai_end;
       
    95     for (boost::tie(ai, ai_end) = adjacent_vertices(target(e, g), g);
       
    96          ai != ai_end; ++ai)
       
    97       BOOST_CHECK( color[*ai] != Color::white() );
       
    98   }
       
    99   void finish_vertex(const Vertex& u, const Graph& ) const {
       
   100     BOOST_CHECK( color[u] == Color::black() );
       
   101 
       
   102   }
       
   103 private:
       
   104   mutable Vertex current_vertex;
       
   105   mutable typename boost::property_traits<DistanceMap>::value_type
       
   106     current_distance;
       
   107   DistanceMap distance;
       
   108   ParentMap parent;
       
   109   ColorMap color;
       
   110   Vertex src;
       
   111 };
       
   112 
       
   113 
       
   114 template <class Graph>
       
   115 struct bfs_test
       
   116 {
       
   117   typedef boost::graph_traits<Graph> Traits;
       
   118   typedef typename Traits::vertices_size_type
       
   119     vertices_size_type;
       
   120   static void go(vertices_size_type max_V) {
       
   121     typedef typename Traits::vertex_descriptor vertex_descriptor;
       
   122     typedef boost::color_traits<boost::default_color_type> Color;
       
   123 
       
   124     vertices_size_type i;
       
   125     typename Traits::edges_size_type j;
       
   126     typename Traits::vertex_iterator ui, ui_end;
       
   127 
       
   128     boost::mt19937 gen;
       
   129 
       
   130     for (i = 0; i < max_V; ++i)
       
   131       for (j = 0; j < i*i; ++j) {
       
   132         Graph g;
       
   133         boost::generate_random_graph(g, i, j, gen);
       
   134 
       
   135         // declare the "start" variable
       
   136         vertex_descriptor start = boost::random_vertex(g, gen);
       
   137 
       
   138         // vertex properties
       
   139         std::vector<int> distance(i, (std::numeric_limits<int>::max)());
       
   140         distance[start] = 0;
       
   141         std::vector<vertex_descriptor> parent(i);
       
   142         for (boost::tie(ui, ui_end) = vertices(g); ui != ui_end; ++ui)
       
   143           parent[*ui] = *ui;
       
   144         std::vector<boost::default_color_type> color(i);
       
   145 
       
   146         // Create the testing visitor.
       
   147         bfs_testing_visitor<int*,vertex_descriptor*,Graph,
       
   148           boost::default_color_type*>
       
   149           vis(start, &distance[0], &parent[0], &color[0]);
       
   150 
       
   151         boost::breadth_first_search(g, start,
       
   152                                     visitor(vis).
       
   153                                     color_map(&color[0]));
       
   154 
       
   155         // All white vertices should be unreachable from the source.
       
   156         for (boost::tie(ui, ui_end) = vertices(g); ui != ui_end; ++ui)
       
   157           if (color[*ui] == Color::white()) {
       
   158             std::vector<boost::default_color_type> color2(i, Color::white());
       
   159             BOOST_CHECK(!boost::is_reachable(start, *ui, g, &color2[0]));
       
   160           }
       
   161 
       
   162         // The shortest path to a child should be one longer than
       
   163         // shortest path to the parent.
       
   164         for (boost::tie(ui, ui_end) = vertices(g); ui != ui_end; ++ui)
       
   165           if (parent[*ui] != *ui) // *ui not the root of the bfs tree
       
   166             BOOST_CHECK(distance[*ui] == distance[parent[*ui]] + 1);
       
   167       }
       
   168   }
       
   169 };
       
   170 
       
   171 
       
   172 int test_main(int argc, char* argv[])
       
   173 {
       
   174   using namespace boost;
       
   175   int max_V = 7;
       
   176   if (argc > 1)
       
   177     max_V = atoi(argv[1]);
       
   178 
       
   179   bfs_test< adjacency_list<vecS, vecS, directedS> >::go(max_V);
       
   180   bfs_test< adjacency_list<vecS, vecS, undirectedS> >::go(max_V);
       
   181   
       
   182   #ifdef __SYMBIAN32__
       
   183 	std_log(LOG_FILENAME_LINE,"[End Test Case ]");
       
   184 
       
   185 	testResultXml("bfs");
       
   186 	close_log_file();
       
   187 #endif
       
   188   return 0;
       
   189 }